diff --git a/.hgtags b/.hgtags index 5cfc1c804be..c3213062fb5 100644 --- a/.hgtags +++ b/.hgtags @@ -86,3 +86,5 @@ c4c8a5bc54f66abc68cd185d9294042121922154 jdk7-b99 e02b4d709e177d08d56130a4bc68061e4bbacc7d jdk7-b109 a6442d6bc38a44152e0662688213ce4d2701f42a jdk7-b110 69f3edf083477955b5bd2f754252c7504167d8e1 jdk7-b111 +f960f117f1623629f64203e2b09a92a8f6f14ff5 jdk7-b112 +1fee41c7ed2b3388970a756a85aa693c0de8407a jdk7-b113 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 19a3f1c2601..91c72f80940 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -86,3 +86,5 @@ f8be576feefce0c6695f188ef97ec16b73ad9cfd jdk7-b104 81dfc728d7bb7e1fff4a4dc6d0f7cea5a3315667 jdk7-b109 2a02d4a6955c7c078aee9a604cb3be409800d82c jdk7-b110 9702d6fef68e17533ee7fcf5923b11ead3e912ce jdk7-b111 +b852103caf73da70068473777ae867a457bb3ae1 jdk7-b112 +c1df968c4527bfab5f97662a89245f15d12d378b jdk7-b113 diff --git a/Makefile b/Makefile index 065e0c55edc..d42650e58ce 100644 --- a/Makefile +++ b/Makefile @@ -558,9 +558,12 @@ endif # rule to test ################################################################ -.NOTPARALLEL: test +.NOTPARALLEL: test_run -test: test_clean test_start test_summary +test: + $(MAKE) test_run + +test_run: test_clean test_start test_summary test_start: @$(ECHO) "Tests started at `$(DATE)`" @@ -586,7 +589,7 @@ test_summary: $(OUTPUTDIR)/test_failures.txt # Get failure list from log $(OUTPUTDIR)/test_failures.txt: $(OUTPUTDIR)/test_log.txt @$(RM) $@ - @( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) > $@ + @( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) | $(NAWK) 'length>0' > $@ # Get log file of all tests run JDK_TO_TEST := $(shell \ @@ -598,10 +601,11 @@ JDK_TO_TEST := $(shell \ $(ECHO) "$(PRODUCT_HOME)"; \ fi \ ) +TEST_TARGETS=all $(OUTPUTDIR)/test_log.txt: $(RM) $@ - ( $(CD) test && \ - $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) \ + ( $(CD) test && \ + $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) $(TEST_TARGETS) \ ) | tee $@ ################################################################ @@ -614,7 +618,7 @@ include ./make/jprt.gmk # PHONY ################################################################ -.PHONY: all test test_start test_summary test_clean \ +.PHONY: all test test_run test_start test_summary test_clean \ generic_build_repo_series \ what clobber insane \ dev dev-build dev-sanity dev-clobber \ diff --git a/corba/.hgtags b/corba/.hgtags index 9f6d3054114..03eadfbbb1b 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -86,3 +86,5 @@ a56d734a1e970e1a21a8f4feb13053e9a33674c7 jdk7-b100 c3dd858e09b20206459d9e7b0ead99d27ab00eab jdk7-b109 0e1f80fda2271f53d4bbb59ec3f301dfbcef6a0a jdk7-b110 640fa4d4e2ad4c2d7e4815c955026740d8c52b7a jdk7-b111 +cc67fdc4fee9a5b25caee4e71b51a8ff24ae7d1a jdk7-b112 +a89a6c5be9d1a754868d3d359cbf7ad36aa95631 jdk7-b113 diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 71539d8e572..da1bccd72ad 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -121,3 +121,5 @@ e44a93947ccbfce712b51725f313163606f15486 jdk7-b108 cc4bb3022b3144dc5db0805b9ef6c7eff2aa3b81 jdk7-b109 2f25f2b8de2700a1822463b1bd3d02b5e218018f jdk7-b110 07b042e13dde4f3479ba9ec55120fcd5e8623323 jdk7-b111 +5511edd5d719f3fc9fdd04879482026a3d2c8652 jdk7-b112 +beef35b96b81129c375d572357fb9548d9020db1 jdk7-b113 diff --git a/jaxp/.hgtags b/jaxp/.hgtags index e7b0a593feb..e3050dd6df5 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -86,3 +86,5 @@ d42c4acb6424a094bdafe2ad9c8c1c7ca7fb7b7e jdk7-b104 0f382d6120fc07aed2209484a42458cabf405916 jdk7-b109 d422dbdd09766269344b796b3a46a5b3f74557e1 jdk7-b110 8106c747067c905d814a737a57fea0e29057b33f jdk7-b111 +1b05254242881527b4d5d711295c0fe708c8823a jdk7-b112 +bc0c84ce54c34d3e8b0604b94da0d7c75c26755e jdk7-b113 diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 7d3a0bc9d25..12e62c797d0 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -86,3 +86,5 @@ b1ca39340238a239ba6d8489ad5315215e1366ca jdk7-b108 4f626e0d70bda68c76bbd0e89d2bc2407f979736 jdk7-b109 95ecac35fb11530752bd0404c9bf02bcfb30990e jdk7-b110 2575ebca96c7fb1b78f6ae025a97321210aba309 jdk7-b111 +8e0f0054817f0f73fb33e80fb1333fb45b1d513d jdk7-b112 +d35c94fd22362f478f75b4bfcd2bef6a83cb9b3f jdk7-b113 diff --git a/jdk/.hgtags b/jdk/.hgtags index e69a21ab6c0..b49ddeec2f9 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -86,3 +86,5 @@ b91ef6b60f4e19bf4592c6dd594c9bac62487519 jdk7-b106 ab0d3f54a63f2aadfcdd2e14b81f79362ce454e2 jdk7-b109 176586cd040e4dd17a5ff6e91f72df10d7442453 jdk7-b110 fb63a2688db807a73e2a3de7d9bab298f1bff0e8 jdk7-b111 +b53f226b1d91473ac54184afa827be07b87e0319 jdk7-b112 +61d3b9fbb26bdef56cfa41b9af5bc312a22cbeb8 jdk7-b113 diff --git a/jdk/make/java/java/FILES_java.gmk b/jdk/make/java/java/FILES_java.gmk index 4043c374a02..acbc8a73230 100644 --- a/jdk/make/java/java/FILES_java.gmk +++ b/jdk/make/java/java/FILES_java.gmk @@ -466,14 +466,11 @@ JAVA_JAVA_java = \ java/security/ProtectionDomain.java \ java/net/URLClassLoader.java \ java/net/URLConnection.java \ + sun/misc/BootClassLoaderHook.java \ sun/misc/Launcher.java \ sun/misc/MetaIndex.java \ sun/misc/URLClassPath.java \ sun/misc/Version.java \ - sun/net/www/protocol/jar/Handler.java \ - sun/net/www/protocol/jar/JarURLConnection.java \ - sun/net/www/protocol/file/Handler.java \ - sun/net/www/protocol/file/FileURLConnection.java \ sun/misc/FileURLMapper.java \ sun/misc/MessageUtils.java \ sun/misc/GC.java \ @@ -483,6 +480,10 @@ JAVA_JAVA_java = \ sun/misc/JavaIOFileDescriptorAccess.java \ sun/misc/JavaNioAccess.java \ sun/misc/Perf.java \ - sun/misc/PerfCounter.java + sun/misc/PerfCounter.java \ + sun/net/www/protocol/jar/Handler.java \ + sun/net/www/protocol/jar/JarURLConnection.java \ + sun/net/www/protocol/file/Handler.java \ + sun/net/www/protocol/file/FileURLConnection.java FILES_java = $(JAVA_JAVA_java) diff --git a/jdk/make/mkdemo/Makefile b/jdk/make/mkdemo/Makefile index cda377f83f2..5a54d2795cd 100644 --- a/jdk/make/mkdemo/Makefile +++ b/jdk/make/mkdemo/Makefile @@ -31,7 +31,7 @@ BUILDDIR = .. PRODUCT = demos include $(BUILDDIR)/common/Defs.gmk -SUBDIRS = jni +SUBDIRS = jni nio SUBDIRS_desktop = applets jfc SUBDIRS_management = management SUBDIRS_misc = scripting diff --git a/jdk/make/mkdemo/nio/Makefile b/jdk/make/mkdemo/nio/Makefile new file mode 100644 index 00000000000..26dc772b213 --- /dev/null +++ b/jdk/make/mkdemo/nio/Makefile @@ -0,0 +1,39 @@ +# +# Copyright (c) 1997, 2007, 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. +# + +# +# Makefile for building the jfc demos +# + +BUILDDIR = ../.. +PRODUCT = demos +include $(BUILDDIR)/common/Defs.gmk + +SUBDIRS = zipfs +include $(BUILDDIR)/common/Subdirs.gmk + +all build clean clobber:: + $(SUBDIRS-loop) + diff --git a/jdk/make/mkdemo/nio/zipfs/Makefile b/jdk/make/mkdemo/nio/zipfs/Makefile new file mode 100644 index 00000000000..16e71a9ba45 --- /dev/null +++ b/jdk/make/mkdemo/nio/zipfs/Makefile @@ -0,0 +1,44 @@ +# +# Copyright (c) 1997, 2002, 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. +# + +# +# Makefile to build the ZipFileSystem demo. +# + +BUILDDIR = ../../.. +PRODUCT = demo/zipfs +DEMONAME = zipfs +include $(BUILDDIR)/common/Defs.gmk + +DEMO_ROOT = $(SHARE_SRC)/demo/nio/$(DEMONAME) +DEMO_TOPFILES = ./README.txt +DEMO_SRCDIR = $(DEMO_ROOT) +DEMO_DESTDIR = $(DEMODIR)/nio/$(DEMONAME) + +# +# Demo jar building rules. +# +include $(BUILDDIR)/common/Demo.gmk + diff --git a/jdk/make/sun/cmm/lcms/Makefile b/jdk/make/sun/cmm/lcms/Makefile index 1072c2fac7b..702c32680c8 100644 --- a/jdk/make/sun/cmm/lcms/Makefile +++ b/jdk/make/sun/cmm/lcms/Makefile @@ -80,7 +80,12 @@ vpath %.c $(SHARE_SRC)/native/$(PKGDIR) vpath %.c $(SHARE_SRC)/native/sun/java2d ifeq ($(PLATFORM), windows) -OTHER_CFLAGS += -DCMS_IS_WINDOWS_ -Dsqrtf=sqrt +OTHER_CFLAGS += -DCMS_IS_WINDOWS_ + +ifeq ($(COMPILER_VERSION), VS2003) +OTHER_CFLAGS += -Dsqrtf=sqrt +endif + OTHER_LDLIBS = $(OBJDIR)/../../../sun.awt/awt/$(OBJDIRNAME)/awt.lib OTHER_INCLUDES += -I$(SHARE_SRC)/native/sun/java2d \ -I$(SHARE_SRC)/native/sun/awt/debug diff --git a/jdk/src/share/bin/java.c b/jdk/src/share/bin/java.c index 4c61fb7c853..01eeb2a0547 100644 --- a/jdk/src/share/bin/java.c +++ b/jdk/src/share/bin/java.c @@ -355,7 +355,6 @@ JavaMain(void * _args) JavaVM *vm = 0; JNIEnv *env = 0; - jstring mainClassName; jclass mainClass; jmethodID mainID; jobjectArray mainArgs; diff --git a/jdk/src/share/bin/parse_manifest.c b/jdk/src/share/bin/parse_manifest.c index 2c916d87cb5..61b8bdb6b69 100644 --- a/jdk/src/share/bin/parse_manifest.c +++ b/jdk/src/share/bin/parse_manifest.c @@ -72,7 +72,7 @@ inflate_file(int fd, zentry *entry, int *size_out) if (entry->how == STORED) { *(char *)((size_t)in + entry->csize) = '\0'; if (size_out) { - *size_out = entry->csize; + *size_out = (int)entry->csize; } return (in); } else if (entry->how == DEFLATED) { @@ -103,7 +103,7 @@ inflate_file(int fd, zentry *entry, int *size_out) return (NULL); } if (size_out) { - *size_out = entry->isize; + *size_out = (int)entry->isize; } return (out); } else @@ -317,7 +317,7 @@ find_file(int fd, zentry *entry, const char *file_name) * manifest. If so, build the entry record from the data found in * the header located and return success. */ - if (CENNAM(p) == JLI_StrLen(file_name) && + if ((size_t)CENNAM(p) == JLI_StrLen(file_name) && memcmp((p + CENHDR), file_name, JLI_StrLen(file_name)) == 0) { if (lseek(fd, base_offset + CENOFF(p), SEEK_SET) < (off_t)0) { free(buffer); @@ -606,8 +606,5 @@ JLI_ManifestIterate(const char *jarfile, attribute_closure ac, void *user_data) } free(mp); close(fd); - if (rc == 0) - return (0); - else - return (-2); + return (rc == 0) ? 0 : -2; } diff --git a/jdk/src/share/bin/wildcard.c b/jdk/src/share/bin/wildcard.c index 3abcd18a97c..0d834e635b5 100644 --- a/jdk/src/share/bin/wildcard.c +++ b/jdk/src/share/bin/wildcard.c @@ -290,12 +290,12 @@ FileList_join(FileList fl, char sep) char *path; char *p; for (i = 0, size = 1; i < fl->size; i++) - size += JLI_StrLen(fl->files[i]) + 1; + size += (int)JLI_StrLen(fl->files[i]) + 1; path = JLI_MemAlloc(size); for (i = 0, p = path; i < fl->size; i++) { - int len = JLI_StrLen(fl->files[i]); + int len = (int)JLI_StrLen(fl->files[i]); if (i > 0) *p++ = sep; memcpy(p, fl->files[i], len); p += len; @@ -309,7 +309,7 @@ static FileList FileList_split(const char *path, char sep) { const char *p, *q; - int len = JLI_StrLen(path); + int len = (int)JLI_StrLen(path); int count; FileList fl; for (count = 1, p = path; p < path + len; p++) @@ -330,7 +330,7 @@ FileList_split(const char *path, char sep) static int isJarFileName(const char *filename) { - int len = JLI_StrLen(filename); + int len = (int)JLI_StrLen(filename); return (len >= 4) && (filename[len - 4] == '.') && (equal(filename + len - 3, "jar") || @@ -342,8 +342,8 @@ isJarFileName(const char *filename) static char * wildcardConcat(const char *wildcard, const char *basename) { - int wildlen = JLI_StrLen(wildcard); - int baselen = JLI_StrLen(basename); + int wildlen = (int)JLI_StrLen(wildcard); + int baselen = (int)JLI_StrLen(basename); char *filename = (char *) JLI_MemAlloc(wildlen + baselen); /* Replace the trailing '*' with basename */ memcpy(filename, wildcard, wildlen-1); @@ -369,7 +369,7 @@ wildcardFileList(const char *wildcard) static int isWildcard(const char *filename) { - int len = JLI_StrLen(filename); + int len = (int)JLI_StrLen(filename); return (len > 0) && (filename[len - 1] == '*') && (len == 1 || IS_FILE_SEPARATOR(filename[len - 2])) && diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java index 0c1b0954300..b662ebb9683 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java @@ -654,8 +654,8 @@ class Attribute implements Comparable, Constants { String layout; public FormatException(String message, int ctype, String name, String layout) { - super(ATTR_CONTEXT_NAME[ctype]+"."+name - +(message == null? "": (": "+message))); + super(ATTR_CONTEXT_NAME[ctype]+ " attribute \"" + name + "\"" + + (message == null? "" : (": " + message))); this.ctype = ctype; this.name = name; this.layout = layout; diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java index a14bf350a6f..fd28171a75b 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java @@ -30,6 +30,7 @@ import java.util.*; import com.sun.java.util.jar.pack.Package.Class; import com.sun.java.util.jar.pack.Package.InnerClass; import com.sun.java.util.jar.pack.ConstantPool.*; +import com.sun.tools.classfile.AttributeException; /** * Reader for a class file that is being incorporated into a package. @@ -246,7 +247,9 @@ class ClassReader implements Constants { fixups[fptr++] = in.readUnsignedShort(); break; default: - throw new IOException("Bad constant pool tag "+tag); + throw new ClassFormatException("Bad constant pool tag " + + tag + " in File: " + cls.file.nameString + + " at pos: " + inPos); } } @@ -403,7 +406,7 @@ class ClassReader implements Constants { skip(length, "unknown "+name+" attribute in "+h); continue; } else { - String message = "unknown in "+h; + String message = " is unknown attribute in class " + h; throw new Attribute.FormatException(message, ctype, name, unknownAttrCommand); } @@ -415,7 +418,12 @@ class ClassReader implements Constants { if (a.name() == "Code") { Class.Method m = (Class.Method) h; m.code = new Code(m); - readCode(m.code); + try { + readCode(m.code); + } catch (Instruction.FormatException iie) { + String message = iie.getMessage() + " in " + h; + throw new ClassReader.ClassFormatException(message); + } } else { assert(h == cls); readInnerClasses(cls); @@ -427,6 +435,10 @@ class ClassReader implements Constants { in.readFully(bytes); a = a.addContent(bytes); } + if (a.size() == 0 && !a.layout().isEmpty()) { + throw new ClassFormatException(name + + ": attribute length cannot be zero, in " + h); + } h.addAttribute(a); if (verbose > 2) Utils.log.fine("read "+a); @@ -438,6 +450,7 @@ class ClassReader implements Constants { code.max_locals = readUnsignedShort(); code.bytes = new byte[readInt()]; in.readFully(code.bytes); + Instruction.opcodeChecker(code.bytes); int nh = readUnsignedShort(); code.setHandlerCount(nh); for (int i = 0; i < nh; i++) { @@ -463,4 +476,10 @@ class ClassReader implements Constants { cls.innerClasses = ics; // set directly; do not use setInnerClasses. // (Later, ics may be transferred to the pkg.) } + + class ClassFormatException extends IOException { + public ClassFormatException(String message) { + super(message); + } + } } diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java index bef43fd0f03..2eb4604ec08 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java @@ -25,6 +25,8 @@ package com.sun.java.util.jar.pack; +import java.io.IOException; + /** * A parsed bytecode instruction. * Provides accessors to various relevant bits. @@ -628,4 +630,21 @@ class Instruction implements Constants { } } } + + public static void opcodeChecker(byte[] code) throws FormatException { + Instruction i = at(code, 0); + while (i != null) { + int opcode = i.getBC(); + if (opcode == _xxxunusedxxx || opcode < _nop || opcode > _jsr_w) { + String message = "illegal opcode: " + opcode + " " + i; + throw new FormatException(message); + } + i = i.next(); + } + } + static class FormatException extends IOException { + FormatException(String message) { + super(message); + } + } } diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java index 449bbbeb5b1..a45a4bcba09 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java @@ -496,15 +496,29 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { reader.unknownAttrCommand = unknownAttrCommand; try { reader.read(); - } catch (Attribute.FormatException ee) { - // He passed up the category to us in layout. - if (ee.layout.equals(Pack200.Packer.PASS)) { - Utils.log.warning("Passing class file uncompressed due to unrecognized attribute: "+fname); - Utils.log.info(ee.toString()); - return null; + } catch (IOException ioe) { + String message = "Passing class file uncompressed due to"; + if (ioe instanceof Attribute.FormatException) { + Attribute.FormatException ee = (Attribute.FormatException) ioe; + // He passed up the category to us in layout. + if (ee.layout.equals(Pack200.Packer.PASS)) { + Utils.log.info(ee.toString()); + Utils.log.warning(message + " unrecognized attribute: " + + fname); + return null; + } + } else if (ioe instanceof ClassReader.ClassFormatException) { + ClassReader.ClassFormatException ce = (ClassReader.ClassFormatException) ioe; + // %% TODO: Do we invent a new property for this or reuse %% + if (unknownAttrCommand.equals(Pack200.Packer.PASS)) { + Utils.log.info(ce.toString()); + Utils.log.warning(message + " unknown class format: " + + fname); + return null; + } } // Otherwise, it must be an error. - throw ee; + throw ioe; } pkg.addClass(cls); return cls.file; diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java index 2dc47c41464..84f65ac2ccf 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java @@ -182,11 +182,8 @@ class Utils { } public void warning(String msg, Object param) { - int verbose = currentPropMap().getInteger(DEBUG_VERBOSE); - if (verbose > 0) { getLogger().warning(msg, param); } - } public void warning(String msg) { warning(msg, null); @@ -216,7 +213,9 @@ class Utils { // Returns the Max Version String of this implementation static String getVersionString() { - return "Pack200, Vendor: Sun Microsystems, Version: " + + return "Pack200, Vendor: " + + System.getProperty("java.vendor") + + ", Version: " + Constants.JAVA6_PACKAGE_MAJOR_VERSION + "." + Constants.JAVA6_PACKAGE_MINOR_VERSION; } diff --git a/jdk/src/share/classes/com/sun/net/httpserver/BasicAuthenticator.java b/jdk/src/share/classes/com/sun/net/httpserver/BasicAuthenticator.java index 2b1303b406d..666ab0b2c1b 100644 --- a/jdk/src/share/classes/com/sun/net/httpserver/BasicAuthenticator.java +++ b/jdk/src/share/classes/com/sun/net/httpserver/BasicAuthenticator.java @@ -24,9 +24,6 @@ */ package com.sun.net.httpserver; -import java.net.*; -import java.io.*; -import java.util.*; /** * BasicAuthenticator provides an implementation of HTTP Basic @@ -57,7 +54,6 @@ public abstract class BasicAuthenticator extends Authenticator { public Result authenticate (HttpExchange t) { - HttpContext context = t.getHttpContext(); Headers rmap = (Headers) t.getRequestHeaders(); /* * look for auth token diff --git a/jdk/src/share/classes/com/sun/net/httpserver/Filter.java b/jdk/src/share/classes/com/sun/net/httpserver/Filter.java index 7e8c6e7a957..a870d6518d3 100644 --- a/jdk/src/share/classes/com/sun/net/httpserver/Filter.java +++ b/jdk/src/share/classes/com/sun/net/httpserver/Filter.java @@ -25,11 +25,7 @@ package com.sun.net.httpserver; -import java.net.*; -import java.io.*; -import java.nio.*; -import java.nio.channels.*; -import sun.net.www.MessageHeader; +import java.io.IOException; import java.util.*; /** @@ -56,12 +52,10 @@ public abstract class Filter { /* the last element in the chain must invoke the users * handler */ - private List filters; private ListIterator iter; private HttpHandler handler; public Chain (List filters, HttpHandler handler) { - this.filters = filters; iter = filters.listIterator(); this.handler = handler; } diff --git a/jdk/src/share/classes/com/sun/net/httpserver/Headers.java b/jdk/src/share/classes/com/sun/net/httpserver/Headers.java index efac6042861..b9176917368 100644 --- a/jdk/src/share/classes/com/sun/net/httpserver/Headers.java +++ b/jdk/src/share/classes/com/sun/net/httpserver/Headers.java @@ -26,7 +26,6 @@ package com.sun.net.httpserver; import java.util.*; -import java.io.*; /** * HTTP request and response headers are represented by this class which implements @@ -77,19 +76,16 @@ public class Headers implements Map> { if (len == 0) { return key; } - char[] b = new char [len]; - String s = null; - b = key.toCharArray(); - if (b[0] >= 'a' && b[0] <= 'z') { - b[0] = (char)(b[0] - ('a' - 'A')); + char[] b = key.toCharArray(); + if (b[0] >= 'a' && b[0] <= 'z') { + b[0] = (char)(b[0] - ('a' - 'A')); + } + for (int i=1; i= 'A' && b[i] <= 'Z') { + b[i] = (char) (b[i] + ('a' - 'A')); } - for (int i=1; i= 'A' && b[i] <= 'Z') { - b[i] = (char) (b[i] + ('a' - 'A')); - } - } - s = new String (b); - return s; + } + return new String(b); } public int size() {return map.size();} diff --git a/jdk/src/share/classes/com/sun/net/httpserver/HttpsParameters.java b/jdk/src/share/classes/com/sun/net/httpserver/HttpsParameters.java index 13ddc3e658c..c54e917c02e 100644 --- a/jdk/src/share/classes/com/sun/net/httpserver/HttpsParameters.java +++ b/jdk/src/share/classes/com/sun/net/httpserver/HttpsParameters.java @@ -24,9 +24,7 @@ */ package com.sun.net.httpserver; -import java.net.*; -import java.io.*; -import java.util.*; +import java.net.InetSocketAddress; import javax.net.ssl.SSLParameters; /** @@ -90,7 +88,7 @@ public abstract class HttpsParameters { * have been set. */ public String[] getCipherSuites() { - return cipherSuites; + return cipherSuites != null ? cipherSuites.clone() : null; } /** @@ -99,7 +97,7 @@ public abstract class HttpsParameters { * @param cipherSuites the array of ciphersuites (or null) */ public void setCipherSuites(String[] cipherSuites) { - this.cipherSuites = cipherSuites; + this.cipherSuites = cipherSuites != null ? cipherSuites.clone() : null; } /** @@ -110,7 +108,7 @@ public abstract class HttpsParameters { * have been set. */ public String[] getProtocols() { - return protocols; + return protocols != null ? protocols.clone() : null; } /** @@ -119,7 +117,7 @@ public abstract class HttpsParameters { * @param protocols the array of protocols (or null) */ public void setProtocols(String[] protocols) { - this.protocols = protocols; + this.protocols = protocols != null ? protocols.clone() : null; } /** diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java index d469399b71d..bfba75dd2ae 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java @@ -3,7 +3,7 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 1999-2005 The Apache Software Foundation. + * Copyright 1999-2010 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,66 +23,70 @@ package com.sun.org.apache.xml.internal.security.utils; import java.io.OutputStream; /** - * A simple Unsynced ByteArryOutputStream + * A simple Unsynced ByteArrayOutputStream * @author raul * */ public class UnsyncByteArrayOutputStream extends OutputStream { - private static ThreadLocal bufCahce = new ThreadLocal() { + private static final int INITIAL_SIZE = 8192; + private static ThreadLocal bufCache = new ThreadLocal() { protected synchronized Object initialValue() { - return new byte[8*1024]; + return new byte[INITIAL_SIZE]; } }; - byte[] buf; - int size=8*1024;//buf.length; - int pos=0; - public UnsyncByteArrayOutputStream() { - buf=(byte[])bufCahce.get(); - } - /** @inheritDoc */ - public void write(byte[] arg0) { - int newPos=pos+arg0.length; - if (newPos>size) { - expandSize(); - } - System.arraycopy(arg0,0,buf,pos,arg0.length); - pos=newPos; - } - /** @inheritDoc */ - public void write(byte[] arg0, int arg1, int arg2) { - int newPos=pos+arg2; - if (newPos>size) { - expandSize(); - } - System.arraycopy(arg0,arg1,buf,pos,arg2); - pos=newPos; - } - /** @inheritDoc */ - public void write(int arg0) { - if (pos>=size) { - expandSize(); - } - buf[pos++]=(byte)arg0; - } - /** @inheritDoc */ - public byte[] toByteArray() { - byte result[]=new byte[pos]; - System.arraycopy(buf,0,result,0,pos); - return result; - } - /** @inheritDoc */ - public void reset() { - pos=0; - } + private byte[] buf; + private int size = INITIAL_SIZE; + private int pos = 0; - /** @inheritDoc */ - void expandSize() { - int newSize=size<<2; - byte newBuf[]=new byte[newSize]; - System.arraycopy(buf,0,newBuf,0,pos); - buf=newBuf; - size=newSize; + public UnsyncByteArrayOutputStream() { + buf = (byte[])bufCache.get(); + } + public void write(byte[] arg0) { + int newPos = pos + arg0.length; + if (newPos > size) { + expandSize(newPos); } + System.arraycopy(arg0, 0, buf, pos, arg0.length); + pos = newPos; + } + + public void write(byte[] arg0, int arg1, int arg2) { + int newPos = pos + arg2; + if (newPos > size) { + expandSize(newPos); + } + System.arraycopy(arg0, arg1, buf, pos, arg2); + pos = newPos; + } + + public void write(int arg0) { + int newPos = pos + 1; + if (newPos > size) { + expandSize(newPos); + } + buf[pos++] = (byte)arg0; + } + + public byte[] toByteArray() { + byte result[] = new byte[pos]; + System.arraycopy(buf, 0, result, 0, pos); + return result; + } + + public void reset() { + pos = 0; + } + + private void expandSize(int newPos) { + int newSize = size; + while (newPos > newSize) { + newSize = newSize<<2; + } + byte newBuf[] = new byte[newSize]; + System.arraycopy(buf, 0, newBuf, 0, pos); + buf = newBuf; + size = newSize; + } } diff --git a/jdk/src/share/classes/java/awt/Dialog.java b/jdk/src/share/classes/java/awt/Dialog.java index 3e2effd1dc0..36a3502e3ba 100644 --- a/jdk/src/share/classes/java/awt/Dialog.java +++ b/jdk/src/share/classes/java/awt/Dialog.java @@ -1068,7 +1068,7 @@ public class Dialog extends Window { modalityPushed(); try { EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue(); - secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 5000); + secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 0); if (!secondaryLoop.enter()) { secondaryLoop = null; } diff --git a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java index 0c272763508..07ecefe1def 100644 --- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java +++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java @@ -142,6 +142,9 @@ public abstract class KeyboardFocusManager public void removeLastFocusRequest(Component heavyweight) { KeyboardFocusManager.removeLastFocusRequest(heavyweight); } + public void setMostRecentFocusOwner(Window window, Component component) { + KeyboardFocusManager.setMostRecentFocusOwner(window, component); + } } ); } diff --git a/jdk/src/share/classes/java/awt/event/ActionEvent.java b/jdk/src/share/classes/java/awt/event/ActionEvent.java index ec29e6d09f5..3d5280aa658 100644 --- a/jdk/src/share/classes/java/awt/event/ActionEvent.java +++ b/jdk/src/share/classes/java/awt/event/ActionEvent.java @@ -51,7 +51,7 @@ import java.awt.Event; * in the range from {@code ACTION_FIRST} to {@code ACTION_LAST}. * * @see ActionListener - * @see Tutorial: Java 1.1 Event Model + * @see Tutorial: How to Write an Action Listener * * @author Carl Quinn * @since 1.1 diff --git a/jdk/src/share/classes/java/awt/image/SampleModel.java b/jdk/src/share/classes/java/awt/image/SampleModel.java index cb7bd8a491f..a2b02c44a62 100644 --- a/jdk/src/share/classes/java/awt/image/SampleModel.java +++ b/jdk/src/share/classes/java/awt/image/SampleModel.java @@ -937,14 +937,22 @@ public abstract class SampleModel int iArray[], DataBuffer data) { int pixels[]; int Offset=0; + int x1 = x + w; + int y1 = y + h; + + if (x < 0 || x1 < x || x1 > width || + y < 0 || y1 < y || y1 > height) + { + throw new ArrayIndexOutOfBoundsException("Invalid coordinates."); + } if (iArray != null) pixels = iArray; else pixels = new int[w * h]; - for(int i=y; i<(h+y); i++) { - for (int j=x; j<(w+x); j++) { + for(int i=y; i width || + y < 0 || y1 < y || y1 > height) + { + throw new ArrayIndexOutOfBoundsException("Invalid coordinates"); + } if (fArray != null) pixels = fArray; else pixels = new float[w * h]; - for (int i=y; i<(h+y); i++) { - for (int j=x; j<(w+x); j++) { + for (int i=y; i width || + y < 0 || y1 < y || y1 > height) + { + throw new ArrayIndexOutOfBoundsException("Invalid coordinates"); + } if (dArray != null) pixels = dArray; else pixels = new double[w * h]; - for (int i=y; i<(y+h); i++) { - for (int j=x; j<(x+w); j++) { + for (int i=y; i type, String name, int args) { - for (Method method : type.getMethods()) { - if (method.getName().equals(name) && (args == method.getParameterTypes().length)) { - try { - return MethodFinder.findAccessibleMethod(method); + /** + * Internal support for finding a target methodName with a given + * parameter list on a given class. + */ + private static Method internalFindMethod(Class start, String methodName, + 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) { - // continue search for a method with the specified count of parameters + + // make sure method signature matches. + 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; } } } - return null; + method = 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; } - static Method findInstanceMethod(Class type, String name, Class... args) { - try { - return MethodFinder.findInstanceMethod(type, name, args); - } - catch (NoSuchMethodException exception) { + /** + * Find a target methodName on a given class. + */ + static Method findMethod(Class cls, String methodName, int argCount) { + return findMethod(cls, methodName, argCount, null); + } + + /** + * Find a target methodName with specific parameter list on a given class. + *

+ * Used in the contructors of the EventSetDescriptor, + * PropertyDescriptor and the IndexedPropertyDescriptor. + *

+ * @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 internalFindMethod(cls, methodName, argCount, args); } /** diff --git a/jdk/src/share/classes/java/beans/MethodDescriptor.java b/jdk/src/share/classes/java/beans/MethodDescriptor.java index 74a7a16782d..d9e78be516f 100644 --- a/jdk/src/share/classes/java/beans/MethodDescriptor.java +++ b/jdk/src/share/classes/java/beans/MethodDescriptor.java @@ -90,13 +90,13 @@ public class MethodDescriptor extends FeatureDescriptor { // Find methods for up to 2 params. We are guessing here. // This block should never execute unless the classloader // that loaded the argument classes disappears. - method = Introspector.findMethod(cls, name, i); + method = Introspector.findMethod(cls, name, i, null); if (method != null) { break; } } } else { - method = Statement.getMethod(cls, name, params); + method = Introspector.findMethod(cls, name, params.length, params); } setMethod(method); } diff --git a/jdk/src/share/classes/java/beans/PropertyDescriptor.java b/jdk/src/share/classes/java/beans/PropertyDescriptor.java index c7524e3026f..429d2b4079b 100644 --- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java +++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java @@ -112,7 +112,8 @@ public class PropertyDescriptor extends FeatureDescriptor { // If this class or one of its base classes allow PropertyChangeListener, // then we assume that any properties we discover are "bound". // See Introspector.getTargetPropertyInfo() method. - this.bound = null != Introspector.findInstanceMethod(beanClass, "addPropertyChangeListener", PropertyChangeListener.class); + Class[] args = { PropertyChangeListener.class }; + this.bound = null != Introspector.findMethod(beanClass, "addPropertyChangeListener", args.length, args); } /** @@ -223,10 +224,10 @@ public class PropertyDescriptor extends FeatureDescriptor { // property type is. For booleans, there can be "is" and "get" // methods. If an "is" method exists, this is the official // reader method so look for this one first. - readMethod = Introspector.findInstanceMethod(cls, readMethodName); + readMethod = Introspector.findMethod(cls, readMethodName, 0); if (readMethod == null) { readMethodName = Introspector.GET_PREFIX + getBaseName(); - readMethod = Introspector.findInstanceMethod(cls, readMethodName); + readMethod = Introspector.findMethod(cls, readMethodName, 0); } try { setReadMethod(readMethod); @@ -291,7 +292,8 @@ public class PropertyDescriptor extends FeatureDescriptor { writeMethodName = Introspector.SET_PREFIX + getBaseName(); } - writeMethod = Introspector.findInstanceMethod(cls, writeMethodName, type); + Class[] args = (type == null) ? null : new Class[] { type }; + writeMethod = Introspector.findMethod(cls, writeMethodName, 1, args); if (writeMethod != null) { if (!writeMethod.getReturnType().equals(void.class)) { writeMethod = null; diff --git a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java index 46a14a0aa20..d495f07c3f6 100644 --- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java +++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java @@ -100,7 +100,8 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * @param minimumCapacity the minimum desired capacity. */ public void ensureCapacity(int minimumCapacity) { - ensureCapacityInternal(minimumCapacity); + if (minimumCapacity > 0) + ensureCapacityInternal(minimumCapacity); } /** @@ -108,6 +109,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * never synchronized. */ private void ensureCapacityInternal(int minimumCapacity) { + // overflow-conscious code if (minimumCapacity - value.length > 0) expandCapacity(minimumCapacity); } diff --git a/jdk/src/share/classes/java/lang/ClassLoader.java b/jdk/src/share/classes/java/lang/ClassLoader.java index fd9ba91d720..ce7f0e655e8 100644 --- a/jdk/src/share/classes/java/lang/ClassLoader.java +++ b/jdk/src/share/classes/java/lang/ClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -100,8 +100,11 @@ import sun.security.util.SecurityConstants; * themselves at their class initialization time by invoking the * {@link * #registerAsParallelCapable ClassLoader.registerAsParallelCapable} - * method. In environments in which the delegation model is not strictly - * hierarchical, class loaders need to be parallel capable, otherise class + * method. Note that the ClassLoader class is registered as parallel + * capable by default. However, its subclasses still need to register themselves + * if they are parallel capable.
+ * In environments in which the delegation model is not strictly + * hierarchical, class loaders need to be parallel capable, otherwise class * loading can lead to deadlocks because the loader lock is held for the * duration of the class loading process (see {@link #loadClass * loadClass} methods). @@ -1218,14 +1221,14 @@ public abstract class ClassLoader { private static native Class getCaller(int index); /** - * Registers the caller class loader as parallel capable. - * In order for the registration to succeed, all super classes - * of the caller class loader must also be registered as - * parallel capable when this method is called.

- * Note that once a class loader is registered as - * parallel capable, there is no way to change it back. - * In addition, registration should be done statically before - * any instance of the caller classloader being constructed.

+ * Registers the caller as parallel capable.

+ * The registration succeeds if and only if all of the following + * conditions are met:
+ * 1. no instance of the caller has been created

+ * 2. all of the super classes (except class Object) of the caller are + * registered as parallel capable

+ * Note that once a class loader is registered as parallel capable, there + * is no way to change it back.

* * @return true if the caller is successfully registered as * parallel capable and false if otherwise. diff --git a/jdk/src/share/classes/java/lang/Integer.java b/jdk/src/share/classes/java/lang/Integer.java index ab68cf23c25..ab68f4b2558 100644 --- a/jdk/src/share/classes/java/lang/Integer.java +++ b/jdk/src/share/classes/java/lang/Integer.java @@ -586,25 +586,13 @@ public final class Integer extends Number implements Comparable { * Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS. * - * The cache is initialized on first usage. During VM initialization the - * getAndRemoveCacheProperties method may be used to get and remove any system - * properites that configure the cache size. At this time, the size of the - * cache may be controlled by the -XX:AutoBoxCacheMax= option. + * The cache is initialized on first usage. The size of the cache + * may be controlled by the -XX:AutoBoxCacheMax= option. + * During VM initialization, java.lang.Integer.IntegerCache.high property + * may be set and saved in the private system properties in the + * sun.misc.VM class. */ - // value of java.lang.Integer.IntegerCache.high property (obtained during VM init) - private static String integerCacheHighPropValue; - - static void getAndRemoveCacheProperties() { - if (!sun.misc.VM.isBooted()) { - Properties props = System.getProperties(); - integerCacheHighPropValue = - (String)props.remove("java.lang.Integer.IntegerCache.high"); - if (integerCacheHighPropValue != null) - System.setProperties(props); // remove from system props - } - } - private static class IntegerCache { static final int low = -128; static final int high; @@ -613,6 +601,8 @@ public final class Integer extends Number implements Comparable { static { // high value may be configured by property int h = 127; + String integerCacheHighPropValue = + sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); diff --git a/jdk/src/share/classes/java/lang/System.java b/jdk/src/share/classes/java/lang/System.java index 42431865f25..6df4af69505 100644 --- a/jdk/src/share/classes/java/lang/System.java +++ b/jdk/src/share/classes/java/lang/System.java @@ -53,7 +53,13 @@ import sun.reflect.annotation.AnnotationType; */ public final class System { - /* First thing---register the natives */ + /* register the natives via the static initializer. + * + * VM will invoke the initializeSystemClass method to complete + * the initialization for this class separated from clinit. + * Note that to use properties set by the VM, see the constraints + * described in the initializeSystemClass method. + */ private static native void registerNatives(); static { registerNatives(); @@ -1096,17 +1102,21 @@ public final class System { * Initialize the system class. Called after thread initialization. */ private static void initializeSystemClass() { - props = new Properties(); - initProperties(props); + // There are certain system configurations that may be controlled by + // VM options such as the maximum amount of direct memory and + // Integer cache size used to support the object identity semantics + // of autoboxing. Typically, the library will obtain these values + // from the properties set by the VM. If the properties are for + // internal implementation use only, these properties should be + // removed from the system properties. + // + // See java.lang.Integer.IntegerCache and the + // sun.misc.VM.saveAndRemoveProperties method for example. + props = initSystemProperties(); + lineSeparator = props.getProperty("line.separator"); sun.misc.Version.init(); - // Gets and removes system properties that configure the Integer - // cache used to support the object identity semantics of autoboxing. - // At this time, the size of the cache may be controlled by the - // vm option -XX:AutoBoxCacheMax=. - Integer.getAndRemoveCacheProperties(); - FileInputStream fdIn = new FileInputStream(FileDescriptor.in); FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err); @@ -1127,17 +1137,6 @@ public final class System { // classes are used. sun.misc.VM.initializeOSEnvironment(); - // Set the maximum amount of direct memory. This value is controlled - // by the vm option -XX:MaxDirectMemorySize=. This method acts - // as an initializer only if it is called before sun.misc.VM.booted(). - sun.misc.VM.maxDirectMemory(); - - // Set a boolean to determine whether ClassLoader.loadClass accepts - // array syntax. This value is controlled by the system property - // "sun.lang.ClassLoader.allowArraySyntax". This method acts as - // an initializer only if it is called before sun.misc.VM.booted(). - sun.misc.VM.allowArraySyntax(); - // Subsystems that are invoked during initialization can invoke // sun.misc.VM.isBooted() in order to avoid doing things that should // wait until the application class loader has been set up. @@ -1152,6 +1151,18 @@ public final class System { setJavaLangAccess(); } + private static Properties initSystemProperties() { + Properties props = new Properties(); + initProperties(props); // initialized by the VM + + // Save a private copy of the system properties object that + // can only be accessed by the internal implementation. Remove + // certain system properties that are not intended for public access. + sun.misc.VM.saveAndRemoveProperties(props); + + return props; + } + private static void setJavaLangAccess() { // Allow privileged classes outside of java.lang sun.misc.SharedSecrets.setJavaLangAccess(new sun.misc.JavaLangAccess(){ diff --git a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java index d8053d7b719..a902de61212 100644 --- a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java +++ b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java @@ -28,9 +28,7 @@ package java.net; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.InterruptedIOException; import java.io.FileDescriptor; -import java.io.ByteArrayOutputStream; import sun.net.ConnectionResetException; import sun.net.NetHooks; @@ -58,7 +56,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl protected int fdUseCount = 0; /* lock when increment/decrementing fdUseCount */ - protected Object fdLock = new Object(); + protected final Object fdLock = new Object(); /* indicates a close is pending on the file descriptor */ protected boolean closePending = false; @@ -68,7 +66,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl private int CONNECTION_RESET_PENDING = 1; private int CONNECTION_RESET = 2; private int resetState; - private Object resetLock = new Object(); + private final Object resetLock = new Object(); /** * Load net library into runtime. @@ -100,25 +98,24 @@ abstract class AbstractPlainSocketImpl extends SocketImpl protected void connect(String host, int port) throws UnknownHostException, IOException { - IOException pending = null; + boolean connected = false; try { InetAddress address = InetAddress.getByName(host); this.port = port; this.address = address; - try { - connectToAddress(address, port, timeout); - return; - } catch (IOException e) { - pending = e; + connectToAddress(address, port, timeout); + connected = true; + } finally { + if (!connected) { + try { + close(); + } catch (IOException ioe) { + /* Do nothing. If connect threw an exception then + it will be passed up the call stack */ + } } - } catch (UnknownHostException e) { - pending = e; } - - // everything failed - close(); - throw pending; } /** @@ -151,22 +148,29 @@ abstract class AbstractPlainSocketImpl extends SocketImpl * SocketAddress subclass not supported by this socket * @since 1.4 */ - protected void connect(SocketAddress address, int timeout) throws IOException { - if (address == null || !(address instanceof InetSocketAddress)) - throw new IllegalArgumentException("unsupported address type"); - InetSocketAddress addr = (InetSocketAddress) address; - if (addr.isUnresolved()) - throw new UnknownHostException(addr.getHostName()); - this.port = addr.getPort(); - this.address = addr.getAddress(); - + protected void connect(SocketAddress address, int timeout) + throws IOException { + boolean connected = false; try { + if (address == null || !(address instanceof InetSocketAddress)) + throw new IllegalArgumentException("unsupported address type"); + InetSocketAddress addr = (InetSocketAddress) address; + if (addr.isUnresolved()) + throw new UnknownHostException(addr.getHostName()); + this.port = addr.getPort(); + this.address = addr.getAddress(); + connectToAddress(this.address, port, timeout); - return; - } catch (IOException e) { - // everything failed - close(); - throw e; + connected = true; + } finally { + if (!connected) { + try { + close(); + } catch (IOException ioe) { + /* Do nothing. If connect threw an exception then + it will be passed up the call stack */ + } + } } } @@ -311,7 +315,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl } } try { - FileDescriptor fd = acquireFD(); + acquireFD(); try { socketConnect(address, port, timeout); /* socket may have been closed during poll/select */ @@ -370,7 +374,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl * @param s the connection */ protected void accept(SocketImpl s) throws IOException { - FileDescriptor fd = acquireFD(); + acquireFD(); try { socketAccept(s); } finally { @@ -562,7 +566,6 @@ abstract class AbstractPlainSocketImpl extends SocketImpl close(); } - /* * "Acquires" and returns the FileDescriptor for this impl * diff --git a/jdk/src/share/classes/java/nio/Bits.java b/jdk/src/share/classes/java/nio/Bits.java index fa11b6be785..54f004b6ea9 100644 --- a/jdk/src/share/classes/java/nio/Bits.java +++ b/jdk/src/share/classes/java/nio/Bits.java @@ -622,7 +622,7 @@ class Bits { // package-private // initialization if it is launched with "-XX:MaxDirectMemorySize=". private static volatile long maxMemory = VM.maxDirectMemory(); private static volatile long reservedMemory; - private static volatile long usedMemory; + private static volatile long totalCapacity; private static volatile long count; private static boolean memoryLimitSet = false; @@ -630,15 +630,17 @@ class Bits { // package-private // freed. They allow the user to control the amount of direct memory // which a process may access. All sizes are specified in bytes. static void reserveMemory(long size, int cap) { - synchronized (Bits.class) { if (!memoryLimitSet && VM.isBooted()) { maxMemory = VM.maxDirectMemory(); memoryLimitSet = true; } - if (size <= maxMemory - reservedMemory) { + // -XX:MaxDirectMemorySize limits the total capacity rather than the + // actual memory usage, which will differ when buffers are page + // aligned. + if (cap <= maxMemory - totalCapacity) { reservedMemory += size; - usedMemory += cap; + totalCapacity += cap; count++; return; } @@ -652,10 +654,10 @@ class Bits { // package-private Thread.currentThread().interrupt(); } synchronized (Bits.class) { - if (reservedMemory + size > maxMemory) + if (totalCapacity + cap > maxMemory) throw new OutOfMemoryError("Direct buffer memory"); reservedMemory += size; - usedMemory += cap; + totalCapacity += cap; count++; } @@ -664,7 +666,7 @@ class Bits { // package-private static synchronized void unreserveMemory(long size, int cap) { if (reservedMemory > 0) { reservedMemory -= size; - usedMemory -= cap; + totalCapacity -= cap; count--; assert (reservedMemory > -1); } @@ -689,7 +691,7 @@ class Bits { // package-private } @Override public long getTotalCapacity() { - return Bits.usedMemory; + return Bits.totalCapacity; } @Override public long getMemoryUsed() { diff --git a/jdk/src/share/classes/java/nio/Direct-X-Buffer.java.template b/jdk/src/share/classes/java/nio/Direct-X-Buffer.java.template index 520b9c46504..0b785175a66 100644 --- a/jdk/src/share/classes/java/nio/Direct-X-Buffer.java.template +++ b/jdk/src/share/classes/java/nio/Direct-X-Buffer.java.template @@ -27,8 +27,10 @@ package java.nio; +import java.io.FileDescriptor; import sun.misc.Cleaner; import sun.misc.Unsafe; +import sun.misc.VM; import sun.nio.ch.DirectBuffer; @@ -113,9 +115,10 @@ class Direct$Type$Buffer$RW$$BO$ // Direct$Type$Buffer$RW$(int cap) { // package-private #if[rw] - super(-1, 0, cap, cap, false); + super(-1, 0, cap, cap); + boolean pa = VM.isDirectMemoryPageAligned(); int ps = Bits.pageSize(); - int size = cap + ps; + long size = Math.max(1L, (long)cap + (pa ? ps : 0)); Bits.reserveMemory(size, cap); long base = 0; @@ -126,7 +129,7 @@ class Direct$Type$Buffer$RW$$BO$ throw x; } unsafe.setMemory(base, size, (byte) 0); - if (base % ps != 0) { + if (pa && (base % ps != 0)) { // Round up to page boundary address = base + ps - (base & (ps - 1)); } else { @@ -143,7 +146,7 @@ class Direct$Type$Buffer$RW$$BO$ // Invoked only by JNI: NewDirectByteBuffer(void*, long) // private Direct$Type$Buffer(long addr, int cap) { - super(-1, 0, cap, cap, false); + super(-1, 0, cap, cap); address = addr; cleaner = null; } @@ -152,14 +155,17 @@ class Direct$Type$Buffer$RW$$BO$ // For memory-mapped buffers -- invoked by FileChannelImpl via reflection // - protected Direct$Type$Buffer$RW$(int cap, long addr, Runnable unmapper) { + protected Direct$Type$Buffer$RW$(int cap, long addr, + FileDescriptor fd, + Runnable unmapper) + { #if[rw] - super(-1, 0, cap, cap, true); + super(-1, 0, cap, cap, fd); address = addr; viewedBuffer = null; cleaner = Cleaner.create(this, unmapper); #else[rw] - super(cap, addr, unmapper); + super(cap, addr, fd, unmapper); #end[rw] } diff --git a/jdk/src/share/classes/java/nio/MappedByteBuffer.java b/jdk/src/share/classes/java/nio/MappedByteBuffer.java index 4811f41d2e1..9c2a446716f 100644 --- a/jdk/src/share/classes/java/nio/MappedByteBuffer.java +++ b/jdk/src/share/classes/java/nio/MappedByteBuffer.java @@ -25,6 +25,7 @@ package java.nio; +import java.io.FileDescriptor; import sun.misc.Unsafe; @@ -71,26 +72,26 @@ public abstract class MappedByteBuffer // for optimization purposes, it's easier to do it the other way around. // This works because DirectByteBuffer is a package-private class. - // Volatile to make sure that the finalization thread sees the current - // value of this so that a region is not accidentally unmapped again later. - volatile boolean isAMappedBuffer; // package-private + // For mapped buffers, a FileDescriptor that may be used for mapping + // operations if valid; null if the buffer is not mapped. + private final FileDescriptor fd; // This should only be invoked by the DirectByteBuffer constructors // MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private - boolean mapped) + FileDescriptor fd) { super(mark, pos, lim, cap); - isAMappedBuffer = mapped; + this.fd = fd; } MappedByteBuffer(int mark, int pos, int lim, int cap) { // package-private super(mark, pos, lim, cap); - isAMappedBuffer = false; + this.fd = null; } private void checkMapped() { - if (!isAMappedBuffer) + if (fd == null) // Can only happen if a luser explicitly casts a direct byte buffer throw new UnsupportedOperationException(); } @@ -191,13 +192,12 @@ public abstract class MappedByteBuffer checkMapped(); if ((address != 0) && (capacity() != 0)) { long offset = mappingOffset(); - force0(mappingAddress(offset), mappingLength(offset)); + force0(fd, mappingAddress(offset), mappingLength(offset)); } return this; } private native boolean isLoaded0(long address, long length, int pageCount); private native void load0(long address, long length); - private native void force0(long address, long length); - + private native void force0(FileDescriptor fd, long address, long length); } diff --git a/jdk/src/share/classes/java/security/cert/CertificateRevokedException.java b/jdk/src/share/classes/java/security/cert/CertificateRevokedException.java index 7f4660bd74c..a76299ccc0d 100644 --- a/jdk/src/share/classes/java/security/cert/CertificateRevokedException.java +++ b/jdk/src/share/classes/java/security/cert/CertificateRevokedException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -61,8 +61,8 @@ public class CertificateRevokedException extends CertificateException { */ private final CRLReason reason; /** - * @serial the name of the authority that signed the certificate's - * revocation status information + * @serial the X500Principal that represents the name of the + * authority that signed the certificate's revocation status information */ private final X500Principal authority; @@ -79,8 +79,9 @@ public class CertificateRevokedException extends CertificateException { * @param extensions a map of X.509 Extensions. Each key is an OID String * that maps to the corresponding Extension. The map is copied to * prevent subsequent modification. - * @param authority the name of the authority that signed the certificate's - * revocation status information + * @param authority the X500Principal that represents the name + * of the authority that signed the certificate's revocation status + * information * @throws NullPointerException if revocationDate, * reason, authority, or * extensions is null @@ -121,8 +122,8 @@ public class CertificateRevokedException extends CertificateException { * Returns the name of the authority that signed the certificate's * revocation status information. * - * @return the name of the authority that signed the certificate's - * revocation status information + * @return the X500Principal that represents the name of the + * authority that signed the certificate's revocation status information */ public X500Principal getAuthorityName() { return authority; diff --git a/jdk/src/share/classes/java/util/ArrayList.java b/jdk/src/share/classes/java/util/ArrayList.java index 4b746ea0124..7c6eded3a83 100644 --- a/jdk/src/share/classes/java/util/ArrayList.java +++ b/jdk/src/share/classes/java/util/ArrayList.java @@ -176,6 +176,11 @@ public class ArrayList extends AbstractList * @param minCapacity the desired minimum capacity */ public void ensureCapacity(int minCapacity) { + if (minCapacity > 0) + ensureCapacityInternal(minCapacity); + } + + private void ensureCapacityInternal(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) @@ -403,7 +408,7 @@ public class ArrayList extends AbstractList * @return true (as specified by {@link Collection#add}) */ public boolean add(E e) { - ensureCapacity(size + 1); // Increments modCount!! + ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } @@ -420,7 +425,7 @@ public class ArrayList extends AbstractList public void add(int index, E element) { rangeCheckForAdd(index); - ensureCapacity(size + 1); // Increments modCount!! + ensureCapacityInternal(size + 1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; @@ -524,7 +529,7 @@ public class ArrayList extends AbstractList public boolean addAll(Collection c) { Object[] a = c.toArray(); int numNew = a.length; - ensureCapacity(size + numNew); // Increments modCount + ensureCapacityInternal(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; @@ -550,7 +555,7 @@ public class ArrayList extends AbstractList Object[] a = c.toArray(); int numNew = a.length; - ensureCapacity(size + numNew); // Increments modCount + ensureCapacityInternal(size + numNew); // Increments modCount int numMoved = size - index; if (numMoved > 0) diff --git a/jdk/src/share/classes/java/util/Arrays.java b/jdk/src/share/classes/java/util/Arrays.java index 54abbb27c8d..b4951e14f11 100644 --- a/jdk/src/share/classes/java/util/Arrays.java +++ b/jdk/src/share/classes/java/util/Arrays.java @@ -97,7 +97,8 @@ public class Arrays { * if {@code fromIndex < 0} or {@code toIndex > a.length} */ public static void sort(int[] a, int fromIndex, int toIndex) { - DualPivotQuicksort.sort(a, fromIndex, toIndex); + rangeCheck(a.length, fromIndex, toIndex); + DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); } /** @@ -136,7 +137,8 @@ public class Arrays { * if {@code fromIndex < 0} or {@code toIndex > a.length} */ public static void sort(long[] a, int fromIndex, int toIndex) { - DualPivotQuicksort.sort(a, fromIndex, toIndex); + rangeCheck(a.length, fromIndex, toIndex); + DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); } /** @@ -175,7 +177,8 @@ public class Arrays { * if {@code fromIndex < 0} or {@code toIndex > a.length} */ public static void sort(short[] a, int fromIndex, int toIndex) { - DualPivotQuicksort.sort(a, fromIndex, toIndex); + rangeCheck(a.length, fromIndex, toIndex); + DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); } /** @@ -214,7 +217,8 @@ public class Arrays { * if {@code fromIndex < 0} or {@code toIndex > a.length} */ public static void sort(char[] a, int fromIndex, int toIndex) { - DualPivotQuicksort.sort(a, fromIndex, toIndex); + rangeCheck(a.length, fromIndex, toIndex); + DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); } /** @@ -253,7 +257,8 @@ public class Arrays { * if {@code fromIndex < 0} or {@code toIndex > a.length} */ public static void sort(byte[] a, int fromIndex, int toIndex) { - DualPivotQuicksort.sort(a, fromIndex, toIndex); + rangeCheck(a.length, fromIndex, toIndex); + DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); } /** @@ -308,7 +313,8 @@ public class Arrays { * if {@code fromIndex < 0} or {@code toIndex > a.length} */ public static void sort(float[] a, int fromIndex, int toIndex) { - DualPivotQuicksort.sort(a, fromIndex, toIndex); + rangeCheck(a.length, fromIndex, toIndex); + DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); } /** @@ -363,12 +369,12 @@ public class Arrays { * if {@code fromIndex < 0} or {@code toIndex > a.length} */ public static void sort(double[] a, int fromIndex, int toIndex) { - DualPivotQuicksort.sort(a, fromIndex, toIndex); + rangeCheck(a.length, fromIndex, toIndex); + DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); } /* * Sorting of complex type arrays. - * */ /** diff --git a/jdk/src/share/classes/java/util/DualPivotQuicksort.java b/jdk/src/share/classes/java/util/DualPivotQuicksort.java index 873230a2c73..616ee2e2fe2 100644 --- a/jdk/src/share/classes/java/util/DualPivotQuicksort.java +++ b/jdk/src/share/classes/java/util/DualPivotQuicksort.java @@ -36,7 +36,7 @@ package java.util; * @author Jon Bentley * @author Josh Bloch * - * @version 2010.06.21 m765.827.12i:5\7 + * @version 2010.10.13 m765.827.12i:5\7p * @since 1.7 */ final class DualPivotQuicksort { @@ -54,26 +54,26 @@ final class DualPivotQuicksort { * If the length of an array to be sorted is less than this * constant, insertion sort is used in preference to Quicksort. */ - private static final int INSERTION_SORT_THRESHOLD = 32; + private static final int INSERTION_SORT_THRESHOLD = 47; /** - * If the length of a byte array to be sorted is greater than - * this constant, counting sort is used in preference to Quicksort. + * If the length of a byte array to be sorted is greater than this + * constant, counting sort is used in preference to insertion sort. */ - private static final int COUNTING_SORT_THRESHOLD_FOR_BYTE = 128; + private static final int COUNTING_SORT_THRESHOLD_FOR_BYTE = 29; /** * If the length of a short or char array to be sorted is greater * than this constant, counting sort is used in preference to Quicksort. */ - private static final int COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR = 32768; + private static final int COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR = 3200; /* * Sorting methods for seven primitive types. */ /** - * Sorts the specified array into ascending numerical order. + * Sorts the specified array. * * @param a the array to be sorted */ @@ -82,58 +82,34 @@ final class DualPivotQuicksort { } /** - * Sorts the specified range of the array into ascending order. The range - * to be sorted extends from the index {@code fromIndex}, inclusive, to - * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty (and the call is a no-op). - * - * @param a the array to be sorted - * @param fromIndex the index of the first element, inclusive, to be sorted - * @param toIndex the index of the last element, exclusive, to be sorted - * @throws IllegalArgumentException if {@code fromIndex > toIndex} - * @throws ArrayIndexOutOfBoundsException - * if {@code fromIndex < 0} or {@code toIndex > a.length} - */ - public static void sort(int[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); - sort(a, fromIndex, toIndex - 1, true); - } - - /** - * Sorts the specified range of the array into ascending order by the - * Dual-Pivot Quicksort algorithm. This method differs from the public - * {@code sort} method in that the {@code right} index is inclusive, - * it does no range checking on {@code left} or {@code right}, and has - * boolean flag whether insertion sort with sentinel is used or not. + * Sorts the specified range of the array. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted - * @param leftmost indicates if the part is the most left in the range + */ + public static void sort(int[] a, int left, int right) { + sort(a, left, right, true); + } + + /** + * Sorts the specified range of the array by Dual-Pivot Quicksort. + * + * @param a the array to be sorted + * @param left the index of the first element, inclusive, to be sorted + * @param right the index of the last element, inclusive, to be sorted + * @param leftmost indicates if this part is the leftmost in the range */ private static void sort(int[] a, int left, int right, boolean leftmost) { int length = right - left + 1; - // Use insertion sort on tiny arrays + // Use insertion sort on small arrays if (length < INSERTION_SORT_THRESHOLD) { - if (!leftmost) { + if (leftmost) { /* - * Every element in adjoining part plays the role - * of sentinel, therefore this allows us to avoid - * the j >= left check on each iteration. - */ - for (int j, i = left + 1; i <= right; i++) { - int ai = a[i]; - for (j = i - 1; ai < a[j]; j--) { - // assert j >= left; - a[j + 1] = a[j]; - } - a[j + 1] = ai; - } - } else { - /* - * For case of leftmost part traditional (without a sentinel) - * insertion sort, optimized for server JVM, is used. + * Traditional (without sentinel) insertion sort, + * optimized for server VM, is used in case of + * the leftmost part. */ for (int i = left, j = i; i < right; j = ++i) { int ai = a[i + 1]; @@ -145,12 +121,54 @@ final class DualPivotQuicksort { } a[j + 1] = ai; } + } else { + /* + * Skip the longest ascending sequence. + */ + do { + if (left++ >= right) { + return; + } + } while (a[left - 1] <= a[left]); + + /* + * Every element from adjoining part plays the role + * of sentinel, therefore this allows us to avoid the + * left range check on each iteration. Moreover, we use + * the best improved algorithm, so called pair insertion + * sort, which is faster than traditional implementation + * in the context of Dual-Pivot Quicksort. + */ + for (int k = left--; (left += 2) <= right; ) { + int a1, a2; k = left - 1; + + if (a[k] < a[left]) { + a2 = a[k]; a1 = a[left]; + } else { + a1 = a[k]; a2 = a[left]; + } + while (a1 < a[--k]) { + a[k + 2] = a[k]; + } + a[++k + 1] = a1; + + while (a2 < a[--k]) { + a[k + 1] = a[k]; + } + a[k + 1] = a2; + } + int last = a[right]; + + while (last < a[--right]) { + a[right + 1] = a[right]; + } + a[right + 1] = last; } return; } // Inexpensive approximation of length / 7 - int seventh = (length >>> 3) + (length >>> 6) + 1; + int seventh = (length >> 3) + (length >> 6) + 1; /* * Sort five evenly spaced elements around (and including) the @@ -232,10 +250,14 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { int ak = a[k]; if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; + /* + * Here and below we use "a[i] = b; i++;" instead + * of "a[i++] = b;" due to performance issue. + */ a[less] = ak; less++; } else if (ak > pivot2) { // Move a[k] to right part @@ -244,13 +266,17 @@ final class DualPivotQuicksort { break outer; } } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot2 a[k] = a[less]; a[less] = a[great]; less++; } else { // pivot1 <= a[great] <= pivot2 a[k] = a[great]; } + /* + * Here and below we use "a[i] = b; i--;" instead + * of "a[i--] = b;" due to performance issue. + */ a[great] = ak; great--; } @@ -265,7 +291,7 @@ final class DualPivotQuicksort { sort(a, great + 2, right, false); /* - * If center part is too large (comprises > 5/7 of the array), + * If center part is too large (comprises > 4/7 of the array), * swap internal pivot values to ends. */ if (less < e1 && e5 < great) { @@ -299,7 +325,7 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { int ak = a[k]; if (ak == pivot1) { // Move a[k] to left part a[k] = a[less]; @@ -311,7 +337,7 @@ final class DualPivotQuicksort { break outer; } } - if (a[great] == pivot1) { + if (a[great] == pivot1) { // a[great] < pivot2 a[k] = a[less]; /* * Even though a[great] equals to pivot1, the @@ -337,7 +363,7 @@ final class DualPivotQuicksort { } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way + * Partitioning degenerates to the traditional 3-way * (or "Dutch National Flag") schema: * * left part center part right part @@ -356,28 +382,20 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part. */ - for (int k = left; k <= great; k++) { + for (int k = less; k <= great; ++k) { if (a[k] == pivot1) { continue; } int ak = a[k]; - if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; a[less] = ak; less++; } else { // a[k] > pivot1 - Move a[k] to right part - /* - * We know that pivot1 == a[e3] == pivot2. Thus, we know - * that great will still be >= k when the following loop - * terminates, even though we don't test for it explicitly. - * In other words, a[e3] acts as a sentinel for great. - */ while (a[great] > pivot1) { - // assert great > k; great--; } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot1 a[k] = a[less]; a[less] = a[great]; less++; @@ -397,14 +415,18 @@ final class DualPivotQuicksort { } } - // Sort left and right parts recursively + /* + * Sort left and right parts recursively. + * All elements from center part are equal + * and, therefore, already sorted. + */ sort(a, left, less - 1, leftmost); sort(a, great + 1, right, false); } } /** - * Sorts the specified array into ascending numerical order. + * Sorts the specified array. * * @param a the array to be sorted */ @@ -413,58 +435,34 @@ final class DualPivotQuicksort { } /** - * Sorts the specified range of the array into ascending order. The range - * to be sorted extends from the index {@code fromIndex}, inclusive, to - * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty (and the call is a no-op). - * - * @param a the array to be sorted - * @param fromIndex the index of the first element, inclusive, to be sorted - * @param toIndex the index of the last element, exclusive, to be sorted - * @throws IllegalArgumentException if {@code fromIndex > toIndex} - * @throws ArrayIndexOutOfBoundsException - * if {@code fromIndex < 0} or {@code toIndex > a.length} - */ - public static void sort(long[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); - sort(a, fromIndex, toIndex - 1, true); - } - - /** - * Sorts the specified range of the array into ascending order by the - * Dual-Pivot Quicksort algorithm. This method differs from the public - * {@code sort} method in that the {@code right} index is inclusive, - * it does no range checking on {@code left} or {@code right}, and has - * boolean flag whether insertion sort with sentinel is used or not. + * Sorts the specified range of the array. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted - * @param leftmost indicates if the part is the most left in the range + */ + public static void sort(long[] a, int left, int right) { + sort(a, left, right, true); + } + + /** + * Sorts the specified range of the array by Dual-Pivot Quicksort. + * + * @param a the array to be sorted + * @param left the index of the first element, inclusive, to be sorted + * @param right the index of the last element, inclusive, to be sorted + * @param leftmost indicates if this part is the leftmost in the range */ private static void sort(long[] a, int left, int right, boolean leftmost) { int length = right - left + 1; - // Use insertion sort on tiny arrays + // Use insertion sort on small arrays if (length < INSERTION_SORT_THRESHOLD) { - if (!leftmost) { + if (leftmost) { /* - * Every element in adjoining part plays the role - * of sentinel, therefore this allows us to avoid - * the j >= left check on each iteration. - */ - for (int j, i = left + 1; i <= right; i++) { - long ai = a[i]; - for (j = i - 1; ai < a[j]; j--) { - // assert j >= left; - a[j + 1] = a[j]; - } - a[j + 1] = ai; - } - } else { - /* - * For case of leftmost part traditional (without a sentinel) - * insertion sort, optimized for server JVM, is used. + * Traditional (without sentinel) insertion sort, + * optimized for server VM, is used in case of + * the leftmost part. */ for (int i = left, j = i; i < right; j = ++i) { long ai = a[i + 1]; @@ -476,12 +474,54 @@ final class DualPivotQuicksort { } a[j + 1] = ai; } + } else { + /* + * Skip the longest ascending sequence. + */ + do { + if (left++ >= right) { + return; + } + } while (a[left - 1] <= a[left]); + + /* + * Every element from adjoining part plays the role + * of sentinel, therefore this allows us to avoid the + * left range check on each iteration. Moreover, we use + * the best improved algorithm, so called pair insertion + * sort, which is faster than traditional implementation + * in the context of Dual-Pivot Quicksort. + */ + for (int k = left--; (left += 2) <= right; ) { + long a1, a2; k = left - 1; + + if (a[k] < a[left]) { + a2 = a[k]; a1 = a[left]; + } else { + a1 = a[k]; a2 = a[left]; + } + while (a1 < a[--k]) { + a[k + 2] = a[k]; + } + a[++k + 1] = a1; + + while (a2 < a[--k]) { + a[k + 1] = a[k]; + } + a[k + 1] = a2; + } + long last = a[right]; + + while (last < a[--right]) { + a[right + 1] = a[right]; + } + a[right + 1] = last; } return; } // Inexpensive approximation of length / 7 - int seventh = (length >>> 3) + (length >>> 6) + 1; + int seventh = (length >> 3) + (length >> 6) + 1; /* * Sort five evenly spaced elements around (and including) the @@ -563,10 +603,14 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { long ak = a[k]; if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; + /* + * Here and below we use "a[i] = b; i++;" instead + * of "a[i++] = b;" due to performance issue. + */ a[less] = ak; less++; } else if (ak > pivot2) { // Move a[k] to right part @@ -575,13 +619,17 @@ final class DualPivotQuicksort { break outer; } } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot2 a[k] = a[less]; a[less] = a[great]; less++; } else { // pivot1 <= a[great] <= pivot2 a[k] = a[great]; } + /* + * Here and below we use "a[i] = b; i--;" instead + * of "a[i--] = b;" due to performance issue. + */ a[great] = ak; great--; } @@ -596,7 +644,7 @@ final class DualPivotQuicksort { sort(a, great + 2, right, false); /* - * If center part is too large (comprises > 5/7 of the array), + * If center part is too large (comprises > 4/7 of the array), * swap internal pivot values to ends. */ if (less < e1 && e5 < great) { @@ -630,7 +678,7 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { long ak = a[k]; if (ak == pivot1) { // Move a[k] to left part a[k] = a[less]; @@ -642,7 +690,7 @@ final class DualPivotQuicksort { break outer; } } - if (a[great] == pivot1) { + if (a[great] == pivot1) { // a[great] < pivot2 a[k] = a[less]; /* * Even though a[great] equals to pivot1, the @@ -668,7 +716,7 @@ final class DualPivotQuicksort { } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way + * Partitioning degenerates to the traditional 3-way * (or "Dutch National Flag") schema: * * left part center part right part @@ -687,28 +735,20 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part. */ - for (int k = left; k <= great; k++) { + for (int k = less; k <= great; ++k) { if (a[k] == pivot1) { continue; } long ak = a[k]; - if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; a[less] = ak; less++; } else { // a[k] > pivot1 - Move a[k] to right part - /* - * We know that pivot1 == a[e3] == pivot2. Thus, we know - * that great will still be >= k when the following loop - * terminates, even though we don't test for it explicitly. - * In other words, a[e3] acts as a sentinel for great. - */ while (a[great] > pivot1) { - // assert great > k; great--; } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot1 a[k] = a[less]; a[less] = a[great]; less++; @@ -728,45 +768,51 @@ final class DualPivotQuicksort { } } - // Sort left and right parts recursively + /* + * Sort left and right parts recursively. + * All elements from center part are equal + * and, therefore, already sorted. + */ sort(a, left, less - 1, leftmost); sort(a, great + 1, right, false); } } /** - * Sorts the specified array into ascending numerical order. + * Sorts the specified array. * * @param a the array to be sorted */ public static void sort(short[] a) { - if (a.length > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { - countingSort(a, 0, a.length - 1); - } else { - sort(a, 0, a.length - 1, true); - } + sort(a, 0, a.length - 1); } /** - * Sorts the specified range of the array into ascending order. The range - * to be sorted extends from the index {@code fromIndex}, inclusive, to - * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty (and the call is a no-op). + * Sorts the specified range of the array. * * @param a the array to be sorted - * @param fromIndex the index of the first element, inclusive, to be sorted - * @param toIndex the index of the last element, exclusive, to be sorted - * @throws IllegalArgumentException if {@code fromIndex > toIndex} - * @throws ArrayIndexOutOfBoundsException - * if {@code fromIndex < 0} or {@code toIndex > a.length} + * @param left the index of the first element, inclusive, to be sorted + * @param right the index of the last element, inclusive, to be sorted */ - public static void sort(short[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); + public static void sort(short[] a, int left, int right) { + // Use counting sort on large arrays + if (right - left > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { + int[] count = new int[NUM_SHORT_VALUES]; - if (toIndex - fromIndex > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { - countingSort(a, fromIndex, toIndex - 1); - } else { - sort(a, fromIndex, toIndex - 1, true); + for (int i = left - 1; ++i <= right; ) { + count[a[i] - Short.MIN_VALUE]++; + } + for (int i = NUM_SHORT_VALUES, k = right + 1; k > left; ) { + while (count[--i] == 0); + short value = (short) (i + Short.MIN_VALUE); + int s = count[i]; + + do { + a[--k] = value; + } while (--s > 0); + } + } else { // Use Dual-Pivot Quicksort on small arrays + sort(a, left, right, true); } } @@ -774,66 +820,23 @@ final class DualPivotQuicksort { private static final int NUM_SHORT_VALUES = 1 << 16; /** - * Sorts the specified range of the array by counting sort. + * Sorts the specified range of the array by Dual-Pivot Quicksort. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted - */ - private static void countingSort(short[] a, int left, int right) { - int[] count = new int[NUM_SHORT_VALUES]; - - for (int i = left; i <= right; i++) { - count[a[i] - Short.MIN_VALUE]++; - } - for (int i = NUM_SHORT_VALUES - 1, k = right; k >= left; i--) { - while (count[i] == 0) { - i--; - } - short value = (short) (i + Short.MIN_VALUE); - int s = count[i]; - - do { - a[k--] = value; - } while (--s > 0); - } - } - - /** - * Sorts the specified range of the array into ascending order by the - * Dual-Pivot Quicksort algorithm. This method differs from the public - * {@code sort} method in that the {@code right} index is inclusive, - * it does no range checking on {@code left} or {@code right}, and has - * boolean flag whether insertion sort with sentinel is used or not. - * - * @param a the array to be sorted - * @param left the index of the first element, inclusive, to be sorted - * @param right the index of the last element, inclusive, to be sorted - * @param leftmost indicates if the part is the most left in the range + * @param leftmost indicates if this part is the leftmost in the range */ private static void sort(short[] a, int left, int right,boolean leftmost) { int length = right - left + 1; - // Use insertion sort on tiny arrays + // Use insertion sort on small arrays if (length < INSERTION_SORT_THRESHOLD) { - if (!leftmost) { + if (leftmost) { /* - * Every element in adjoining part plays the role - * of sentinel, therefore this allows us to avoid - * the j >= left check on each iteration. - */ - for (int j, i = left + 1; i <= right; i++) { - short ai = a[i]; - for (j = i - 1; ai < a[j]; j--) { - // assert j >= left; - a[j + 1] = a[j]; - } - a[j + 1] = ai; - } - } else { - /* - * For case of leftmost part traditional (without a sentinel) - * insertion sort, optimized for server JVM, is used. + * Traditional (without sentinel) insertion sort, + * optimized for server VM, is used in case of + * the leftmost part. */ for (int i = left, j = i; i < right; j = ++i) { short ai = a[i + 1]; @@ -845,12 +848,54 @@ final class DualPivotQuicksort { } a[j + 1] = ai; } + } else { + /* + * Skip the longest ascending sequence. + */ + do { + if (left++ >= right) { + return; + } + } while (a[left - 1] <= a[left]); + + /* + * Every element from adjoining part plays the role + * of sentinel, therefore this allows us to avoid the + * left range check on each iteration. Moreover, we use + * the best improved algorithm, so called pair insertion + * sort, which is faster than traditional implementation + * in the context of Dual-Pivot Quicksort. + */ + for (int k = left--; (left += 2) <= right; ) { + short a1, a2; k = left - 1; + + if (a[k] < a[left]) { + a2 = a[k]; a1 = a[left]; + } else { + a1 = a[k]; a2 = a[left]; + } + while (a1 < a[--k]) { + a[k + 2] = a[k]; + } + a[++k + 1] = a1; + + while (a2 < a[--k]) { + a[k + 1] = a[k]; + } + a[k + 1] = a2; + } + short last = a[right]; + + while (last < a[--right]) { + a[right + 1] = a[right]; + } + a[right + 1] = last; } return; } // Inexpensive approximation of length / 7 - int seventh = (length >>> 3) + (length >>> 6) + 1; + int seventh = (length >> 3) + (length >> 6) + 1; /* * Sort five evenly spaced elements around (and including) the @@ -932,10 +977,14 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { short ak = a[k]; if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; + /* + * Here and below we use "a[i] = b; i++;" instead + * of "a[i++] = b;" due to performance issue. + */ a[less] = ak; less++; } else if (ak > pivot2) { // Move a[k] to right part @@ -944,13 +993,17 @@ final class DualPivotQuicksort { break outer; } } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot2 a[k] = a[less]; a[less] = a[great]; less++; } else { // pivot1 <= a[great] <= pivot2 a[k] = a[great]; } + /* + * Here and below we use "a[i] = b; i--;" instead + * of "a[i--] = b;" due to performance issue. + */ a[great] = ak; great--; } @@ -965,7 +1018,7 @@ final class DualPivotQuicksort { sort(a, great + 2, right, false); /* - * If center part is too large (comprises > 5/7 of the array), + * If center part is too large (comprises > 4/7 of the array), * swap internal pivot values to ends. */ if (less < e1 && e5 < great) { @@ -999,7 +1052,7 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { short ak = a[k]; if (ak == pivot1) { // Move a[k] to left part a[k] = a[less]; @@ -1011,7 +1064,7 @@ final class DualPivotQuicksort { break outer; } } - if (a[great] == pivot1) { + if (a[great] == pivot1) { // a[great] < pivot2 a[k] = a[less]; /* * Even though a[great] equals to pivot1, the @@ -1037,7 +1090,7 @@ final class DualPivotQuicksort { } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way + * Partitioning degenerates to the traditional 3-way * (or "Dutch National Flag") schema: * * left part center part right part @@ -1056,28 +1109,20 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part. */ - for (int k = left; k <= great; k++) { + for (int k = less; k <= great; ++k) { if (a[k] == pivot1) { continue; } short ak = a[k]; - if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; a[less] = ak; less++; } else { // a[k] > pivot1 - Move a[k] to right part - /* - * We know that pivot1 == a[e3] == pivot2. Thus, we know - * that great will still be >= k when the following loop - * terminates, even though we don't test for it explicitly. - * In other words, a[e3] acts as a sentinel for great. - */ while (a[great] > pivot1) { - // assert great > k; great--; } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot1 a[k] = a[less]; a[less] = a[great]; less++; @@ -1097,45 +1142,51 @@ final class DualPivotQuicksort { } } - // Sort left and right parts recursively + /* + * Sort left and right parts recursively. + * All elements from center part are equal + * and, therefore, already sorted. + */ sort(a, left, less - 1, leftmost); sort(a, great + 1, right, false); } } /** - * Sorts the specified array into ascending numerical order. + * Sorts the specified array. * * @param a the array to be sorted */ public static void sort(char[] a) { - if (a.length > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { - countingSort(a, 0, a.length - 1); - } else { - sort(a, 0, a.length - 1, true); - } + sort(a, 0, a.length - 1); } /** - * Sorts the specified range of the array into ascending order. The range - * to be sorted extends from the index {@code fromIndex}, inclusive, to - * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty (and the call is a no-op). + * Sorts the specified range of the array. * * @param a the array to be sorted - * @param fromIndex the index of the first element, inclusive, to be sorted - * @param toIndex the index of the last element, exclusive, to be sorted - * @throws IllegalArgumentException if {@code fromIndex > toIndex} - * @throws ArrayIndexOutOfBoundsException - * if {@code fromIndex < 0} or {@code toIndex > a.length} + * @param left the index of the first element, inclusive, to be sorted + * @param right the index of the last element, inclusive, to be sorted */ - public static void sort(char[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); + public static void sort(char[] a, int left, int right) { + // Use counting sort on large arrays + if (right - left > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { + int[] count = new int[NUM_CHAR_VALUES]; - if (toIndex - fromIndex > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { - countingSort(a, fromIndex, toIndex - 1); - } else { - sort(a, fromIndex, toIndex - 1, true); + for (int i = left - 1; ++i <= right; ) { + count[a[i]]++; + } + for (int i = NUM_CHAR_VALUES, k = right + 1; k > left; ) { + while (count[--i] == 0); + char value = (char) i; + int s = count[i]; + + do { + a[--k] = value; + } while (--s > 0); + } + } else { // Use Dual-Pivot Quicksort on small arrays + sort(a, left, right, true); } } @@ -1143,66 +1194,23 @@ final class DualPivotQuicksort { private static final int NUM_CHAR_VALUES = 1 << 16; /** - * Sorts the specified range of the array by counting sort. + * Sorts the specified range of the array by Dual-Pivot Quicksort. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted - */ - private static void countingSort(char[] a, int left, int right) { - int[] count = new int[NUM_CHAR_VALUES]; - - for (int i = left; i <= right; i++) { - count[a[i]]++; - } - for (int i = 0, k = left; k <= right; i++) { - while (count[i] == 0) { - i++; - } - char value = (char) i; - int s = count[i]; - - do { - a[k++] = value; - } while (--s > 0); - } - } - - /** - * Sorts the specified range of the array into ascending order by the - * Dual-Pivot Quicksort algorithm. This method differs from the public - * {@code sort} method in that the {@code right} index is inclusive, - * it does no range checking on {@code left} or {@code right}, and has - * boolean flag whether insertion sort with sentinel is used or not. - * - * @param a the array to be sorted - * @param left the index of the first element, inclusive, to be sorted - * @param right the index of the last element, inclusive, to be sorted - * @param leftmost indicates if the part is the most left in the range + * @param leftmost indicates if this part is the leftmost in the range */ private static void sort(char[] a, int left, int right, boolean leftmost) { int length = right - left + 1; - // Use insertion sort on tiny arrays + // Use insertion sort on small arrays if (length < INSERTION_SORT_THRESHOLD) { - if (!leftmost) { + if (leftmost) { /* - * Every element in adjoining part plays the role - * of sentinel, therefore this allows us to avoid - * the j >= left check on each iteration. - */ - for (int j, i = left + 1; i <= right; i++) { - char ai = a[i]; - for (j = i - 1; ai < a[j]; j--) { - // assert j >= left; - a[j + 1] = a[j]; - } - a[j + 1] = ai; - } - } else { - /* - * For case of leftmost part traditional (without a sentinel) - * insertion sort, optimized for server JVM, is used. + * Traditional (without sentinel) insertion sort, + * optimized for server VM, is used in case of + * the leftmost part. */ for (int i = left, j = i; i < right; j = ++i) { char ai = a[i + 1]; @@ -1214,12 +1222,54 @@ final class DualPivotQuicksort { } a[j + 1] = ai; } + } else { + /* + * Skip the longest ascending sequence. + */ + do { + if (left++ >= right) { + return; + } + } while (a[left - 1] <= a[left]); + + /* + * Every element from adjoining part plays the role + * of sentinel, therefore this allows us to avoid the + * left range check on each iteration. Moreover, we use + * the best improved algorithm, so called pair insertion + * sort, which is faster than traditional implementation + * in the context of Dual-Pivot Quicksort. + */ + for (int k = left--; (left += 2) <= right; ) { + char a1, a2; k = left - 1; + + if (a[k] < a[left]) { + a2 = a[k]; a1 = a[left]; + } else { + a1 = a[k]; a2 = a[left]; + } + while (a1 < a[--k]) { + a[k + 2] = a[k]; + } + a[++k + 1] = a1; + + while (a2 < a[--k]) { + a[k + 1] = a[k]; + } + a[k + 1] = a2; + } + char last = a[right]; + + while (last < a[--right]) { + a[right + 1] = a[right]; + } + a[right + 1] = last; } return; } // Inexpensive approximation of length / 7 - int seventh = (length >>> 3) + (length >>> 6) + 1; + int seventh = (length >> 3) + (length >> 6) + 1; /* * Sort five evenly spaced elements around (and including) the @@ -1301,10 +1351,14 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { char ak = a[k]; if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; + /* + * Here and below we use "a[i] = b; i++;" instead + * of "a[i++] = b;" due to performance issue. + */ a[less] = ak; less++; } else if (ak > pivot2) { // Move a[k] to right part @@ -1313,13 +1367,17 @@ final class DualPivotQuicksort { break outer; } } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot2 a[k] = a[less]; a[less] = a[great]; less++; } else { // pivot1 <= a[great] <= pivot2 a[k] = a[great]; } + /* + * Here and below we use "a[i] = b; i--;" instead + * of "a[i--] = b;" due to performance issue. + */ a[great] = ak; great--; } @@ -1334,7 +1392,7 @@ final class DualPivotQuicksort { sort(a, great + 2, right, false); /* - * If center part is too large (comprises > 5/7 of the array), + * If center part is too large (comprises > 4/7 of the array), * swap internal pivot values to ends. */ if (less < e1 && e5 < great) { @@ -1368,7 +1426,7 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { char ak = a[k]; if (ak == pivot1) { // Move a[k] to left part a[k] = a[less]; @@ -1380,7 +1438,7 @@ final class DualPivotQuicksort { break outer; } } - if (a[great] == pivot1) { + if (a[great] == pivot1) { // a[great] < pivot2 a[k] = a[less]; /* * Even though a[great] equals to pivot1, the @@ -1406,7 +1464,7 @@ final class DualPivotQuicksort { } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way + * Partitioning degenerates to the traditional 3-way * (or "Dutch National Flag") schema: * * left part center part right part @@ -1425,28 +1483,20 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part. */ - for (int k = left; k <= great; k++) { + for (int k = less; k <= great; ++k) { if (a[k] == pivot1) { continue; } char ak = a[k]; - if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; a[less] = ak; less++; } else { // a[k] > pivot1 - Move a[k] to right part - /* - * We know that pivot1 == a[e3] == pivot2. Thus, we know - * that great will still be >= k when the following loop - * terminates, even though we don't test for it explicitly. - * In other words, a[e3] acts as a sentinel for great. - */ while (a[great] > pivot1) { - // assert great > k; great--; } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot1 a[k] = a[less]; a[less] = a[great]; less++; @@ -1466,442 +1516,90 @@ final class DualPivotQuicksort { } } - // Sort left and right parts recursively + /* + * Sort left and right parts recursively. + * All elements from center part are equal + * and, therefore, already sorted. + */ sort(a, left, less - 1, leftmost); sort(a, great + 1, right, false); } } - /** - * Sorts the specified array into ascending numerical order. - * - * @param a the array to be sorted - */ - public static void sort(byte[] a) { - if (a.length > COUNTING_SORT_THRESHOLD_FOR_BYTE) { - countingSort(a, 0, a.length - 1); - } else { - sort(a, 0, a.length - 1, true); - } - } - - /** - * Sorts the specified range of the array into ascending order. The range - * to be sorted extends from the index {@code fromIndex}, inclusive, to - * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty (and the call is a no-op). - * - * @param a the array to be sorted - * @param fromIndex the index of the first element, inclusive, to be sorted - * @param toIndex the index of the last element, exclusive, to be sorted - * @throws IllegalArgumentException if {@code fromIndex > toIndex} - * @throws ArrayIndexOutOfBoundsException - * if {@code fromIndex < 0} or {@code toIndex > a.length} - */ - public static void sort(byte[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); - - if (toIndex - fromIndex > COUNTING_SORT_THRESHOLD_FOR_BYTE) { - countingSort(a, fromIndex, toIndex - 1); - } else { - sort(a, fromIndex, toIndex - 1, true); - } - } - /** The number of distinct byte values. */ private static final int NUM_BYTE_VALUES = 1 << 8; /** - * Sorts the specified range of the array by counting sort. + * Sorts the specified array. + * + * @param a the array to be sorted + */ + public static void sort(byte[] a) { + sort(a, 0, a.length - 1); + } + + /** + * Sorts the specified range of the array. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted */ - private static void countingSort(byte[] a, int left, int right) { - int[] count = new int[NUM_BYTE_VALUES]; + public static void sort(byte[] a, int left, int right) { + // Use counting sort on large arrays + if (right - left > COUNTING_SORT_THRESHOLD_FOR_BYTE) { + int[] count = new int[NUM_BYTE_VALUES]; - for (int i = left; i <= right; i++) { - count[a[i] - Byte.MIN_VALUE]++; - } - for (int i = NUM_BYTE_VALUES - 1, k = right; k >= left; i--) { - while (count[i] == 0) { - i--; + for (int i = left - 1; ++i <= right; ) { + count[a[i] - Byte.MIN_VALUE]++; } - byte value = (byte) (i + Byte.MIN_VALUE); - int s = count[i]; + for (int i = NUM_BYTE_VALUES, k = right + 1; k > left; ) { + while (count[--i] == 0); + byte value = (byte) (i + Byte.MIN_VALUE); + int s = count[i]; - do { - a[k--] = value; - } while (--s > 0); + do { + a[--k] = value; + } while (--s > 0); + } + } else { // Use insertion sort on small arrays + for (int i = left, j = i; i < right; j = ++i) { + byte ai = a[i + 1]; + while (ai < a[j]) { + a[j + 1] = a[j]; + if (j-- == left) { + break; + } + } + a[j + 1] = ai; + } } } /** - * Sorts the specified range of the array into ascending order by the - * Dual-Pivot Quicksort algorithm. This method differs from the public - * {@code sort} method in that the {@code right} index is inclusive, - * it does no range checking on {@code left} or {@code right}, and has - * boolean flag whether insertion sort with sentinel is used or not. - * - * @param a the array to be sorted - * @param left the index of the first element, inclusive, to be sorted - * @param right the index of the last element, inclusive, to be sorted - * @param leftmost indicates if the part is the most left in the range - */ - private static void sort(byte[] a, int left, int right, boolean leftmost) { - int length = right - left + 1; - - // Use insertion sort on tiny arrays - if (length < INSERTION_SORT_THRESHOLD) { - if (!leftmost) { - /* - * Every element in adjoining part plays the role - * of sentinel, therefore this allows us to avoid - * the j >= left check on each iteration. - */ - for (int j, i = left + 1; i <= right; i++) { - byte ai = a[i]; - for (j = i - 1; ai < a[j]; j--) { - // assert j >= left; - a[j + 1] = a[j]; - } - a[j + 1] = ai; - } - } else { - /* - * For case of leftmost part traditional (without a sentinel) - * insertion sort, optimized for server JVM, is used. - */ - for (int i = left, j = i; i < right; j = ++i) { - byte ai = a[i + 1]; - while (ai < a[j]) { - a[j + 1] = a[j]; - if (j-- == left) { - break; - } - } - a[j + 1] = ai; - } - } - return; - } - - // Inexpensive approximation of length / 7 - int seventh = (length >>> 3) + (length >>> 6) + 1; - - /* - * Sort five evenly spaced elements around (and including) the - * center element in the range. These elements will be used for - * pivot selection as described below. The choice for spacing - * these elements was empirically determined to work well on - * a wide variety of inputs. - */ - int e3 = (left + right) >>> 1; // The midpoint - int e2 = e3 - seventh; - int e1 = e2 - seventh; - int e4 = e3 + seventh; - int e5 = e4 + seventh; - - // Sort these elements using insertion sort - if (a[e2] < a[e1]) { byte t = a[e2]; a[e2] = a[e1]; a[e1] = t; } - - if (a[e3] < a[e2]) { byte t = a[e3]; a[e3] = a[e2]; a[e2] = t; - if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } - } - if (a[e4] < a[e3]) { byte t = a[e4]; a[e4] = a[e3]; a[e3] = t; - if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; - if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } - } - } - if (a[e5] < a[e4]) { byte t = a[e5]; a[e5] = a[e4]; a[e4] = t; - if (t < a[e3]) { a[e4] = a[e3]; a[e3] = t; - if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; - if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } - } - } - } - - /* - * Use the second and fourth of the five sorted elements as pivots. - * These values are inexpensive approximations of the first and - * second terciles of the array. Note that pivot1 <= pivot2. - */ - byte pivot1 = a[e2]; - byte pivot2 = a[e4]; - - // Pointers - int less = left; // The index of the first element of center part - int great = right; // The index before the first element of right part - - if (pivot1 != pivot2) { - /* - * The first and the last elements to be sorted are moved to the - * locations formerly occupied by the pivots. When partitioning - * is complete, the pivots are swapped back into their final - * positions, and excluded from subsequent sorting. - */ - a[e2] = a[left]; - a[e4] = a[right]; - - /* - * Skip elements, which are less or greater than pivot values. - */ - while (a[++less] < pivot1); - while (a[--great] > pivot2); - - /* - * Partitioning: - * - * left part center part right part - * +--------------------------------------------------------------+ - * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | - * +--------------------------------------------------------------+ - * ^ ^ ^ - * | | | - * less k great - * - * Invariants: - * - * all in (left, less) < pivot1 - * pivot1 <= all in [less, k) <= pivot2 - * all in (great, right) > pivot2 - * - * Pointer k is the first index of ?-part. - */ - outer: - for (int k = less; k <= great; k++) { - byte ak = a[k]; - if (ak < pivot1) { // Move a[k] to left part - a[k] = a[less]; - a[less] = ak; - less++; - } else if (ak > pivot2) { // Move a[k] to right part - while (a[great] > pivot2) { - if (great-- == k) { - break outer; - } - } - if (a[great] < pivot1) { - a[k] = a[less]; - a[less] = a[great]; - less++; - } else { // pivot1 <= a[great] <= pivot2 - a[k] = a[great]; - } - a[great] = ak; - great--; - } - } - - // Swap pivots into their final positions - a[left] = a[less - 1]; a[less - 1] = pivot1; - a[right] = a[great + 1]; a[great + 1] = pivot2; - - // Sort left and right parts recursively, excluding known pivots - sort(a, left, less - 2, leftmost); - sort(a, great + 2, right, false); - - /* - * If center part is too large (comprises > 5/7 of the array), - * swap internal pivot values to ends. - */ - if (less < e1 && e5 < great) { - /* - * Skip elements, which are equal to pivot values. - */ - while (a[less] == pivot1) { - less++; - } - while (a[great] == pivot2) { - great--; - } - - /* - * Partitioning: - * - * left part center part right part - * +----------------------------------------------------------+ - * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | - * +----------------------------------------------------------+ - * ^ ^ ^ - * | | | - * less k great - * - * Invariants: - * - * all in (*, less) == pivot1 - * pivot1 < all in [less, k) < pivot2 - * all in (great, *) == pivot2 - * - * Pointer k is the first index of ?-part. - */ - outer: - for (int k = less; k <= great; k++) { - byte ak = a[k]; - if (ak == pivot1) { // Move a[k] to left part - a[k] = a[less]; - a[less] = ak; - less++; - } else if (ak == pivot2) { // Move a[k] to right part - while (a[great] == pivot2) { - if (great-- == k) { - break outer; - } - } - if (a[great] == pivot1) { - a[k] = a[less]; - /* - * Even though a[great] equals to pivot1, the - * assignment a[less] = pivot1 may be incorrect, - * if a[great] and pivot1 are floating-point zeros - * of different signs. Therefore in float and - * double sorting methods we have to use more - * accurate assignment a[less] = a[great]. - */ - a[less] = pivot1; - less++; - } else { // pivot1 < a[great] < pivot2 - a[k] = a[great]; - } - a[great] = ak; - great--; - } - } - } - - // Sort center part recursively - sort(a, less, great, false); - - } else { // Pivots are equal - /* - * Partition degenerates to the traditional 3-way - * (or "Dutch National Flag") schema: - * - * left part center part right part - * +-------------------------------------------------+ - * | < pivot | == pivot | ? | > pivot | - * +-------------------------------------------------+ - * ^ ^ ^ - * | | | - * less k great - * - * Invariants: - * - * all in (left, less) < pivot - * all in [less, k) == pivot - * all in (great, right) > pivot - * - * Pointer k is the first index of ?-part. - */ - for (int k = left; k <= great; k++) { - if (a[k] == pivot1) { - continue; - } - byte ak = a[k]; - - if (ak < pivot1) { // Move a[k] to left part - a[k] = a[less]; - a[less] = ak; - less++; - } else { // a[k] > pivot1 - Move a[k] to right part - /* - * We know that pivot1 == a[e3] == pivot2. Thus, we know - * that great will still be >= k when the following loop - * terminates, even though we don't test for it explicitly. - * In other words, a[e3] acts as a sentinel for great. - */ - while (a[great] > pivot1) { - // assert great > k; - great--; - } - if (a[great] < pivot1) { - a[k] = a[less]; - a[less] = a[great]; - less++; - } else { // a[great] == pivot1 - /* - * Even though a[great] equals to pivot1, the - * assignment a[k] = pivot1 may be incorrect, - * if a[great] and pivot1 are floating-point - * zeros of different signs. Therefore in float - * and double sorting methods we have to use - * more accurate assignment a[k] = a[great]. - */ - a[k] = pivot1; - } - a[great] = ak; - great--; - } - } - - // Sort left and right parts recursively - sort(a, left, less - 1, leftmost); - sort(a, great + 1, right, false); - } - } - - /** - * Sorts the specified array into ascending numerical order. - * - *

The {@code <} relation does not provide a total order on all float - * values: {@code -0.0f == 0.0f} is {@code true} and a {@code Float.NaN} - * value compares neither less than, greater than, nor equal to any value, - * even itself. This method uses the total order imposed by the method - * {@link Float#compareTo}: {@code -0.0f} is treated as less than value - * {@code 0.0f} and {@code Float.NaN} is considered greater than any - * other value and all {@code Float.NaN} values are considered equal. + * Sorts the specified array. * * @param a the array to be sorted */ public static void sort(float[] a) { - sortNegZeroAndNaN(a, 0, a.length - 1); + sort(a, 0, a.length - 1); } /** - * Sorts the specified range of the array into ascending order. The range - * to be sorted extends from the index {@code fromIndex}, inclusive, to - * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty (and the call is a no-op). - * - *

The {@code <} relation does not provide a total order on all float - * values: {@code -0.0f == 0.0f} is {@code true} and a {@code Float.NaN} - * value compares neither less than, greater than, nor equal to any value, - * even itself. This method uses the total order imposed by the method - * {@link Float#compareTo}: {@code -0.0f} is treated as less than value - * {@code 0.0f} and {@code Float.NaN} is considered greater than any - * other value and all {@code Float.NaN} values are considered equal. - * - * @param a the array to be sorted - * @param fromIndex the index of the first element, inclusive, to be sorted - * @param toIndex the index of the last element, exclusive, to be sorted - * @throws IllegalArgumentException if {@code fromIndex > toIndex} - * @throws ArrayIndexOutOfBoundsException - * if {@code fromIndex < 0} or {@code toIndex > a.length} - */ - public static void sort(float[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); - sortNegZeroAndNaN(a, fromIndex, toIndex - 1); - } - - /** - * Sorts the specified range of the array into ascending order. The - * sort is done in three phases to avoid expensive comparisons in the - * inner loop. The comparisons would be expensive due to anomalies - * associated with negative zero {@code -0.0f} and {@code Float.NaN}. + * Sorts the specified range of the array. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted */ - private static void sortNegZeroAndNaN(float[] a, int left, int right) { + public static void sort(float[] a, int left, int right) { /* * Phase 1: Move NaNs to the end of the array. */ while (left <= right && Float.isNaN(a[right])) { right--; } - for (int k = right - 1; k >= left; k--) { + for (int k = right; --k >= left; ) { float ak = a[k]; if (ak != ak) { // a[k] is NaN a[k] = a[right]; @@ -1921,7 +1619,7 @@ final class DualPivotQuicksort { int hi = right; /* - * Search first zero, or first positive, or last negative element. + * Find the first zero, or first positive, or last negative element. */ while (left < hi) { int middle = (left + hi) >>> 1; @@ -1946,12 +1644,12 @@ final class DualPivotQuicksort { * * Partitioning: * - * +---------------------------------------------------+ - * | < 0.0 | -0.0 | 0.0 | ? ( >= 0.0 ) | - * +---------------------------------------------------+ - * ^ ^ ^ - * | | | - * left p k + * +----------------------------------------------------+ + * | < 0.0 | -0.0 | 0.0 | ? ( >= 0.0 ) | + * +----------------------------------------------------+ + * ^ ^ ^ + * | | | + * left p k * * Invariants: * @@ -1962,53 +1660,36 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part. */ - for (int k = left + 1, p = left; k <= right; k++) { + for (int k = left, p = left - 1; ++k <= right; ) { float ak = a[k]; if (ak != 0.0f) { break; } if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f a[k] = 0.0f; - a[p++] = -0.0f; + a[++p] = -0.0f; } } } /** - * Sorts the specified range of the array into ascending order by the - * Dual-Pivot Quicksort algorithm. This method differs from the public - * {@code sort} method in that the {@code right} index is inclusive, - * it does no range checking on {@code left} or {@code right}, and has - * boolean flag whether insertion sort with sentinel is used or not. + * Sorts the specified range of the array by Dual-Pivot Quicksort. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted - * @param leftmost indicates if the part is the most left in the range + * @param leftmost indicates if this part is the leftmost in the range */ private static void sort(float[] a, int left, int right,boolean leftmost) { int length = right - left + 1; - // Use insertion sort on tiny arrays + // Use insertion sort on small arrays if (length < INSERTION_SORT_THRESHOLD) { - if (!leftmost) { + if (leftmost) { /* - * Every element in adjoining part plays the role - * of sentinel, therefore this allows us to avoid - * the j >= left check on each iteration. - */ - for (int j, i = left + 1; i <= right; i++) { - float ai = a[i]; - for (j = i - 1; ai < a[j]; j--) { - // assert j >= left; - a[j + 1] = a[j]; - } - a[j + 1] = ai; - } - } else { - /* - * For case of leftmost part traditional (without a sentinel) - * insertion sort, optimized for server JVM, is used. + * Traditional (without sentinel) insertion sort, + * optimized for server VM, is used in case of + * the leftmost part. */ for (int i = left, j = i; i < right; j = ++i) { float ai = a[i + 1]; @@ -2020,12 +1701,54 @@ final class DualPivotQuicksort { } a[j + 1] = ai; } + } else { + /* + * Skip the longest ascending sequence. + */ + do { + if (left++ >= right) { + return; + } + } while (a[left - 1] <= a[left]); + + /* + * Every element from adjoining part plays the role + * of sentinel, therefore this allows us to avoid the + * left range check on each iteration. Moreover, we use + * the best improved algorithm, so called pair insertion + * sort, which is faster than traditional implementation + * in the context of Dual-Pivot Quicksort. + */ + for (int k = left--; (left += 2) <= right; ) { + float a1, a2; k = left - 1; + + if (a[k] < a[left]) { + a2 = a[k]; a1 = a[left]; + } else { + a1 = a[k]; a2 = a[left]; + } + while (a1 < a[--k]) { + a[k + 2] = a[k]; + } + a[++k + 1] = a1; + + while (a2 < a[--k]) { + a[k + 1] = a[k]; + } + a[k + 1] = a2; + } + float last = a[right]; + + while (last < a[--right]) { + a[right + 1] = a[right]; + } + a[right + 1] = last; } return; } // Inexpensive approximation of length / 7 - int seventh = (length >>> 3) + (length >>> 6) + 1; + int seventh = (length >> 3) + (length >> 6) + 1; /* * Sort five evenly spaced elements around (and including) the @@ -2107,10 +1830,14 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { float ak = a[k]; if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; + /* + * Here and below we use "a[i] = b; i++;" instead + * of "a[i++] = b;" due to performance issue. + */ a[less] = ak; less++; } else if (ak > pivot2) { // Move a[k] to right part @@ -2119,13 +1846,17 @@ final class DualPivotQuicksort { break outer; } } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot2 a[k] = a[less]; a[less] = a[great]; less++; } else { // pivot1 <= a[great] <= pivot2 a[k] = a[great]; } + /* + * Here and below we use "a[i] = b; i--;" instead + * of "a[i--] = b;" due to performance issue. + */ a[great] = ak; great--; } @@ -2140,7 +1871,7 @@ final class DualPivotQuicksort { sort(a, great + 2, right, false); /* - * If center part is too large (comprises > 5/7 of the array), + * If center part is too large (comprises > 4/7 of the array), * swap internal pivot values to ends. */ if (less < e1 && e5 < great) { @@ -2174,7 +1905,7 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { float ak = a[k]; if (ak == pivot1) { // Move a[k] to left part a[k] = a[less]; @@ -2186,7 +1917,7 @@ final class DualPivotQuicksort { break outer; } } - if (a[great] == pivot1) { + if (a[great] == pivot1) { // a[great] < pivot2 a[k] = a[less]; /* * Even though a[great] equals to pivot1, the @@ -2212,7 +1943,7 @@ final class DualPivotQuicksort { } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way + * Partitioning degenerates to the traditional 3-way * (or "Dutch National Flag") schema: * * left part center part right part @@ -2231,28 +1962,20 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part. */ - for (int k = left; k <= great; k++) { + for (int k = less; k <= great; ++k) { if (a[k] == pivot1) { continue; } float ak = a[k]; - if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; a[less] = ak; less++; } else { // a[k] > pivot1 - Move a[k] to right part - /* - * We know that pivot1 == a[e3] == pivot2. Thus, we know - * that great will still be >= k when the following loop - * terminates, even though we don't test for it explicitly. - * In other words, a[e3] acts as a sentinel for great. - */ while (a[great] > pivot1) { - // assert great > k; great--; } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot1 a[k] = a[less]; a[less] = a[great]; less++; @@ -2272,73 +1995,40 @@ final class DualPivotQuicksort { } } - // Sort left and right parts recursively + /* + * Sort left and right parts recursively. + * All elements from center part are equal + * and, therefore, already sorted. + */ sort(a, left, less - 1, leftmost); sort(a, great + 1, right, false); } } /** - * Sorts the specified array into ascending numerical order. - * - *

The {@code <} relation does not provide a total order on all double - * values: {@code -0.0d == 0.0d} is {@code true} and a {@code Double.NaN} - * value compares neither less than, greater than, nor equal to any value, - * even itself. This method uses the total order imposed by the method - * {@link Double#compareTo}: {@code -0.0d} is treated as less than value - * {@code 0.0d} and {@code Double.NaN} is considered greater than any - * other value and all {@code Double.NaN} values are considered equal. + * Sorts the specified array. * * @param a the array to be sorted */ public static void sort(double[] a) { - sortNegZeroAndNaN(a, 0, a.length - 1); + sort(a, 0, a.length - 1); } /** - * Sorts the specified range of the array into ascending order. The range - * to be sorted extends from the index {@code fromIndex}, inclusive, to - * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty (and the call is a no-op). - * - *

The {@code <} relation does not provide a total order on all double - * values: {@code -0.0d == 0.0d} is {@code true} and a {@code Double.NaN} - * value compares neither less than, greater than, nor equal to any value, - * even itself. This method uses the total order imposed by the method - * {@link Double#compareTo}: {@code -0.0d} is treated as less than value - * {@code 0.0d} and {@code Double.NaN} is considered greater than any - * other value and all {@code Double.NaN} values are considered equal. - * - * @param a the array to be sorted - * @param fromIndex the index of the first element, inclusive, to be sorted - * @param toIndex the index of the last element, exclusive, to be sorted - * @throws IllegalArgumentException if {@code fromIndex > toIndex} - * @throws ArrayIndexOutOfBoundsException - * if {@code fromIndex < 0} or {@code toIndex > a.length} - */ - public static void sort(double[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); - sortNegZeroAndNaN(a, fromIndex, toIndex - 1); - } - - /** - * Sorts the specified range of the array into ascending order. The - * sort is done in three phases to avoid expensive comparisons in the - * inner loop. The comparisons would be expensive due to anomalies - * associated with negative zero {@code -0.0d} and {@code Double.NaN}. + * Sorts the specified range of the array. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted */ - private static void sortNegZeroAndNaN(double[] a, int left, int right) { + public static void sort(double[] a, int left, int right) { /* * Phase 1: Move NaNs to the end of the array. */ while (left <= right && Double.isNaN(a[right])) { right--; } - for (int k = right - 1; k >= left; k--) { + for (int k = right; --k >= left; ) { double ak = a[k]; if (ak != ak) { // a[k] is NaN a[k] = a[right]; @@ -2358,7 +2048,7 @@ final class DualPivotQuicksort { int hi = right; /* - * Search first zero, or first positive, or last negative element. + * Find the first zero, or first positive, or last negative element. */ while (left < hi) { int middle = (left + hi) >>> 1; @@ -2383,12 +2073,12 @@ final class DualPivotQuicksort { * * Partitioning: * - * +---------------------------------------------------+ - * | < 0.0 | -0.0 | 0.0 | ? ( >= 0.0 ) | - * +---------------------------------------------------+ - * ^ ^ ^ - * | | | - * left p k + * +----------------------------------------------------+ + * | < 0.0 | -0.0 | 0.0 | ? ( >= 0.0 ) | + * +----------------------------------------------------+ + * ^ ^ ^ + * | | | + * left p k * * Invariants: * @@ -2399,53 +2089,36 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part. */ - for (int k = left + 1, p = left; k <= right; k++) { + for (int k = left, p = left - 1; ++k <= right; ) { double ak = a[k]; if (ak != 0.0d) { break; } if (Double.doubleToRawLongBits(ak) < 0) { // ak is -0.0d a[k] = 0.0d; - a[p++] = -0.0d; + a[++p] = -0.0d; } } } /** - * Sorts the specified range of the array into ascending order by the - * Dual-Pivot Quicksort algorithm. This method differs from the public - * {@code sort} method in that the {@code right} index is inclusive, - * it does no range checking on {@code left} or {@code right}, and has - * boolean flag whether insertion sort with sentinel is used or not. + * Sorts the specified range of the array by Dual-Pivot Quicksort. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted - * @param leftmost indicates if the part is the most left in the range + * @param leftmost indicates if this part is the leftmost in the range */ private static void sort(double[] a, int left,int right,boolean leftmost) { int length = right - left + 1; - // Use insertion sort on tiny arrays + // Use insertion sort on small arrays if (length < INSERTION_SORT_THRESHOLD) { - if (!leftmost) { + if (leftmost) { /* - * Every element in adjoining part plays the role - * of sentinel, therefore this allows us to avoid - * the j >= left check on each iteration. - */ - for (int j, i = left + 1; i <= right; i++) { - double ai = a[i]; - for (j = i - 1; ai < a[j]; j--) { - // assert j >= left; - a[j + 1] = a[j]; - } - a[j + 1] = ai; - } - } else { - /* - * For case of leftmost part traditional (without a sentinel) - * insertion sort, optimized for server JVM, is used. + * Traditional (without sentinel) insertion sort, + * optimized for server VM, is used in case of + * the leftmost part. */ for (int i = left, j = i; i < right; j = ++i) { double ai = a[i + 1]; @@ -2457,12 +2130,54 @@ final class DualPivotQuicksort { } a[j + 1] = ai; } + } else { + /* + * Skip the longest ascending sequence. + */ + do { + if (left++ >= right) { + return; + } + } while (a[left - 1] <= a[left]); + + /* + * Every element from adjoining part plays the role + * of sentinel, therefore this allows us to avoid the + * left range check on each iteration. Moreover, we use + * the best improved algorithm, so called pair insertion + * sort, which is faster than traditional implementation + * in the context of Dual-Pivot Quicksort. + */ + for (int k = left--; (left += 2) <= right; ) { + double a1, a2; k = left - 1; + + if (a[k] < a[left]) { + a2 = a[k]; a1 = a[left]; + } else { + a1 = a[k]; a2 = a[left]; + } + while (a1 < a[--k]) { + a[k + 2] = a[k]; + } + a[++k + 1] = a1; + + while (a2 < a[--k]) { + a[k + 1] = a[k]; + } + a[k + 1] = a2; + } + double last = a[right]; + + while (last < a[--right]) { + a[right + 1] = a[right]; + } + a[right + 1] = last; } return; } // Inexpensive approximation of length / 7 - int seventh = (length >>> 3) + (length >>> 6) + 1; + int seventh = (length >> 3) + (length >> 6) + 1; /* * Sort five evenly spaced elements around (and including) the @@ -2544,10 +2259,14 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { double ak = a[k]; if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; + /* + * Here and below we use "a[i] = b; i++;" instead + * of "a[i++] = b;" due to performance issue. + */ a[less] = ak; less++; } else if (ak > pivot2) { // Move a[k] to right part @@ -2556,13 +2275,17 @@ final class DualPivotQuicksort { break outer; } } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot2 a[k] = a[less]; a[less] = a[great]; less++; } else { // pivot1 <= a[great] <= pivot2 a[k] = a[great]; } + /* + * Here and below we use "a[i] = b; i--;" instead + * of "a[i--] = b;" due to performance issue. + */ a[great] = ak; great--; } @@ -2577,7 +2300,7 @@ final class DualPivotQuicksort { sort(a, great + 2, right, false); /* - * If center part is too large (comprises > 5/7 of the array), + * If center part is too large (comprises > 4/7 of the array), * swap internal pivot values to ends. */ if (less < e1 && e5 < great) { @@ -2611,7 +2334,7 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { double ak = a[k]; if (ak == pivot1) { // Move a[k] to left part a[k] = a[less]; @@ -2623,7 +2346,7 @@ final class DualPivotQuicksort { break outer; } } - if (a[great] == pivot1) { + if (a[great] == pivot1) { // a[great] < pivot2 a[k] = a[less]; /* * Even though a[great] equals to pivot1, the @@ -2649,7 +2372,7 @@ final class DualPivotQuicksort { } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way + * Partitioning degenerates to the traditional 3-way * (or "Dutch National Flag") schema: * * left part center part right part @@ -2668,28 +2391,20 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part. */ - for (int k = left; k <= great; k++) { + for (int k = less; k <= great; ++k) { if (a[k] == pivot1) { continue; } double ak = a[k]; - if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; a[less] = ak; less++; } else { // a[k] > pivot1 - Move a[k] to right part - /* - * We know that pivot1 == a[e3] == pivot2. Thus, we know - * that great will still be >= k when the following loop - * terminates, even though we don't test for it explicitly. - * In other words, a[e3] acts as a sentinel for great. - */ while (a[great] > pivot1) { - // assert great > k; great--; } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot1 a[k] = a[less]; a[less] = a[great]; less++; @@ -2709,26 +2424,13 @@ final class DualPivotQuicksort { } } - // Sort left and right parts recursively + /* + * Sort left and right parts recursively. + * All elements from center part are equal + * and, therefore, already sorted. + */ sort(a, left, less - 1, leftmost); sort(a, great + 1, right, false); } } - - /** - * Checks that {@code fromIndex} and {@code toIndex} are in the range, - * otherwise throws an appropriate exception. - */ - private static void rangeCheck(int length, int fromIndex, int toIndex) { - if (fromIndex > toIndex) { - throw new IllegalArgumentException( - "fromIndex: " + fromIndex + " > toIndex: " + toIndex); - } - if (fromIndex < 0) { - throw new ArrayIndexOutOfBoundsException(fromIndex); - } - if (toIndex > length) { - throw new ArrayIndexOutOfBoundsException(toIndex); - } - } } diff --git a/jdk/src/share/classes/java/util/Locale.java b/jdk/src/share/classes/java/util/Locale.java index 49b85866ed3..1043c8792c4 100644 --- a/jdk/src/share/classes/java/util/Locale.java +++ b/jdk/src/share/classes/java/util/Locale.java @@ -569,6 +569,9 @@ public final class Locale implements Cloneable, Serializable { * @exception NullPointerException thrown if any argument is null. */ public Locale(String language, String country, String variant) { + if (language== null || country == null || variant == null) { + throw new NullPointerException(); + } _baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant); _extensions = getCompatibilityExtensions(language, "", country, variant); } diff --git a/jdk/src/share/classes/java/util/Properties.java b/jdk/src/share/classes/java/util/Properties.java index 6f9c562e4f8..ee6d17c4e4d 100644 --- a/jdk/src/share/classes/java/util/Properties.java +++ b/jdk/src/share/classes/java/util/Properties.java @@ -705,7 +705,7 @@ class Properties extends Hashtable { * Strings. */ @Deprecated - public synchronized void save(OutputStream out, String comments) { + public void save(OutputStream out, String comments) { try { store(out, comments); } catch (IOException e) { @@ -890,7 +890,7 @@ class Properties extends Hashtable { * @see #loadFromXML(InputStream) * @since 1.5 */ - public synchronized void storeToXML(OutputStream os, String comment) + public void storeToXML(OutputStream os, String comment) throws IOException { if (os == null) @@ -929,8 +929,7 @@ class Properties extends Hashtable { * @see #loadFromXML(InputStream) * @since 1.5 */ - public synchronized void storeToXML(OutputStream os, String comment, - String encoding) + public void storeToXML(OutputStream os, String comment, String encoding) throws IOException { if (os == null) diff --git a/jdk/src/share/classes/java/util/ResourceBundle.java b/jdk/src/share/classes/java/util/ResourceBundle.java index e645fe91439..9fbdbe1626d 100644 --- a/jdk/src/share/classes/java/util/ResourceBundle.java +++ b/jdk/src/share/classes/java/util/ResourceBundle.java @@ -292,16 +292,6 @@ public abstract class ResourceBundle { private static final ConcurrentMap cacheList = new ConcurrentHashMap(INITIAL_CACHE_SIZE); - /** - * This ConcurrentMap is used to keep multiple threads from loading the - * same bundle concurrently. The table entries are - * where CacheKey is the key for the bundle that is under construction - * and Thread is the thread that is constructing the bundle. - * This list is manipulated in findBundleInCache and putBundleInCache. - */ - private static final ConcurrentMap underConstruction - = new ConcurrentHashMap(); - /** * Queue for reference objects referring to class loaders or bundles. */ @@ -1381,7 +1371,7 @@ public abstract class ResourceBundle { boolean expiredBundle = false; // First, look up the cache to see if it's in the cache, without - // declaring beginLoading. + // attempting to load bundle. cacheKey.setLocale(targetLocale); ResourceBundle bundle = findBundleInCache(cacheKey, control); if (isValidBundle(bundle)) { @@ -1408,56 +1398,25 @@ public abstract class ResourceBundle { CacheKey constKey = (CacheKey) cacheKey.clone(); try { - // Try declaring loading. If beginLoading() returns true, - // then we can proceed. Otherwise, we need to take a look - // at the cache again to see if someone else has loaded - // the bundle and put it in the cache while we've been - // waiting for other loading work to complete. - while (!beginLoading(constKey)) { - bundle = findBundleInCache(cacheKey, control); - if (bundle == null) { - continue; - } - if (bundle == NONEXISTENT_BUNDLE) { - // If the bundle is NONEXISTENT_BUNDLE, the bundle doesn't exist. - return parent; - } - expiredBundle = bundle.expired; - if (!expiredBundle) { - if (bundle.parent == parent) { - return bundle; - } - BundleReference bundleRef = cacheList.get(cacheKey); - if (bundleRef != null && bundleRef.get() == bundle) { - cacheList.remove(cacheKey, bundleRef); - } + bundle = loadBundle(cacheKey, formats, control, expiredBundle); + if (bundle != null) { + if (bundle.parent == null) { + bundle.setParent(parent); } + bundle.locale = targetLocale; + bundle = putBundleInCache(cacheKey, bundle, control); + return bundle; } - try { - bundle = loadBundle(cacheKey, formats, control, expiredBundle); - if (bundle != null) { - if (bundle.parent == null) { - bundle.setParent(parent); - } - bundle.locale = targetLocale; - bundle = putBundleInCache(cacheKey, bundle, control); - return bundle; - } - - // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle - // instance for the locale. - putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control); - } finally { - endLoading(constKey); - } + // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle + // instance for the locale. + putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control); } finally { if (constKey.getCause() instanceof InterruptedException) { Thread.currentThread().interrupt(); } } } - assert underConstruction.get(cacheKey) != Thread.currentThread(); return parent; } @@ -1465,7 +1424,6 @@ public abstract class ResourceBundle { List formats, Control control, boolean reload) { - assert underConstruction.get(cacheKey) == Thread.currentThread(); // Here we actually load the bundle in the order of formats // specified by the getFormats() value. @@ -1498,7 +1456,6 @@ public abstract class ResourceBundle { break; } } - assert underConstruction.get(cacheKey) == Thread.currentThread(); return bundle; } @@ -1529,57 +1486,6 @@ public abstract class ResourceBundle { return true; } - /** - * Declares the beginning of actual resource bundle loading. This method - * returns true if the declaration is successful and the current thread has - * been put in underConstruction. If someone else has already begun - * loading, this method waits until that loading work is complete and - * returns false. - */ - private static final boolean beginLoading(CacheKey constKey) { - Thread me = Thread.currentThread(); - Thread worker; - // We need to declare by putting the current Thread (me) to - // underConstruction that we are working on loading the specified - // resource bundle. If we are already working the loading, it means - // that the resource loading requires a recursive call. In that case, - // we have to proceed. (4300693) - if (((worker = underConstruction.putIfAbsent(constKey, me)) == null) - || worker == me) { - return true; - } - - // If someone else is working on the loading, wait until - // the Thread finishes the bundle loading. - synchronized (worker) { - while (underConstruction.get(constKey) == worker) { - try { - worker.wait(); - } catch (InterruptedException e) { - // record the interruption - constKey.setCause(e); - } - } - } - return false; - } - - /** - * Declares the end of the bundle loading. This method calls notifyAll - * for those who are waiting for this completion. - */ - private static final void endLoading(CacheKey constKey) { - // Remove this Thread from the underConstruction map and wake up - // those who have been waiting for me to complete this bundle - // loading. - Thread me = Thread.currentThread(); - assert (underConstruction.get(constKey) == me); - underConstruction.remove(constKey); - synchronized (me) { - me.notifyAll(); - } - } - /** * Throw a MissingResourceException with proper message */ diff --git a/jdk/src/share/classes/java/util/Vector.java b/jdk/src/share/classes/java/util/Vector.java index 8517b887746..e508aa5b5c0 100644 --- a/jdk/src/share/classes/java/util/Vector.java +++ b/jdk/src/share/classes/java/util/Vector.java @@ -222,8 +222,10 @@ public class Vector * @param minCapacity the desired minimum capacity */ public synchronized void ensureCapacity(int minCapacity) { - modCount++; - ensureCapacityHelper(minCapacity); + if (minCapacity > 0) { + modCount++; + ensureCapacityHelper(minCapacity); + } } /** diff --git a/jdk/src/share/classes/java/util/XMLUtils.java b/jdk/src/share/classes/java/util/XMLUtils.java index a742675eaa2..8a3ac86ba32 100644 --- a/jdk/src/share/classes/java/util/XMLUtils.java +++ b/jdk/src/share/classes/java/util/XMLUtils.java @@ -141,14 +141,13 @@ class XMLUtils { comments.appendChild(doc.createTextNode(comment)); } - Set keys = props.keySet(); - Iterator i = keys.iterator(); - while(i.hasNext()) { - String key = (String)i.next(); - Element entry = (Element)properties.appendChild( - doc.createElement("entry")); - entry.setAttribute("key", key); - entry.appendChild(doc.createTextNode(props.getProperty(key))); + synchronized (props) { + for (String key : props.stringPropertyNames()) { + Element entry = (Element)properties.appendChild( + doc.createElement("entry")); + entry.setAttribute("key", key); + entry.appendChild(doc.createTextNode(props.getProperty(key))); + } } emitDocument(doc, os, encoding); } diff --git a/jdk/src/share/classes/java/util/logging/LogRecord.java b/jdk/src/share/classes/java/util/logging/LogRecord.java index 57da7634a09..84ccb89aed8 100644 --- a/jdk/src/share/classes/java/util/logging/LogRecord.java +++ b/jdk/src/share/classes/java/util/logging/LogRecord.java @@ -529,8 +529,6 @@ public class LogRecord implements java.io.Serializable { Throwable throwable = new Throwable(); int depth = access.getStackTraceDepth(throwable); - String logClassName = "java.util.logging.Logger"; - String plogClassName = "sun.util.logging.PlatformLogger"; boolean lookingForLogger = true; for (int ix = 0; ix < depth; ix++) { // Calling getStackTraceElement directly prevents the VM @@ -538,13 +536,14 @@ public class LogRecord implements java.io.Serializable { StackTraceElement frame = access.getStackTraceElement(throwable, ix); String cname = frame.getClassName(); + boolean isLoggerImpl = isLoggerImplFrame(cname); if (lookingForLogger) { // Skip all frames until we have found the first logger frame. - if (cname.equals(logClassName) || cname.startsWith(plogClassName)) { + if (isLoggerImpl) { lookingForLogger = false; } } else { - if (!cname.equals(logClassName) && !cname.startsWith(plogClassName)) { + if (!isLoggerImpl) { // skip reflection call if (!cname.startsWith("java.lang.reflect.") && !cname.startsWith("sun.reflect.")) { // We've found the relevant frame. @@ -558,4 +557,11 @@ public class LogRecord implements java.io.Serializable { // We haven't found a suitable frame, so just punt. This is // OK as we are only committed to making a "best effort" here. } + + private boolean isLoggerImplFrame(String cname) { + // the log record could be created for a platform logger + return (cname.equals("java.util.logging.Logger") || + cname.startsWith("java.util.logging.LoggingProxyImpl") || + cname.startsWith("sun.util.logging.")); + } } diff --git a/jdk/src/share/classes/java/util/zip/ZipFile.java b/jdk/src/share/classes/java/util/zip/ZipFile.java index 79de443b1b0..e995c4e89ee 100644 --- a/jdk/src/share/classes/java/util/zip/ZipFile.java +++ b/jdk/src/share/classes/java/util/zip/ZipFile.java @@ -85,8 +85,7 @@ class ZipFile implements ZipConstants, Closeable { static { // A system prpperty to disable mmap use to avoid vm crash when // in-use zip file is accidently overwritten by others. - String prop = AccessController.doPrivileged( - new GetPropertyAction("sun.zip.disableMemoryMapping")); + String prop = sun.misc.VM.getSavedProperty("sun.zip.disableMemoryMapping"); usemmap = (prop == null || !(prop.length() == 0 || prop.equalsIgnoreCase("true"))); } diff --git a/jdk/src/share/classes/javax/swing/GroupLayout.java b/jdk/src/share/classes/javax/swing/GroupLayout.java index a343b7bc8a1..7628076a994 100644 --- a/jdk/src/share/classes/javax/swing/GroupLayout.java +++ b/jdk/src/share/classes/javax/swing/GroupLayout.java @@ -1464,8 +1464,8 @@ public class GroupLayout implements LayoutManager2 { * <= {@code pref} <= {@code max}. *

* Similarly any methods that take a {@code Component} throw a - * {@code NullPointerException} if passed {@code null} and any methods - * that take a {@code Group} throw an {@code IllegalArgumentException} if + * {@code IllegalArgumentException} if passed {@code null} and any methods + * that take a {@code Group} throw an {@code NullPointerException} if * passed {@code null}. * * @see #createSequentialGroup diff --git a/jdk/src/share/classes/javax/swing/JComponent.java b/jdk/src/share/classes/javax/swing/JComponent.java index ae3bddf1182..f94a797ae6c 100644 --- a/jdk/src/share/classes/javax/swing/JComponent.java +++ b/jdk/src/share/classes/javax/swing/JComponent.java @@ -4787,6 +4787,17 @@ public abstract class JComponent extends Container implements Serializable, * @see RepaintManager#addDirtyRegion */ public void repaint(long tm, int x, int y, int width, int height) { + Container p = this; + while ((p = p.getParent()) instanceof JComponent) { + JComponent jp = (JComponent) p; + if (jp.isPaintingOrigin()) { + Rectangle rectangle = SwingUtilities.convertRectangle( + this, new Rectangle(x, y, width, height), jp); + jp.repaint(tm, + rectangle.x, rectangle.y, rectangle.width, rectangle.height); + return; + } + } RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height); } diff --git a/jdk/src/share/classes/javax/swing/JDesktopPane.java b/jdk/src/share/classes/javax/swing/JDesktopPane.java index 1193cc574fe..7ad6753d5e0 100644 --- a/jdk/src/share/classes/javax/swing/JDesktopPane.java +++ b/jdk/src/share/classes/javax/swing/JDesktopPane.java @@ -215,7 +215,8 @@ public class JDesktopPane extends JLayeredPane implements Accessible /** * Sets the DesktopManger that will handle - * desktop-specific UI actions. + * desktop-specific UI actions. This may be overridden by + * {@code LookAndFeel}. * * @param d the DesktopManager to use * diff --git a/jdk/src/share/classes/javax/swing/JLayer.java b/jdk/src/share/classes/javax/swing/JLayer.java index dd7874c3e70..eab0bf4ab2f 100644 --- a/jdk/src/share/classes/javax/swing/JLayer.java +++ b/jdk/src/share/classes/javax/swing/JLayer.java @@ -25,17 +25,17 @@ package javax.swing; +import sun.awt.AWTAccessor; + import javax.swing.plaf.LayerUI; +import javax.swing.border.Border; import java.awt.*; import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import java.io.ObjectInputStream; -import java.io.Serializable; -import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Iterator; import java.security.AccessController; import java.security.PrivilegedAction; @@ -156,8 +156,6 @@ public final class JLayer private LayerUI layerUI; private JPanel glassPane; private boolean isPainting; - private static final DefaultLayerLayout sharedLayoutInstance = - new DefaultLayerLayout(); private long eventMask; private static final LayerEventController eventController = @@ -165,7 +163,7 @@ public final class JLayer /** * Creates a new {@code JLayer} object with a {@code null} view component - * and {@code null} {@link javax.swing.plaf.LayerUI}. + * and default {@link javax.swing.plaf.LayerUI}. * * @see #setView * @see #setUI @@ -176,14 +174,14 @@ public final class JLayer /** * Creates a new {@code JLayer} object - * with {@code null} {@link javax.swing.plaf.LayerUI}. + * with default {@link javax.swing.plaf.LayerUI}. * * @param view the component to be decorated by this {@code JLayer} * * @see #setUI */ public JLayer(V view) { - this(view, null); + this(view, new LayerUI()); } /** @@ -195,7 +193,6 @@ public final class JLayer * to be used by this {@code JLayer} */ public JLayer(V view, LayerUI ui) { - setLayout(sharedLayoutInstance); setGlassPane(createGlassPane()); setView(view); setUI(ui); @@ -279,10 +276,15 @@ public final class JLayer */ public void setGlassPane(JPanel glassPane) { Component oldGlassPane = getGlassPane(); + boolean isGlassPaneVisible = false; if (oldGlassPane != null) { + isGlassPaneVisible = oldGlassPane.isVisible(); super.remove(oldGlassPane); } if (glassPane != null) { + AWTAccessor.getComponentAccessor().setMixingCutoutShape(glassPane, + new Rectangle()); + glassPane.setVisible(isGlassPaneVisible); super.addImpl(glassPane, null, 0); } this.glassPane = glassPane; @@ -302,6 +304,40 @@ public final class JLayer return new DefaultLayerGlassPane(); } + /** + * Sets the layout manager for this container. This method is + * overridden to prevent the layout manager from being set. + *

Note: If {@code mgr} is non-{@code null}, this + * method will throw an exception as layout managers are not supported on + * a {@code JLayer}. + * + * @param mgr the specified layout manager + * @exception IllegalArgumentException this method is not supported + */ + public void setLayout(LayoutManager mgr) { + if (mgr != null) { + throw new IllegalArgumentException("JLayer.setLayout() not supported"); + } + } + + /** + * A non-{@code null] border, or non-zero insets, isn't supported, to prevent the geometry + * of this component from becoming complex enough to inhibit + * subclassing of {@code LayerUI} class. To create a {@code JLayer} with a border, + * add it to a {@code JPanel} that has a border. + *

Note: If {@code border} is non-{@code null}, this + * method will throw an exception as borders are not supported on + * a {@code JLayer}. + * + * @param border the {@code Border} to set + * @exception IllegalArgumentException this method is not supported + */ + public void setBorder(Border border) { + if (border != null) { + throw new IllegalArgumentException("JLayer.setBorder() not supported"); + } + } + /** * This method is not supported by {@code JLayer} * and always throws {@code UnsupportedOperationException} @@ -340,6 +376,32 @@ public final class JLayer setGlassPane(null); } + /** + * Always returns {@code true} to cause painting to originate from {@code JLayer}, + * or one of its ancestors. + * + * @return true + * @see JComponent#isPaintingOrigin() + */ + boolean isPaintingOrigin() { + return true; + } + + /** + * Delegates repainting to {@link javax.swing.plaf.LayerUI#repaint} method. + * + * @param tm this parameter is not used + * @param x the x value of the dirty region + * @param y the y value of the dirty region + * @param width the width of the dirty region + * @param height the height of the dirty region + */ + public void repaint(long tm, int x, int y, int width, int height) { + if (getUI() != null) { + getUI().repaint(tm, x, y, width, height, this); + } + } + /** * Delegates all painting to the {@link javax.swing.plaf.LayerUI} object. * @@ -364,14 +426,18 @@ public final class JLayer } /** - * To enable the correct painting of the {@code glassPane} and view component, - * the {@code JLayer} overrides the default implementation of - * this method to return {@code false} when the {@code glassPane} is visible. + * The {@code JLayer} overrides the default implementation of + * this method (in {@code JComponent}) to return {@code false}. + * This ensures + * that the drawing machinery will call the {@code JLayer}'s + * {@code paint} + * implementation rather than messaging the {@code JLayer}'s + * children directly. * - * @return false if {@code JLayer}'s {@code glassPane} is visible + * @return false */ public boolean isOptimizedDrawingEnabled() { - return glassPane == null || !glassPane.isVisible(); + return false; } /** @@ -461,17 +527,16 @@ public final class JLayer /** * Returns the preferred size of the viewport for a view component. *

- * If the ui delegate of this layer is not {@code null}, this method delegates its - * implementation to the {@code LayerUI.getPreferredScrollableViewportSize(JLayer)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return the preferred size of the viewport for a view component * * @see Scrollable - * @see LayerUI#getPreferredScrollableViewportSize(JLayer) */ public Dimension getPreferredScrollableViewportSize() { - if (getUI() != null) { - return getUI().getPreferredScrollableViewportSize(this); + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getPreferredScrollableViewportSize(); } return getPreferredSize(); } @@ -481,18 +546,17 @@ public final class JLayer * that display logical rows or columns in order to completely expose * one block of rows or columns, depending on the value of orientation. *

- * If the ui delegate of this layer is not {@code null}, this method delegates its - * implementation to the {@code LayerUI.getScrollableBlockIncrement(JLayer,Rectangle,int,int)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return the "block" increment for scrolling in the specified direction * * @see Scrollable - * @see LayerUI#getScrollableBlockIncrement(JLayer, Rectangle, int, int) */ public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { - if (getUI() != null) { - return getUI().getScrollableBlockIncrement(this, visibleRect, + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getScrollableBlockIncrement(visibleRect, orientation, direction); } return (orientation == SwingConstants.VERTICAL) ? visibleRect.height : @@ -504,17 +568,16 @@ public final class JLayer * determine the height of the layer, unless the preferred height * of the layer is smaller than the height of the viewport. *

- * If the ui delegate of this layer is not null, this method delegates its - * implementation to the {@code LayerUI.getScrollableTracksViewportHeight(JLayer)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return whether the layer should track the height of the viewport * * @see Scrollable - * @see LayerUI#getScrollableTracksViewportHeight(JLayer) */ public boolean getScrollableTracksViewportHeight() { - if (getUI() != null) { - return getUI().getScrollableTracksViewportHeight(this); + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getScrollableTracksViewportHeight(); } return false; } @@ -524,17 +587,16 @@ public final class JLayer * determine the width of the layer, unless the preferred width * of the layer is smaller than the width of the viewport. *

- * If the ui delegate of this layer is not null, this method delegates its - * implementation to the {@code LayerUI.getScrollableTracksViewportWidth(JLayer)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return whether the layer should track the width of the viewport * * @see Scrollable - * @see LayerUI#getScrollableTracksViewportWidth(JLayer) */ public boolean getScrollableTracksViewportWidth() { - if (getUI() != null) { - return getUI().getScrollableTracksViewportWidth(this); + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getScrollableTracksViewportWidth(); } return false; } @@ -549,20 +611,19 @@ public final class JLayer * Scrolling containers, like {@code JScrollPane}, will use this method * each time the user requests a unit scroll. *

- * If the ui delegate of this layer is not {@code null}, this method delegates its - * implementation to the {@code LayerUI.getScrollableUnitIncrement(JLayer,Rectangle,int,int)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return The "unit" increment for scrolling in the specified direction. * This value should always be positive. * * @see Scrollable - * @see LayerUI#getScrollableUnitIncrement(JLayer, Rectangle, int, int) */ public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { - if (getUI() != null) { - return getUI().getScrollableUnitIncrement( - this, visibleRect, orientation, direction); + if (getView() instanceof Scrollable) { + return ((Scrollable) getView()).getScrollableUnitIncrement( + visibleRect, orientation, direction); } return 1; } @@ -594,6 +655,16 @@ public final class JLayer eventController.updateAWTEventListener(eventMask, 0); } + /** + * Delegates its functionality to the {@link javax.swing.plaf.LayerUI#doLayout(JLayer)} method, + * if {@code LayerUI} is set. + */ + public void doLayout() { + if (getUI() != null) { + getUI().doLayout(this); + } + } + /** * static AWTEventListener to be shared with all AbstractLayerUIs */ @@ -625,8 +696,8 @@ public final class JLayer JLayer l = (JLayer) component; LayerUI ui = l.getUI(); if (ui != null && - isEventEnabled(l.getLayerEventMask(), - event.getID())) { + isEventEnabled(l.getLayerEventMask(), event.getID()) && + (!(event instanceof InputEvent) || !((InputEvent)event).isConsumed())) { ui.eventDispatched(event, l); } } @@ -758,82 +829,4 @@ public final class JLayer return super.contains(x, y); } } - - /** - * The default layout manager for the {@link javax.swing.JLayer}.
- * It places the glassPane on top of the view component - * and makes it the same size as {@code JLayer}, - * it also makes the view component the same size but minus layer's insets
- */ - private static class DefaultLayerLayout implements LayoutManager, Serializable { - /** - * {@inheritDoc} - */ - public void layoutContainer(Container parent) { - JLayer layer = (JLayer) parent; - Component view = layer.getView(); - Component glassPane = layer.getGlassPane(); - if (view != null) { - Insets insets = layer.getInsets(); - view.setLocation(insets.left, insets.top); - view.setSize(layer.getWidth() - insets.left - insets.right, - layer.getHeight() - insets.top - insets.bottom); - } - if (glassPane != null) { - glassPane.setLocation(0, 0); - glassPane.setSize(layer.getWidth(), layer.getHeight()); - } - } - - /** - * {@inheritDoc} - */ - public Dimension minimumLayoutSize(Container parent) { - JLayer layer = (JLayer) parent; - Insets insets = layer.getInsets(); - Dimension ret = new Dimension(insets.left + insets.right, - insets.top + insets.bottom); - Component view = layer.getView(); - if (view != null) { - Dimension size = view.getMinimumSize(); - ret.width += size.width; - ret.height += size.height; - } - if (ret.width == 0 || ret.height == 0) { - ret.width = ret.height = 4; - } - return ret; - } - - /** - * {@inheritDoc} - */ - public Dimension preferredLayoutSize(Container parent) { - JLayer layer = (JLayer) parent; - Insets insets = layer.getInsets(); - Dimension ret = new Dimension(insets.left + insets.right, - insets.top + insets.bottom); - Component view = layer.getView(); - if (view != null) { - Dimension size = view.getPreferredSize(); - if (size.width > 0 && size.height > 0) { - ret.width += size.width; - ret.height += size.height; - } - } - return ret; - } - - /** - * {@inheritDoc} - */ - public void addLayoutComponent(String name, Component comp) { - } - - /** - * {@inheritDoc} - */ - public void removeLayoutComponent(Component comp) { - } - } } diff --git a/jdk/src/share/classes/javax/swing/JTable.java b/jdk/src/share/classes/javax/swing/JTable.java index bcf00a37547..7842410e772 100644 --- a/jdk/src/share/classes/javax/swing/JTable.java +++ b/jdk/src/share/classes/javax/swing/JTable.java @@ -4574,9 +4574,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * @see TableColumnModelListener */ public void columnMoved(TableColumnModelEvent e) { - // If I'm currently editing, then I should stop editing - if (isEditing()) { - removeEditor(); + if (isEditing() && !getCellEditor().stopCellEditing()) { + getCellEditor().cancelCellEditing(); } repaint(); } @@ -4593,8 +4592,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * @see TableColumnModelListener */ public void columnMarginChanged(ChangeEvent e) { - if (isEditing()) { - removeEditor(); + if (isEditing() && !getCellEditor().stopCellEditing()) { + getCellEditor().cancelCellEditing(); } TableColumn resizingColumn = getResizingColumn(); // Need to do this here, before the parent's diff --git a/jdk/src/share/classes/javax/swing/ToolTipManager.java b/jdk/src/share/classes/javax/swing/ToolTipManager.java index 17bda0fdcff..ff4aa2c2ac9 100644 --- a/jdk/src/share/classes/javax/swing/ToolTipManager.java +++ b/jdk/src/share/classes/javax/swing/ToolTipManager.java @@ -459,7 +459,7 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener if (insideComponent == null) { // Drag exit } - if (window != null && event.getSource() == window) { + if (window != null && event.getSource() == window && insideComponent != null) { // if we get an exit and have a heavy window // we need to check if it if overlapping the inside component Container insideComponentWindow = insideComponent.getTopLevelAncestor(); diff --git a/jdk/src/share/classes/javax/swing/plaf/LayerUI.java b/jdk/src/share/classes/javax/swing/plaf/LayerUI.java index 2cfa8e185cc..1fb757313a4 100644 --- a/jdk/src/share/classes/javax/swing/plaf/LayerUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/LayerUI.java @@ -599,104 +599,6 @@ public class LayerUI public void applyPropertyChange(PropertyChangeEvent evt, JLayer l) { } - /** - * Returns the preferred size of the viewport for a view component. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @return the preferred size of the viewport for a view component - * @see Scrollable#getPreferredScrollableViewportSize() - */ - public Dimension getPreferredScrollableViewportSize(JLayer l) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getPreferredScrollableViewportSize(); - } - return l.getPreferredSize(); - } - - /** - * Returns a scroll increment, which is required for components - * that display logical rows or columns in order to completely expose - * one block of rows or columns, depending on the value of orientation. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @param visibleRect The view area visible within the viewport - * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL. - * @param direction Less than zero to scroll up/left, greater than zero for down/right. - * @return the "block" increment for scrolling in the specified direction - * @see Scrollable#getScrollableBlockIncrement(Rectangle, int, int) - */ - public int getScrollableBlockIncrement(JLayer l, - Rectangle visibleRect, - int orientation, int direction) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableBlockIncrement( - visibleRect,orientation, direction); - } - return (orientation == SwingConstants.VERTICAL) ? visibleRect.height : - visibleRect.width; - } - - /** - * Returns {@code false} to indicate that the height of the viewport does not - * determine the height of the layer, unless the preferred height - * of the layer is smaller than the height of the viewport. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @return whether the layer should track the height of the viewport - * @see Scrollable#getScrollableTracksViewportHeight() - */ - public boolean getScrollableTracksViewportHeight(JLayer l) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableTracksViewportHeight(); - } - return false; - } - - /** - * Returns {@code false} to indicate that the width of the viewport does not - * determine the width of the layer, unless the preferred width - * of the layer is smaller than the width of the viewport. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @return whether the layer should track the width of the viewport - * @see Scrollable - * @see LayerUI#getScrollableTracksViewportWidth(JLayer) - */ - public boolean getScrollableTracksViewportWidth(JLayer l) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableTracksViewportWidth(); - } - return false; - } - - /** - * Returns a scroll increment, which is required for components - * that display logical rows or columns in order to completely expose - * one new row or column, depending on the value of orientation. - * Ideally, components should handle a partially exposed row or column - * by returning the distance required to completely expose the item. - *

- * Scrolling containers, like JScrollPane, will use this method - * each time the user requests a unit scroll. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @param visibleRect The view area visible within the viewport - * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL. - * @param direction Less than zero to scroll up/left, greater than zero for down/right. - * @return The "unit" increment for scrolling in the specified direction. - * This value should always be positive. - * @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int) - */ - public int getScrollableUnitIncrement(JLayer l, - Rectangle visibleRect, - int orientation, int direction) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableUnitIncrement( - visibleRect, orientation, direction); - } - return 1; - } - /** * If the {@code JLayer}'s view component is not {@code null}, * this calls the view's {@code getBaseline()} method. @@ -718,7 +620,7 @@ public class LayerUI /** * If the {@code JLayer}'s view component is not {@code null}, - * this calls the view's {@code getBaselineResizeBehavior()} method. + * this returns the result of the view's {@code getBaselineResizeBehavior()} method. * Otherwise, the default implementation is called. * * @param c {@code JLayer} to return baseline resize behavior for @@ -732,4 +634,90 @@ public class LayerUI } return super.getBaselineResizeBehavior(c); } + + /** + * Causes the passed instance of {@code JLayer} to lay out its components. + * + * @param l the {@code JLayer} component where this UI delegate is being installed + */ + public void doLayout(JLayer l) { + Component view = l.getView(); + if (view != null) { + view.setBounds(0, 0, l.getWidth(), l.getHeight()); + } + Component glassPane = l.getGlassPane(); + if (glassPane != null) { + glassPane.setBounds(0, 0, l.getWidth(), l.getHeight()); + } + } + + /** + * If the {@code JLayer}'s view component is not {@code null}, + * this returns the result of the view's {@code getPreferredSize()} method. + * Otherwise, the default implementation is used. + * + * @param c {@code JLayer} to return preferred size for + * @return preferred size for the passed {@code JLayer} + */ + public Dimension getPreferredSize(JComponent c) { + JLayer l = (JLayer) c; + Component view = l.getView(); + if (view != null) { + return view.getPreferredSize(); + } + return super.getPreferredSize(c); + } + + /** + * If the {@code JLayer}'s view component is not {@code null}, + * this returns the result of the view's {@code getMinimalSize()} method. + * Otherwise, the default implementation is used. + * + * @param c {@code JLayer} to return preferred size for + * @return minimal size for the passed {@code JLayer} + */ + public Dimension getMinimumSize(JComponent c) { + JLayer l = (JLayer) c; + Component view = l.getView(); + if (view != null) { + return view.getMinimumSize(); + } + return super.getMinimumSize(c); + } + + /** + * If the {@code JLayer}'s view component is not {@code null}, + * this returns the result of the view's {@code getMaximumSize()} method. + * Otherwise, the default implementation is used. + * + * @param c {@code JLayer} to return preferred size for + * @return maximun size for the passed {@code JLayer} + */ + public Dimension getMaximumSize(JComponent c) { + JLayer l = (JLayer) c; + Component view = l.getView(); + if (view != null) { + return view.getMaximumSize(); + } + return super.getMaximumSize(c); + } + + /** + * Adds the specified region to the dirty region list if the component + * is showing. The component will be repainted after all of the + * currently pending events have been dispatched. + *

+ * This method is to be overridden when the dirty region needs to be changed. + * + * @param tm this parameter is not used + * @param x the x value of the dirty region + * @param y the y value of the dirty region + * @param width the width of the dirty region + * @param height the height of the dirty region + * @see java.awt.Component#isShowing + * @see RepaintManager#addDirtyRegion + */ + public void repaint(long tm, int x, int y, int width, int height, JLayer l) { + RepaintManager.currentManager(l).addDirtyRegion(l, x, y, width, height); + } } diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java index deba91beff3..52204916ce5 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java @@ -1603,6 +1603,7 @@ public class BasicScrollBarUI BoundedRangeModel newModel = (BoundedRangeModel)e.getNewValue(); oldModel.removeChangeListener(modelListener); newModel.addChangeListener(modelListener); + scrollBarValue = scrollbar.getValue(); scrollbar.repaint(); scrollbar.revalidate(); } else if ("orientation" == propertyName) { diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java index 77742db410f..e7c811b0c22 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java @@ -144,7 +144,7 @@ public class MetalComboBoxUI extends BasicComboBoxUI { */ public int getBaseline(JComponent c, int width, int height) { int baseline; - if (MetalLookAndFeel.usingOcean()) { + if (MetalLookAndFeel.usingOcean() && height >= 4) { height -= 4; baseline = super.getBaseline(c, width, height); if (baseline >= 0) { diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java index 4c6b446be08..ea67ac03852 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java @@ -115,6 +115,9 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI return new SynthTabbedPaneUI(); } + private SynthTabbedPaneUI() { + } + private boolean scrollableTabLayoutEnabled() { return (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT); } diff --git a/jdk/src/share/classes/sun/awt/AWTAccessor.java b/jdk/src/share/classes/sun/awt/AWTAccessor.java index 669f15ad8b8..27609806967 100644 --- a/jdk/src/share/classes/sun/awt/AWTAccessor.java +++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java @@ -344,6 +344,11 @@ public final class AWTAccessor { * Removes the last focus request for the heavyweight from the queue. */ void removeLastFocusRequest(Component heavyweight); + + /* + * Sets the most recent focus owner in the window. + */ + void setMostRecentFocusOwner(Window window, Component component); } /* diff --git a/jdk/src/share/classes/sun/awt/EmbeddedFrame.java b/jdk/src/share/classes/sun/awt/EmbeddedFrame.java index b3e6a2f7801..96b1325f8cb 100644 --- a/jdk/src/share/classes/sun/awt/EmbeddedFrame.java +++ b/jdk/src/share/classes/sun/awt/EmbeddedFrame.java @@ -70,7 +70,10 @@ public abstract class EmbeddedFrame extends Frame // JDK 1.1 compatibility private static final long serialVersionUID = 2967042741780317130L; - // Use these in traverseOut method to determine directions + /* + * The constants define focus traversal directions. + * Use them in {@code traverseIn}, {@code traverseOut} methods. + */ protected static final boolean FORWARD = true; protected static final boolean BACKWARD = false; @@ -283,6 +286,41 @@ public abstract class EmbeddedFrame extends Frame return false; } + /** + * This method is called by the embedder when we should receive focus as element + * of the traversal chain. The method requests focus on: + * 1. the first Component of this EmbeddedFrame if user moves focus forward + * in the focus traversal cycle. + * 2. the last Component of this EmbeddedFrame if user moves focus backward + * in the focus traversal cycle. + * + * The direction parameter specifies which of the two mentioned cases is + * happening. Use FORWARD and BACKWARD constants defined in the EmbeddedFrame class + * to avoid confusing boolean values. + * + * A concrete implementation of this method is defined in the platform-dependent + * subclasses. + * + * @param direction FORWARD or BACKWARD + * @return true, if the EmbeddedFrame wants to get focus, false otherwise. + */ + public boolean traverseIn(boolean direction) { + Component comp = null; + + if (direction == FORWARD) { + comp = getFocusTraversalPolicy().getFirstComponent(this); + } else { + comp = getFocusTraversalPolicy().getLastComponent(this); + } + if (comp != null) { + // comp.requestFocus(); - Leads to a hung. + + AWTAccessor.getKeyboardFocusManagerAccessor().setMostRecentFocusOwner(this, comp); + synthesizeWindowActivation(true); + } + return (null != comp); + } + /** * This method is called from dispatchKeyEvent in the following two cases: * 1. The focus is on the first Component of this EmbeddedFrame and we are diff --git a/jdk/src/share/classes/sun/jkernel/DownloadManager.java b/jdk/src/share/classes/sun/jkernel/DownloadManager.java index 1a4f1ff28e6..416cec7feea 100644 --- a/jdk/src/share/classes/sun/jkernel/DownloadManager.java +++ b/jdk/src/share/classes/sun/jkernel/DownloadManager.java @@ -25,13 +25,18 @@ package sun.jkernel; import java.io.*; +import java.net.URLStreamHandlerFactory; +import java.net.URL; +import java.net.MalformedURLException; import java.security.*; import java.util.*; import java.util.concurrent.*; import java.util.jar.*; import java.util.zip.*; -import sun.misc.Launcher; import sun.misc.BootClassLoaderHook; +import sun.misc.Launcher; +import sun.misc.URLClassPath; +import sun.net.www.ParseUtil; /** * Handles the downloading of additional JRE components. The bootstrap class @@ -658,31 +663,61 @@ public class DownloadManager extends BootClassLoaderHook { return getAppDataLocalLow() + getKernelJREDir(); } - /** - * Returns an array of JAR files which have been added to the boot strap - * class path since the JVM was first booted. - */ - public static synchronized File[] getAdditionalBootStrapPaths() { - return additionalBootStrapPaths != null ? additionalBootStrapPaths : - new File[0]; - } - - + // To be revisited: + // How DownloadManager maintains its bootstrap class path. + // sun.misc.Launcher.getBootstrapClassPath() returns + // DownloadManager.getBootstrapClassPath() instead. + // + // So should no longer need to lock the Launcher.class. + // In addition, additionalBootStrapPaths is not really needed + // if it obtains the initial bootclasspath during DownloadManager's + // initialization. private static void addEntryToBootClassPath(File path) { // Must acquire these locks in this order synchronized(Launcher.class) { - synchronized(DownloadManager.class) { + synchronized(DownloadManager.class) { File[] newBootStrapPaths = new File[ additionalBootStrapPaths.length + 1]; System.arraycopy(additionalBootStrapPaths, 0, newBootStrapPaths, 0, additionalBootStrapPaths.length); newBootStrapPaths[newBootStrapPaths.length - 1] = path; additionalBootStrapPaths = newBootStrapPaths; - Launcher.flushBootstrapClassPath(); + if (bootstrapClassPath != null) + bootstrapClassPath.addURL(getFileURL(path)); } } } + /** + * Returns the kernel's bootstrap class path which includes the additional + * JARs downloaded + */ + private static URLClassPath bootstrapClassPath = null; + private synchronized static + URLClassPath getBootClassPath(URLClassPath bcp, + URLStreamHandlerFactory factory) + { + if (bootstrapClassPath == null) { + bootstrapClassPath = new URLClassPath(bcp.getURLs(), factory); + for (File path : additionalBootStrapPaths) { + bootstrapClassPath.addURL(getFileURL(path)); + } + } + return bootstrapClassPath; + } + + private static URL getFileURL(File file) { + try { + file = file.getCanonicalFile(); + } catch (IOException e) {} + + try { + return ParseUtil.fileToEncodedURL(file); + } catch (MalformedURLException e) { + // Should never happen since we specify the protocol... + throw new InternalError(); + } + } /** * Scan through java.ext.dirs to see if the lib/ext directory is included. @@ -1680,8 +1715,10 @@ public class DownloadManager extends BootClassLoaderHook { } } - public File[] getAdditionalBootstrapPaths() { - return DownloadManager.getAdditionalBootStrapPaths(); + public URLClassPath getBootstrapClassPath(URLClassPath bcp, + URLStreamHandlerFactory factory) + { + return DownloadManager.getBootClassPath(bcp, factory); } public boolean isCurrentThreadPrefetching() { diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher.properties b/jdk/src/share/classes/sun/launcher/resources/launcher.properties index cb4718976fb..e89d147a5bb 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher.properties @@ -49,7 +49,7 @@ java.launcher.opt.footer =\ -cp \n\ \ require the specified version to run\n\ \ -showversion print product version and continue\n\ -\ -jre-restrict-search | -jre-no-restrict-search\n\ +\ -jre-restrict-search | -no-jre-restrict-search\n\ \ include/exclude user private JREs in the version search\n\ \ -? -help print this help message\n\ \ -X print help on non-standard options\n\ diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_de.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_de.properties index 275b452a80b..99d347d5966 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_de.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_de.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ Standard-VM ist {0}, java.launcher.ergo.message2 =\ da Sie auf einem Server-Class-Computer ausf\u00fchren.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp \n\ -classpath \n\ A {0} getrennte Liste von Verzeichnissen, JAR-Archiven,\n\ und ZIP-Archiven f\u00fcr die Suche nach Klassendateien .\n\ -D=\n\ Systemeigenschaft festlegen\n\ -verbose[:class|gc|jni]\n\ ausf\u00fchrliche Ausgabe aktivieren\n\ -version Produktversion drucken und beenden\n\ -version:\n\ angegebene Version zum Ausf\u00fchren erforderlich \n\ -showversion Produktversion drucken und fortfahren\n\ -jre-restrict-search | -jre-no-restrict-search\n\ private JREs der Benutzer in Versionssuche ein-/ausschlie\u00dfen\n\ -? -help diese Hilfemeldung drucken\n\ -X Hilfe zu nicht standardm\u00e4\u00dfigen Optionen drucken\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ Assertions mit spezifizierter Granularit\u00e4t aktivieren\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ Assertions mit spezifizierter Granularit\u00e4t deaktivieren\n\ -esa | --enablesystemassertions\n\ System-Assertions aktivieren\n\ -dsa | --disablesystemassertions\n\ System-Assertions deaktivieren\n\ -agentlib:[=]\n\ systemeigene Agent-Bibliothek laden , z.B. -agentlib:hprof\n\ siehe auch, -agentlib:jdwp=help und -agentlib:hprof=help\n\ -agentpath:[=]\n\ systemeigene Agent-Bibliothek \u00fcber vollst\u00e4ndigen Pfadnamen laden\n\ -javaagent:[=]\n\ Java Programmierungs-Sprachagenten laden, siehe java.lang.instrument\n\ -splash:\n\ Eingangsbildschirm mit spezifiziertem Bild anzeigen\nWeitere Informationen finden Sie unter http://java.sun.com/javase/reference. +java.launcher.opt.footer =\ -cp \n\ -classpath \n\ A {0} getrennte Liste von Verzeichnissen, JAR-Archiven,\n\ und ZIP-Archiven f\u00fcr die Suche nach Klassendateien .\n\ -D=\n\ Systemeigenschaft festlegen\n\ -verbose[:class|gc|jni]\n\ ausf\u00fchrliche Ausgabe aktivieren\n\ -version Produktversion drucken und beenden\n\ -version:\n\ angegebene Version zum Ausf\u00fchren erforderlich \n\ -showversion Produktversion drucken und fortfahren\n\ -jre-restrict-search | -no-jre-restrict-search\n\ private JREs der Benutzer in Versionssuche ein-/ausschlie\u00dfen\n\ -? -help diese Hilfemeldung drucken\n\ -X Hilfe zu nicht standardm\u00e4\u00dfigen Optionen drucken\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ Assertions mit spezifizierter Granularit\u00e4t aktivieren\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ Assertions mit spezifizierter Granularit\u00e4t deaktivieren\n\ -esa | --enablesystemassertions\n\ System-Assertions aktivieren\n\ -dsa | --disablesystemassertions\n\ System-Assertions deaktivieren\n\ -agentlib:[=]\n\ systemeigene Agent-Bibliothek laden , z.B. -agentlib:hprof\n\ siehe auch, -agentlib:jdwp=help und -agentlib:hprof=help\n\ -agentpath:[=]\n\ systemeigene Agent-Bibliothek \u00fcber vollst\u00e4ndigen Pfadnamen laden\n\ -javaagent:[=]\n\ Java Programmierungs-Sprachagenten laden, siehe java.lang.instrument\n\ -splash:\n\ Eingangsbildschirm mit spezifiziertem Bild anzeigen\nWeitere Informationen finden Sie unter http://java.sun.com/javase/reference. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed gemischte Ausf\u00fchrung des Modus (Standard)\n\ -Xint nur interpretierte Ausf\u00fchrung des Modus\n\ -Xbootclasspath:\n\ Suchpfad f\u00fcr Bootstrap-Klassen und Ressourcen einrichten\n\ -Xbootclasspath/a:\n\ an das Ende des Bootstrap-Klassenpfads anh\u00e4ngen\n\ -Xbootclasspath/p:\n\ an den Beginn des Bootstrap-Klassenpfads anh\u00e4ngen\n\ -Xnoclassgc Klassen-Speicherbereinigung deaktivieren\n\ -Xincgc inkrementelle Speicherbereinigung aktivieren\n\ -Xloggc: GC-Status f\u00fcr eine Datei mit Zeitstempeln einrichten\n\ -Xbatch Hintergrund-Kompilation deaktivieren\n\ -Xms anf\u00e4ngliche Java Heap-Gr\u00f6\u00dfe einstellen\n\ -Xmx maximale Java Heap-Gr\u00f6\u00dfe einstellen\n\ -Xss Gr\u00f6\u00dfe des Java Thread-Stack einstellen\n\ -Xprof CPU-Profildaten ausgeben\n\ -Xfuture genaueste Pr\u00fcfungen aktivieren und zuk\u00fcnftige Standards absehen\n\ -Xrs Verwendung von OS-Signalen durch Java/VM reduzieren (siehe Dokumentation)\n\ -Xcheck:jni zus\u00e4tzliche Pr\u00fcfungen f\u00fcr JNI- Funktionen ausf\u00fchren\n\ -Xshare:off Nicht versuchen, freigegebene Klassendaten zu verwenden\n\ -Xshare:auto Freigegebene Klassendaten verwenden, wenn m\u00f6glich (Standard)\n\ -Xshare:on Nutzung freigegebener Daten ist erforderlich, ansonsten schl\u00e4gt der Vorgang fehl.\n\nDie -X-Optionen sind kein Standard und k\u00f6nnen \u00c4nderungen unterliegen.\n diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_es.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_es.properties index 11bf04f2a66..2daa7a2ffc8 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_es.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_es.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ La m\u00e1quina virtual predete java.launcher.ergo.message2 =\ porque est\u00e1 trabajando en una m\u00e1quina de clase servidor.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp \n\ -classpath \n\ Una {0} lista de directorios, archivos JAR,\n\ y archivos ZIP en los que buscar los archivos de clase.\n\ -D=\n\ establecer una propiedad de sistema\n\ -verbose[:class|gc|jni]\n\ permitir la salida detallada\n\ -version imprimir versi\u00f3n del producto y salir\n\ -version:\n\ solicitar la versi\u00f3n especificada para ejecutar\n\ -showversion imprimir versi\u00f3n del producto y continuar\n\ -jre-restrict-search | -jre-no-restrict-search\n\ incluir/excluir JRE privados del usuario en la b\u00fasqueda de la versi\u00f3n\n\ -? -help imprimir este mensaje de ayuda\n\ -X imprimir ayuda en las opciones no est\u00e1ndar\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ permitir afirmaciones con granularidad especificada\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ desactivar afirmaciones con granularidad especificada\n\ -esa | -enablesystemassertions\n\ permitir afirmaciones del sistema\n\ -dsa | -disablesystemassertions\n\ desactivar afirmaciones del sistema\n\ -agentlib:[=]\n\ cargar biblioteca de agente nativo, por ejemplo -agentlib:hprof\n\ consulte tambi\u00e9n, -agentlib:jdwp=help y -agentlib:hprof=help\n\ -agentpath:[=]\n\ cargar biblioteca de agente nativo por ruta completa\n\ -javaagent:[=]\n\ cargar agente del lenguaje de programaci\u00f3n Java, consulte java.lang.instrument\n\ -splash:\n\ mostrar pantalla de bienvenida con imagen especificada\nConsulte http://java.sun.com/javase/reference para m\u00e1s informaci\u00f3n. +java.launcher.opt.footer =\ -cp \n\ -classpath \n\ Una {0} lista de directorios, archivos JAR,\n\ y archivos ZIP en los que buscar los archivos de clase.\n\ -D=\n\ establecer una propiedad de sistema\n\ -verbose[:class|gc|jni]\n\ permitir la salida detallada\n\ -version imprimir versi\u00f3n del producto y salir\n\ -version:\n\ solicitar la versi\u00f3n especificada para ejecutar\n\ -showversion imprimir versi\u00f3n del producto y continuar\n\ -jre-restrict-search | -no-jre-restrict-search\n\ incluir/excluir JRE privados del usuario en la b\u00fasqueda de la versi\u00f3n\n\ -? -help imprimir este mensaje de ayuda\n\ -X imprimir ayuda en las opciones no est\u00e1ndar\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ permitir afirmaciones con granularidad especificada\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ desactivar afirmaciones con granularidad especificada\n\ -esa | -enablesystemassertions\n\ permitir afirmaciones del sistema\n\ -dsa | -disablesystemassertions\n\ desactivar afirmaciones del sistema\n\ -agentlib:[=]\n\ cargar biblioteca de agente nativo, por ejemplo -agentlib:hprof\n\ consulte tambi\u00e9n, -agentlib:jdwp=help y -agentlib:hprof=help\n\ -agentpath:[=]\n\ cargar biblioteca de agente nativo por ruta completa\n\ -javaagent:[=]\n\ cargar agente del lenguaje de programaci\u00f3n Java, consulte java.lang.instrument\n\ -splash:\n\ mostrar pantalla de bienvenida con imagen especificada\nConsulte http://java.sun.com/javase/reference para m\u00e1s informaci\u00f3n. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed modo mixto de ejecuci\u00f3n (predeterminado)\n\ -Xint s\u00f3lo modo de ejecuci\u00f3n interpretado\n\ -Xbootclasspath:\n\ definir ruta de b\u00fasqueda para clases y recursos de la rutina de carga\n\ -Xbootclasspath/a:\n\ a\u00f1adir al final de la ruta de clase de la rutina de carga\n\ -Xbootclasspath/p:\n\ a\u00f1adir al principio de la ruta de clase de la rutina de carga\n\ -Xnoclassgc desactivar recolecci\u00f3n de residuos de clase\n\ -Xincgc permitir recolecci\u00f3n de residuos incremental\n\ -Xloggc: registrar estado de GC en un archivo con marcas de tiempo\n\ -Xbatch desactivar recopilaci\u00f3n de fondos\n\ -Xms definir tama\u00f1o del mont\u00f3n de Java inicial\n\ -Xmx definir tama\u00f1o m\u00e1ximo del mont\u00f3n de Java\n\ -Xss definir tama\u00f1o de la pila del subproceso de java\n\ -Xprof salida de datos del perfil de la cpu\n\ -Xfuture permitir comprobaciones m\u00e1s estrictas para los procesos predeterminados futuros\n\ -Xrs reducir el uso de se\u00f1ales del SO por parte de Java o la m\u00e1quina virtual (consulte la documentaci\u00f3n)\n\ -Xcheck:jni realizar comprobaciones adicionales para las funciones de JNI\n\ -Xshare:off no intentar utilizar datos de clase compartidos\n\ -Xshare:auto utilizar datos de clase compartidos siempre que sea posible (predeterminado)\n\ -Xshare:on solicitar el uso obligatorio de datos de clase compartidos.\n\nLas opciones "-X" no son est\u00e1ndar y pueden sufrir modificaciones sin previo aviso.\n diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_fr.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_fr.properties index c4e5f47a090..ace15ee3529 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_fr.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_fr.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ La machine virtuelle par d\u00e java.launcher.ergo.message2 =\ car vous utilisez une machine de type serveur.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp \n\ -classpath \n\ Une liste s\u00e9par\u00e9e {0} de r\u00e9pertoires, archives JAR\n\ et archives ZIP dans laquelle rechercher des fichiers de classe.\n\ -D=\n\ d\u00e9finir une propri\u00e9t\u00e9 syst\u00e8me\n\ -verbose[:class|gc|jni]\n\ activer une sortie d\u00e9taill\u00e9ee\n\ -version imprimer la version du produit et quitter\n\ -version:\n\ utiliser la version sp\u00e9cifi\u00e9e pour l''ex\u00e9cution\n\ -showversion imprimer la version du produit et continuer\n\ -jre-restrict-search | -jre-no-restrict-search\n\ inclure/exclure les JRE priv\u00e9s d''utilisateur dans la recherche de version\n\ -? -help imprimer ce message d''aide\n\ -X imprimer l''aide relative aux options non standard\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ activer les assertions avec la granularit\u00e9 sp\u00e9cifi\u00e9e\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ d\u00e9sactiver les assertions avec la granularit\u00e9 sp\u00e9cifi\u00e9e\n\ -esa | -enablesystemassertions\n\ activer les assertions syst\u00e8me\n\ -dsa | -disablesystemassertions\n\ d\u00e9sactiver les assertions syst\u00e8me\n\ -agentlib:[=]\n\ charger la biblioth\u00e8que d''agents natifs, par exemple -agentlib:hprof\n\ voir \u00e9galement, -agentlib:jdwp=help et -agentlib:hprof=help\n\ -agentpath:[=]\n\ charger la biblioth\u00e8que d''agents natifs en indiquant le chemin complet\n\ -javaagent:[=]\n\ charger l''agent de langage de programmation Java, voir java.lang.instrument\n\ -splash:\n\ afficher l''\u00e9cran de bienvenue avec l''image sp\u00e9cifi\u00e9e\nPour plus de d\u00e9tails, reportez-vous \u00e0 la page http://java.sun.com/javase/reference. +java.launcher.opt.footer =\ -cp \n\ -classpath \n\ Une liste s\u00e9par\u00e9e {0} de r\u00e9pertoires, archives JAR\n\ et archives ZIP dans laquelle rechercher des fichiers de classe.\n\ -D=\n\ d\u00e9finir une propri\u00e9t\u00e9 syst\u00e8me\n\ -verbose[:class|gc|jni]\n\ activer une sortie d\u00e9taill\u00e9ee\n\ -version imprimer la version du produit et quitter\n\ -version:\n\ utiliser la version sp\u00e9cifi\u00e9e pour l''ex\u00e9cution\n\ -showversion imprimer la version du produit et continuer\n\ -jre-restrict-search | -no-jre-restrict-search\n\ inclure/exclure les JRE priv\u00e9s d''utilisateur dans la recherche de version\n\ -? -help imprimer ce message d''aide\n\ -X imprimer l''aide relative aux options non standard\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ activer les assertions avec la granularit\u00e9 sp\u00e9cifi\u00e9e\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ d\u00e9sactiver les assertions avec la granularit\u00e9 sp\u00e9cifi\u00e9e\n\ -esa | -enablesystemassertions\n\ activer les assertions syst\u00e8me\n\ -dsa | -disablesystemassertions\n\ d\u00e9sactiver les assertions syst\u00e8me\n\ -agentlib:[=]\n\ charger la biblioth\u00e8que d''agents natifs, par exemple -agentlib:hprof\n\ voir \u00e9galement, -agentlib:jdwp=help et -agentlib:hprof=help\n\ -agentpath:[=]\n\ charger la biblioth\u00e8que d''agents natifs en indiquant le chemin complet\n\ -javaagent:[=]\n\ charger l''agent de langage de programmation Java, voir java.lang.instrument\n\ -splash:\n\ afficher l''\u00e9cran de bienvenue avec l''image sp\u00e9cifi\u00e9e\nPour plus de d\u00e9tails, reportez-vous \u00e0 la page http://java.sun.com/javase/reference. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed ex\u00e9cution du mode compil\u00e9 (par d\u00e9faut)\n\ -Xint ex\u00e9cution du mode interpr\u00e9t\u00e9 uniquement\n\ -Xbootclasspath:\n\ d\u00e9finir le chemin de recherche pour les classes et ressources bootstrap\n\ -Xbootclasspath/a:\n\ ajouter \u00e0 la fin du chemin de la classe bootstrap\n\ -Xbootclasspath/p:\n\ ajouter au d\u00e9but du chemin de la classe bootstrap\n\ -Xnoclassgc d\u00e9sactiver la collection d''informations parasites sur la classe\n\ -Xincgc activer la collection incr\u00e9mentielle d''informations parasites\n\ -Xloggc: enregistrer le statut GC dans un fichier horodat\u00e9\n\ -Xbatch d\u00e9sactiver la compilation d''arri\u00e8re-plans\n\ -Xms d\u00e9finir la taille initiale des tas Java\n\ -Xmx d\u00e9finir la taille maximale des tas Java\n\ -Xss d\u00e9finir la taille des piles de fil Java\n\ -Xprof \u00e9mettre des donn\u00e9es de profilage d''UC\n\ -Xfuture activer des contr\u00f4les plus stricts, en anticipant les erreurs futures\n\ -Xrs r\u00e9duire l''utilisation des signaux d''OS par Java/la machine virtuelle (reportez-vous \u00e0 la documentation)\n\ -Xcheck:jni effectuer des contr\u00f4les suppl\u00e9mentaires pour les fonctions JNI\n\ -Xshare:off ne pas tenter d''utiliser les donn\u00e9es de classe partag\u00e9es\n\ -Xshare:auto utiliser les donn\u00e9es de classe partag\u00e9es si possible (par d\u00e9faut)\n\ -Xshare:on forcer l''utilisation de donn\u00e9es de classe partag\u00e9es, sinon \u00e9chec.\n\nLes options\u00a0X ne sont pas standard et sont sujettes \u00e0 modification sans pr\u00e9avis.\n diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_it.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_it.properties index e73987e57e5..267283288a8 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_it.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_it.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ La macchina virtuale predefinit java.launcher.ergo.message2 =\ perch\u00e9 l'esecuzione avviene su una macchina di classe server.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp \n\ -classpath \n\ Elenco separato da {0} di directory, archivi JAR\n\ e archivi ZIP in cui cercare i file di classe.\n\ -D=\n\ imposta una propriet\u00e0 di sistema\n\ -verbose[:class|gc|jni]\n\ attiva l''output dettagliato\n\ -version stampa la versione del prodotto ed esce\n\ -version:\n\ richiede la versione specificata per l''esecuzione\n\ -showversion stampa la versione del prodotto e procede\n\ -jre-restrict-search | -jre-no-restrict-search\n\ consente di includere/escludere JRE privati dell''utente nella ricerca della versione\n\ -? -help stampa il presente messaggio della Guida\n\ -X stampa la Guida delle opzioni non standard\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ attiva le asserzioni con la granularit\u00e0 specificata\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ disattiva le asserzioni con la granularit\u00e0 specificata\n\ -esa | -enablesystemassertions\n\ attiva le asserzioni di sistema\n\ -dsa | -disablesystemassertions\n\ disattiva le asserzioni di sistema\n\ -agentlib:[=]\n\ carica la libreria agente nativa , ad es. -agentlib:hprof\n\ vedere anche, -agentlib:jdwp=help e -agentlib:hprof=help\n\ -agentpath:[=]\n\ carica la libreria agente nativa in base al percorso completo\n\ -javaagent:[=]\n\ carica l''agente del linguaggio di programmazione Java, vedere java.lang.instrument\n\ -splash:\n\ mostra la schermata iniziale con l''immagine specificata\nPer ulteriori informazioni, visitare http://java.sun.com/javase/reference. +java.launcher.opt.footer =\ -cp \n\ -classpath \n\ Elenco separato da {0} di directory, archivi JAR\n\ e archivi ZIP in cui cercare i file di classe.\n\ -D=\n\ imposta una propriet\u00e0 di sistema\n\ -verbose[:class|gc|jni]\n\ attiva l''output dettagliato\n\ -version stampa la versione del prodotto ed esce\n\ -version:\n\ richiede la versione specificata per l''esecuzione\n\ -showversion stampa la versione del prodotto e procede\n\ -jre-restrict-search | -no-jre-restrict-search\n\ consente di includere/escludere JRE privati dell''utente nella ricerca della versione\n\ -? -help stampa il presente messaggio della Guida\n\ -X stampa la Guida delle opzioni non standard\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ attiva le asserzioni con la granularit\u00e0 specificata\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ disattiva le asserzioni con la granularit\u00e0 specificata\n\ -esa | -enablesystemassertions\n\ attiva le asserzioni di sistema\n\ -dsa | -disablesystemassertions\n\ disattiva le asserzioni di sistema\n\ -agentlib:[=]\n\ carica la libreria agente nativa , ad es. -agentlib:hprof\n\ vedere anche, -agentlib:jdwp=help e -agentlib:hprof=help\n\ -agentpath:[=]\n\ carica la libreria agente nativa in base al percorso completo\n\ -javaagent:[=]\n\ carica l''agente del linguaggio di programmazione Java, vedere java.lang.instrument\n\ -splash:\n\ mostra la schermata iniziale con l''immagine specificata\nPer ulteriori informazioni, visitare http://java.sun.com/javase/reference. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed esecuzione in modalit\u00e0 mista (predefinita)\n\ -Xint solo esecuzione in modalit\u00e0 interpretata\n\ -Xbootclasspath:\n\ imposta il percorso di ricerca per classi e risorse di bootstrap\n\ -Xbootclasspath/a:\n\ accoda alla fine del percorso della classe di bootstrap\n\ -Xbootclasspath/p:\n\ antepone al percorso della classe di bootsrap\n\ -Xnoclassgc disattiva Garbage Collection per la classe\n\ -Xincgc attiva Garbage Collection incrementale\n\ -Xloggc: registra lo stato GC in un file con timestamp\n\ -Xbatch disattiva la compilazione in background\n\ -Xms imposta la dimensione heap Java iniziale\n\ -Xmx imposta la dimensione heap Java massima\n\ -Xss imposta la dimensione dello stack del thread Java\n\ -Xprof dati di profilo della CPU di output\n\ -Xfuture attiva verifiche pi\u00f9 dettagliate, anticipa le impostazioni predefinite future\n\ -Xrs riduce l''uso di segnali OS da parte di Java o della macchina virtuale (vedere la documentazione)\n\ -Xcheck:jni esegue verifiche aggiuntive per le funzioni JNI\n\ -Xshare:off esclude l''utilizzo di dati classe condivisi\n\ -Xshare:auto imposta l''utilizzo di dati classe condivisi ogni volta che \u00e8 possibile (impostazione predefinita)\n\ -Xshare:on richiede l''utilizzo di dati classe condivisi, in caso contrario origina un errore.\n\nLe opzioni -X sono non standard e soggette a modifiche senza preavviso.\n diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_ja.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_ja.properties index ada07d76a59..2da74b850ca 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_ja.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_ja.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ \u30c7\u30d5\u30a9\u30eb\u30c8 java.launcher.ergo.message2 =\ \u7406\u7531\u306f\u3001\u30b5\u30fc\u30d0\u30fc\u30af\u30e9\u30b9\u306e\u30de\u30b7\u30f3\u3092\u4f7f\u7528\u3057\u3066\u3044\u308b\u304b\u3089\u3067\u3059\u3002\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp <\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u304a\u3088\u3073 ZIP/JAR \u30d5\u30a1\u30a4\u30eb\u306e\u30af\u30e9\u30b9\u691c\u7d22\u30d1\u30b9>\n\ -classpath <\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u304a\u3088\u3073 ZIP/JAR \u30d5\u30a1\u30a4\u30eb\u306e\u30af\u30e9\u30b9\u691c\u7d22\u30d1\u30b9>\n\ \u30af\u30e9\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u691c\u7d22\u3059\u308b\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3001JAR \u30a2\u30fc\u30ab\u30a4\u30d6\u3001\n\ \u304a\u3088\u3073 ZIP \u30a2\u30fc\u30ab\u30a4\u30d6\u306e {0} \u3067\u5206\u5272\u3055\u308c\u305f\u30ea\u30b9\u30c8\u3002\n\ -D=\n\ \u30b7\u30b9\u30c6\u30e0\u30d7\u30ed\u30d1\u30c6\u30a3\u30fc\u306e\u8a2d\u5b9a\n\ -verbose[:class|gc|jni]\n\ \u8a73\u7d30\u51fa\u529b\u306e\u6709\u52b9\u5316\n\ -version \u88fd\u54c1\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u5370\u5237\u3057\u3066\u7d42\u4e86\n\ -version:\n\ \u5b9f\u884c\u306b\u5fc5\u8981\u306a\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u8981\u6c42\n\ -showversion \u88fd\u54c1\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u5370\u5237\u3057\u3066\u7d99\u7d9a\n\ -jre-restrict-search | -jre-no-restrict-search\n\ \u30d0\u30fc\u30b8\u30e7\u30f3\u691c\u7d22\u306b\u30e6\u30fc\u30b6\u30fc\u306e\u975e\u516c\u958b JRE \u3092\u542b\u3081\u308b\u304b\u9664\u5916\u3059\u308b\u304b\u3092\u5207\u308a\u66ff\u3048\u308b\n\ -? -help \u3053\u306e\u30d8\u30eb\u30d7\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u5370\u5237\n\ -X \u975e\u6a19\u6e96\u30aa\u30d7\u30b7\u30e7\u30f3\u306e\u30d8\u30eb\u30d7\u3092\u5370\u5237\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ \u6307\u5b9a\u3057\u305f\u7c92\u5ea6\u3067\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u6709\u52b9\u5316\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ \u6307\u5b9a\u3057\u305f\u7c92\u5ea6\u3067\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u7121\u52b9\u5316\n\ -esa | -enablesystemassertions\n\ \u30b7\u30b9\u30c6\u30e0\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u6709\u52b9\u5316\n\ -dsa | -disablesystemassertions\n\ \u30b7\u30b9\u30c6\u30e0\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u7121\u52b9\u5316\n\ -agentlib:[=]\n\ \u30cd\u30a4\u30c6\u30a3\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u30e9\u30a4\u30d6\u30e9\u30ea (\u4f8b: -agentlib:hprof) \u3092\u30ed\u30fc\u30c9\n\ \u95a2\u9023\u9805\u76ee\u3001 -agentlib:jdwp=help and -agentlib:hprof=help\n\ -agentpath:[=]\n\ \u5b8c\u5168\u306a\u30d1\u30b9\u540d\u3067\u30cd\u30a4\u30c6\u30a3\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u30ed\u30fc\u30c9\n\ -javaagent:[=]\n\ Java \u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u8a00\u8a9e\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u3092\u30ed\u30fc\u30c9\u3002java.lang.instrument \u3092\u53c2\u7167\n\ -splash:\n\ \u6307\u5b9a\u3057\u305f\u753b\u50cf\u306e\u30b9\u30d7\u30e9\u30c3\u30b7\u30e5\u753b\u9762\u3092\u8868\u793a\n\u8a73\u7d30\u306f http://java.sun.com/javase/reference \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +java.launcher.opt.footer =\ -cp <\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u304a\u3088\u3073 ZIP/JAR \u30d5\u30a1\u30a4\u30eb\u306e\u30af\u30e9\u30b9\u691c\u7d22\u30d1\u30b9>\n\ -classpath <\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u304a\u3088\u3073 ZIP/JAR \u30d5\u30a1\u30a4\u30eb\u306e\u30af\u30e9\u30b9\u691c\u7d22\u30d1\u30b9>\n\ \u30af\u30e9\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u691c\u7d22\u3059\u308b\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3001JAR \u30a2\u30fc\u30ab\u30a4\u30d6\u3001\n\ \u304a\u3088\u3073 ZIP \u30a2\u30fc\u30ab\u30a4\u30d6\u306e {0} \u3067\u5206\u5272\u3055\u308c\u305f\u30ea\u30b9\u30c8\u3002\n\ -D=\n\ \u30b7\u30b9\u30c6\u30e0\u30d7\u30ed\u30d1\u30c6\u30a3\u30fc\u306e\u8a2d\u5b9a\n\ -verbose[:class|gc|jni]\n\ \u8a73\u7d30\u51fa\u529b\u306e\u6709\u52b9\u5316\n\ -version \u88fd\u54c1\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u5370\u5237\u3057\u3066\u7d42\u4e86\n\ -version:\n\ \u5b9f\u884c\u306b\u5fc5\u8981\u306a\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u8981\u6c42\n\ -showversion \u88fd\u54c1\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u5370\u5237\u3057\u3066\u7d99\u7d9a\n\ -jre-restrict-search | -no-jre-restrict-search\n\ \u30d0\u30fc\u30b8\u30e7\u30f3\u691c\u7d22\u306b\u30e6\u30fc\u30b6\u30fc\u306e\u975e\u516c\u958b JRE \u3092\u542b\u3081\u308b\u304b\u9664\u5916\u3059\u308b\u304b\u3092\u5207\u308a\u66ff\u3048\u308b\n\ -? -help \u3053\u306e\u30d8\u30eb\u30d7\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u5370\u5237\n\ -X \u975e\u6a19\u6e96\u30aa\u30d7\u30b7\u30e7\u30f3\u306e\u30d8\u30eb\u30d7\u3092\u5370\u5237\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ \u6307\u5b9a\u3057\u305f\u7c92\u5ea6\u3067\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u6709\u52b9\u5316\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ \u6307\u5b9a\u3057\u305f\u7c92\u5ea6\u3067\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u7121\u52b9\u5316\n\ -esa | -enablesystemassertions\n\ \u30b7\u30b9\u30c6\u30e0\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u6709\u52b9\u5316\n\ -dsa | -disablesystemassertions\n\ \u30b7\u30b9\u30c6\u30e0\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u7121\u52b9\u5316\n\ -agentlib:[=]\n\ \u30cd\u30a4\u30c6\u30a3\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u30e9\u30a4\u30d6\u30e9\u30ea (\u4f8b: -agentlib:hprof) \u3092\u30ed\u30fc\u30c9\n\ \u95a2\u9023\u9805\u76ee\u3001 -agentlib:jdwp=help and -agentlib:hprof=help\n\ -agentpath:[=]\n\ \u5b8c\u5168\u306a\u30d1\u30b9\u540d\u3067\u30cd\u30a4\u30c6\u30a3\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u30ed\u30fc\u30c9\n\ -javaagent:[=]\n\ Java \u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u8a00\u8a9e\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u3092\u30ed\u30fc\u30c9\u3002java.lang.instrument \u3092\u53c2\u7167\n\ -splash:\n\ \u6307\u5b9a\u3057\u305f\u753b\u50cf\u306e\u30b9\u30d7\u30e9\u30c3\u30b7\u30e5\u753b\u9762\u3092\u8868\u793a\n\u8a73\u7d30\u306f http://java.sun.com/javase/reference \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002 # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed \u6df7\u5408\u30e2\u30fc\u30c9\u3067\u306e\u5b9f\u884c (\u30c7\u30d5\u30a9\u30eb\u30c8)\n\ -Xint \u30a4\u30f3\u30bf\u30fc\u30d7\u30ea\u30bf\u30e2\u30fc\u30c9\u3067\u306e\u307f\u5b9f\u884c\n\ -Xbootclasspath:\n\ \u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7\u30af\u30e9\u30b9\u304a\u3088\u3073\u30ea\u30bd\u30fc\u30b9\u306e\u691c\u7d22\u30d1\u30b9\u3092\u8a2d\u5b9a\n\ -Xbootclasspath/a:\n\ \u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7\u30af\u30e9\u30b9\u306e\u30d1\u30b9\u306e\u672b\u5c3e\u306b\u8ffd\u52a0\n\ -Xbootclasspath/p:\n\ \u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7\u30af\u30e9\u30b9\u306e\u30d1\u30b9\u306e\u5192\u982d\u306b\u8ffd\u52a0\n\ -Xnoclassgc \u30af\u30e9\u30b9\u30ac\u30fc\u30d9\u30fc\u30b8\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u3092\u7121\u52b9\u5316\n\ -Xincgc \u5897\u5206\u30ac\u30fc\u30d9\u30fc\u30b8\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u3092\u7121\u52b9\u5316\n\ -Xloggc: \u30d5\u30a1\u30a4\u30eb\u306e GC \u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u4ed8\u304d\u3067\u8a18\u9332\n\ -Xbatch \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u30b3\u30f3\u30d1\u30a4\u30eb\u3092\u7121\u52b9\u5316\n\ -Xms \u521d\u671f Java \u30d2\u30fc\u30d7\u30b5\u30a4\u30ba\u3092\u8a2d\u5b9a\n\ -Xmx \u6700\u5927 Java \u30d2\u30fc\u30d7\u30b5\u30a4\u30ba\u3092\u8a2d\u5b9a\n\ -Xss Java \u30b9\u30ec\u30c3\u30c9\u30b9\u30bf\u30c3\u30af\u30b5\u30a4\u30ba\u3092\u8a2d\u5b9a\n\ -Xprof CPU \u30d7\u30ed\u30d5\u30a1\u30a4\u30ea\u30f3\u30b0\u30c7\u30fc\u30bf\u3092\u51fa\u529b\n\ -Xfuture \u4eca\u5f8c\u30c7\u30d5\u30a9\u30eb\u30c8\u3068\u3059\u308b\u6700\u3082\u53b3\u683c\u306a\u30c1\u30a7\u30c3\u30af\u3092\u6709\u52b9\u5316\n\ -Xrs Java/VM \u306e OS \u30b7\u30b0\u30ca\u30eb\u4f7f\u7528\u3092\u524a\u6e1b (\u30de\u30cb\u30e5\u30a2\u30eb\u3092\u53c2\u7167)\n\ -Xcheck:jni JNI \u95a2\u6570\u306e\u8ffd\u52a0\u30c1\u30a7\u30c3\u30af\u3092\u5b9f\u884c\n\ -Xshare:off \u5171\u6709\u30af\u30e9\u30b9\u30c7\u30fc\u30bf\u306e\u4f7f\u7528\u3092\u8a66\u884c\u3057\u306a\u3044\n\ -Xshare:auto \u53ef\u80fd\u306a\u5834\u5408\u306f\u5171\u6709\u30af\u30e9\u30b9\u30c7\u30fc\u30bf\u3092\u4f7f\u7528 (\u30c7\u30d5\u30a9\u30eb\u30c8)\n\ -Xshare:on \u5171\u6709\u30af\u30e9\u30b9\u30c7\u30fc\u30bf\u306e\u4f7f\u7528\u3092\u8981\u6c42 (\u305d\u3046\u3057\u306a\u3044\u3068\u969c\u5bb3\u304c\u767a\u751f\u3059\u308b\u5834\u5408)\n\n-X \u30aa\u30d7\u30b7\u30e7\u30f3\u306f\u975e\u6a19\u6e96\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3067\u3042\u308a\u3001\u4e88\u544a\u306a\u304f\u5909\u66f4\u3055\u308c\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002\n diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_ko.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_ko.properties index 2c56f83cca6..ef3ae358639 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_ko.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_ko.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ \uae30\ubcf8 VM\uc740 {0}\uc784 java.launcher.ergo.message2 =\ \uadf8 \uc774\uc720\ub294 \uc11c\ubc84 \ud074\ub798\uc2a4 \uc2dc\uc2a4\ud15c\uc5d0\uc11c \uc2e4\ud589 \uc911\uc774\uae30 \ub54c\ubb38\uc785\ub2c8\ub2e4.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp <\ub514\ub809\ud1a0\ub9ac \ubc0f zip/jar \ud30c\uc77c\uc758 \ud074\ub798\uc2a4 \uac80\uc0c9 \uacbd\ub85c>\n\ -classpath <\ub514\ub809\ud1a0\ub9ac \ubc0f zip/jar \ud30c\uc77c\uc758 \ud074\ub798\uc2a4 \uac80\uc0c9 \uacbd\ub85c>\n\ \ud074\ub798\uc2a4 \ud30c\uc77c\uc744 \uac80\uc0c9\ud558\uae30 \uc704\ud55c \ub514\ub809\ud1a0\ub9ac, JAR \uc544\uce74\uc774\ube0c \ubc0f\n\ ZIP \uc544\uce74\uc774\ube0c\uc758 {0} \uad6c\ubd84\ub41c \ubaa9\ub85d\uc785\ub2c8\ub2e4.\n\ -D=\n\ \uc2dc\uc2a4\ud15c \ub4f1\ub85d \uc815\ubcf4 \uc124\uc815\n\ -verbose[:class|gc|jni]\n\ \ucd94\uac00 \ucd9c\ub825 \uc0ac\uc6a9\n\ -version \uc81c\ud488 \ubc84\uc804\uc744 \uc778\uc1c4\ud558\uace0 \uc885\ub8cc\n\ -version:\n\ \uc2e4\ud589\ud558\ub824\uba74 \uc9c0\uc815\ud55c \ubc84\uc804 \ud544\uc694\n\ -showversion \uc81c\ud488 \ubc84\uc804\uc744 \uc778\uc1c4\ud558\uace0 \uacc4\uc18d\n\ -jre-restrict-search | -jre-no-restrict-search\n\ \ubc84\uc804 \uac80\uc0c9\uc5d0\uc11c \uc0ac\uc6a9\uc790 \uac1c\uc778 JRE \ud3ec\ud568/\uc81c\uc678\n\ -? -help \uc774 \ub3c4\uc6c0\ub9d0 \uba54\uc2dc\uc9c0 \uc778\uc1c4\n\ -X \ube44\ud45c\uc900 \uc635\uc158\uc5d0 \ub300\ud55c \ub3c4\uc6c0\ub9d0 \uc778\uc1c4\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ \uc9c0\uc815\ud55c \uc815\ubc00\ub3c4\uc758 \uba85\uc81c \uc0ac\uc6a9\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ \uc9c0\uc815\ud55c \uc815\ubc00\ub3c4\uc758 \uba85\uc81c \uc0ac\uc6a9 \uc548 \ud568\n\ -esa | -enablesystemassertions\n\ \uc2dc\uc2a4\ud15c \uba85\uc81c \uc0ac\uc6a9\n\ -dsa | -disablesystemassertions\n\ \uc2dc\uc2a4\ud15c \uba85\uc81c \uc0ac\uc6a9 \uc548 \ud568\n\ -agentlib:[=]\n\ \uc6d0\uc2dc \uc5d0\uc774\uc804\ud2b8 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub85c\ub4dc, \uc608: -agentlib:hprof\n\ \ucc38\uc870: -agentlib:jdwp=help \ubc0f -agentlib:hprof=help\n\ -agentpath:[=]\n\ \uc804\uccb4 \uacbd\ub85c \uc774\ub984\uc73c\ub85c \uc6d0\uc2dc \uc5d0\uc774\uc804\ud2b8 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub85c\ub4dc\n\ -javaagent:[=]\n\ Java \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4 \uc5d0\uc774\uc804\ud2b8 \ub85c\ub4dc, java.lang.instrument \ucc38\uc870\n\ -splash:\n\ \uc9c0\uc815\ud55c \uc774\ubbf8\uc9c0\uc758 \uc2a4\ud50c\ub798\uc2dc \ud654\uba74 \ud45c\uc2dc\n\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 http://java.sun.com/javase/reference\ub97c \ucc38\uc870\ud558\uc2ed\uc2dc\uc624. +java.launcher.opt.footer =\ -cp <\ub514\ub809\ud1a0\ub9ac \ubc0f zip/jar \ud30c\uc77c\uc758 \ud074\ub798\uc2a4 \uac80\uc0c9 \uacbd\ub85c>\n\ -classpath <\ub514\ub809\ud1a0\ub9ac \ubc0f zip/jar \ud30c\uc77c\uc758 \ud074\ub798\uc2a4 \uac80\uc0c9 \uacbd\ub85c>\n\ \ud074\ub798\uc2a4 \ud30c\uc77c\uc744 \uac80\uc0c9\ud558\uae30 \uc704\ud55c \ub514\ub809\ud1a0\ub9ac, JAR \uc544\uce74\uc774\ube0c \ubc0f\n\ ZIP \uc544\uce74\uc774\ube0c\uc758 {0} \uad6c\ubd84\ub41c \ubaa9\ub85d\uc785\ub2c8\ub2e4.\n\ -D=\n\ \uc2dc\uc2a4\ud15c \ub4f1\ub85d \uc815\ubcf4 \uc124\uc815\n\ -verbose[:class|gc|jni]\n\ \ucd94\uac00 \ucd9c\ub825 \uc0ac\uc6a9\n\ -version \uc81c\ud488 \ubc84\uc804\uc744 \uc778\uc1c4\ud558\uace0 \uc885\ub8cc\n\ -version:\n\ \uc2e4\ud589\ud558\ub824\uba74 \uc9c0\uc815\ud55c \ubc84\uc804 \ud544\uc694\n\ -showversion \uc81c\ud488 \ubc84\uc804\uc744 \uc778\uc1c4\ud558\uace0 \uacc4\uc18d\n\ -jre-restrict-search | -no-jre-restrict-search\n\ \ubc84\uc804 \uac80\uc0c9\uc5d0\uc11c \uc0ac\uc6a9\uc790 \uac1c\uc778 JRE \ud3ec\ud568/\uc81c\uc678\n\ -? -help \uc774 \ub3c4\uc6c0\ub9d0 \uba54\uc2dc\uc9c0 \uc778\uc1c4\n\ -X \ube44\ud45c\uc900 \uc635\uc158\uc5d0 \ub300\ud55c \ub3c4\uc6c0\ub9d0 \uc778\uc1c4\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ \uc9c0\uc815\ud55c \uc815\ubc00\ub3c4\uc758 \uba85\uc81c \uc0ac\uc6a9\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ \uc9c0\uc815\ud55c \uc815\ubc00\ub3c4\uc758 \uba85\uc81c \uc0ac\uc6a9 \uc548 \ud568\n\ -esa | -enablesystemassertions\n\ \uc2dc\uc2a4\ud15c \uba85\uc81c \uc0ac\uc6a9\n\ -dsa | -disablesystemassertions\n\ \uc2dc\uc2a4\ud15c \uba85\uc81c \uc0ac\uc6a9 \uc548 \ud568\n\ -agentlib:[=]\n\ \uc6d0\uc2dc \uc5d0\uc774\uc804\ud2b8 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub85c\ub4dc, \uc608: -agentlib:hprof\n\ \ucc38\uc870: -agentlib:jdwp=help \ubc0f -agentlib:hprof=help\n\ -agentpath:[=]\n\ \uc804\uccb4 \uacbd\ub85c \uc774\ub984\uc73c\ub85c \uc6d0\uc2dc \uc5d0\uc774\uc804\ud2b8 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub85c\ub4dc\n\ -javaagent:[=]\n\ Java \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4 \uc5d0\uc774\uc804\ud2b8 \ub85c\ub4dc, java.lang.instrument \ucc38\uc870\n\ -splash:\n\ \uc9c0\uc815\ud55c \uc774\ubbf8\uc9c0\uc758 \uc2a4\ud50c\ub798\uc2dc \ud654\uba74 \ud45c\uc2dc\n\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 http://java.sun.com/javase/reference\ub97c \ucc38\uc870\ud558\uc2ed\uc2dc\uc624. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed \ud63c\ud569 \ubaa8\ub4dc \uc2e4\ud589(\uae30\ubcf8\uac12)\n\ -Xint \ud574\uc11d\ub41c \ubaa8\ub4dc \uc2e4\ud589 \uc804\uc6a9\n\ -Xbootclasspath:\n\ \ubd80\ud2b8\uc2a4\ud2b8\ub7a9 \ud074\ub798\uc2a4\uc640 \uc790\uc6d0\uc758 \uac80\uc0c9 \uacbd\ub85c \uc124\uc815\n\ -Xbootclasspath/a:\n\ \ubd80\ud2b8\uc2a4\ud2b8\ub7a9 \ud074\ub798\uc2a4 \uacbd\ub85c \ub05d\uc5d0 \ucd94\uac00\n\ -Xbootclasspath/p:\n\ \ubd80\ud2b8\uc2a4\ud2b8\ub7a9 \ud074\ub798\uc2a4 \uacbd\ub85c \uc55e\uc5d0 \ucd94\uac00\n\ -Xnoclassgc \ud074\ub798\uc2a4 \uac00\ube44\uc9c0 \uceec\ub809\uc158 \uc0ac\uc6a9 \uc548 \ud568\n\ -Xincgc \uc99d\ubd84 \uac00\ube44\uc9c0 \uceec\ub809\uc158 \uc0ac\uc6a9\n\ -Xloggc: GC \uc0c1\ud0dc\ub97c \ud0c0\uc784 \uc2a4\ud0ec\ud504\uc640 \ud568\uaed8 \ud30c\uc77c\uc5d0 \ub85c\uadf8\n\ -Xbatch \ubc31\uadf8\ub77c\uc6b4\ub4dc \ucef4\ud30c\uc77c \uc0ac\uc6a9 \uc548 \ud568\n\ -Xms \ucd08\uae30 Java \ud799 \ud06c\uae30 \uc124\uc815\n\ -Xmx \ucd5c\ub300 Java \ud799 \ud06c\uae30 \uc124\uc815\n\ -Xss java \uc2a4\ub808\ub4dc \uc2a4\ud0dd \ud06c\uae30 \uc124\uc815\n\ -Xprof cpu \ud504\ub85c\ud30c\uc77c\ub9c1 \ub370\uc774\ud130 \ucd9c\ub825\n\ -Xfuture \ubbf8\ub798 \uae30\ubcf8\uac12\uc744 \uc608\uce21\ud558\uc5ec \uac00\uc7a5 \uc5c4\uaca9\ud55c \uac80\uc0ac \uc0ac\uc6a9\n\ -Xrs Java/VM\uc5d0 \uc758\ud55c OS \uc2e0\ud638 \uc0ac\uc6a9 \uac10\uc18c(\uc124\uba85\uc11c \ucc38\uc870)\n\ -Xcheck:jni JNI \uae30\ub2a5\uc5d0 \ub300\ud55c \ucd94\uac00\uc801\uc778 \uac80\uc0ac \uc218\ud589\n\ -Xshare:off \uacf5\uc720\ub41c \ud074\ub798\uc2a4 \ub370\uc774\ud130\uc758 \uc0ac\uc6a9\uc744 \uc2dc\ub3c4\ud558\uc9c0 \uc54a\uc74c\n\ -Xshare:auto \uac00\ub2a5\ud55c \uacbd\uc6b0 \uacf5\uc720\ub41c \ud074\ub798\uc2a4 \ub370\uc774\ud130 \uc0ac\uc6a9(\uae30\ubcf8\uac12)\n\ -Xshare:on \uacf5\uc720\ub41c \ud074\ub798\uc2a4 \ub370\uc774\ud130\ub97c \uc0ac\uc6a9\ud574\uc57c \ud558\uba70 \uadf8\ub807\uc9c0 \uc54a\uc73c\uba74 \uc2e4\ud328.\n\n-X \uc635\uc158\uc740 \ud45c\uc900\uc774 \uc544\ub2c8\uba70 \uc54c\ub9bc \uc5c6\uc774 \ubcc0\uacbd\ub420 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_sv.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_sv.properties index 21f20ad1f0e..95b3ba28db4 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_sv.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_sv.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ Standard-VM \u00e4r {0} java.launcher.ergo.message2 =\ eftersom du k\u00f6r p\u00e5 en dator med server-klass.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp \n\ -classpath \n\ en med {0} avgr\u00e4nsad lista \u00f6ver kataloger, JAR-arkiv\n\ och ZIP-arkiv f\u00f6r s\u00f6kning efter klassfiler.\n\ -D=\n\ ange en systemegenskap\n\ -verbose[:klass|gc|jni]\n\ visa mer text\n\ -version skriv ut produktversionen och avsluta\n\ -version:\n\ kr\u00e4ver den angivna versionen f\u00f6r att kunna k\u00f6ras\n\ -showversion skriv ut produktversion och forts\u00e4tt\n\ -jre-restrict-search | -jre-no-restrict-search\n\ inkludera/exkludera anv\u00e4ndarens privata JRE-filer i versionss\u00f6kningen\n\ -? -help skriver ut det h\u00e4r hj\u00e4lpmeddelandet\n\ -X skriv ut hj\u00e4lp f\u00f6r alternativ som inte \u00e4r standard\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ aktivera bekr\u00e4ftelser med angiven precision\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ inaktivera bekr\u00e4ftelser med angiven precision\n\ -esa | -enablesystemassertions\n\ aktivera systembekr\u00e4ftelser\n\ -dsa | -disablesystemassertions\n\ inaktivera systembekr\u00e4ftelser\n\ -agentlib:[=]\n\ l\u00e4s in det interna agentbiblioteket , t.ex. -agentlib:hprof\n\ se \u00e4ven, -agentlib:jdwp=help och -agentlib:hprof=help\n\ -agentpath:[=]\n\ l\u00e4s in internt agentbibliotek utifr\u00e5n fullst\u00e4ndig s\u00f6kv\u00e4g\n\ -javaagent:[=]\n\ l\u00e4s in agenten f\u00f6r programmeringsspr\u00e5ket Java, se java.lang.instrument\n\ -splash:\n\ visa v\u00e4lkomstf\u00f6nster med angiven bild\nMer information finns p\u00e5 http://java.sun.com/javase/reference. +java.launcher.opt.footer =\ -cp \n\ -classpath \n\ en med {0} avgr\u00e4nsad lista \u00f6ver kataloger, JAR-arkiv\n\ och ZIP-arkiv f\u00f6r s\u00f6kning efter klassfiler.\n\ -D=\n\ ange en systemegenskap\n\ -verbose[:klass|gc|jni]\n\ visa mer text\n\ -version skriv ut produktversionen och avsluta\n\ -version:\n\ kr\u00e4ver den angivna versionen f\u00f6r att kunna k\u00f6ras\n\ -showversion skriv ut produktversion och forts\u00e4tt\n\ -jre-restrict-search | -no-jre-restrict-search\n\ inkludera/exkludera anv\u00e4ndarens privata JRE-filer i versionss\u00f6kningen\n\ -? -help skriver ut det h\u00e4r hj\u00e4lpmeddelandet\n\ -X skriv ut hj\u00e4lp f\u00f6r alternativ som inte \u00e4r standard\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ aktivera bekr\u00e4ftelser med angiven precision\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ inaktivera bekr\u00e4ftelser med angiven precision\n\ -esa | -enablesystemassertions\n\ aktivera systembekr\u00e4ftelser\n\ -dsa | -disablesystemassertions\n\ inaktivera systembekr\u00e4ftelser\n\ -agentlib:[=]\n\ l\u00e4s in det interna agentbiblioteket , t.ex. -agentlib:hprof\n\ se \u00e4ven, -agentlib:jdwp=help och -agentlib:hprof=help\n\ -agentpath:[=]\n\ l\u00e4s in internt agentbibliotek utifr\u00e5n fullst\u00e4ndig s\u00f6kv\u00e4g\n\ -javaagent:[=]\n\ l\u00e4s in agenten f\u00f6r programmeringsspr\u00e5ket Java, se java.lang.instrument\n\ -splash:\n\ visa v\u00e4lkomstf\u00f6nster med angiven bild\nMer information finns p\u00e5 http://java.sun.com/javase/reference. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed k\u00f6rning i blandat l\u00e4ge (standard)\n\ -Xint endast k\u00f6rning i tolkat l\u00e4ge\n\ -Xbootclasspath:\n\ ange s\u00f6kv\u00e4g f\u00f6r bootstrap-klasser och -resurser\n\ -Xbootclasspath/a:\n\ l\u00e4gg till p\u00e5 slutet av s\u00f6kv\u00e4gen till bootstrap-klassen\n\ -Xbootclasspath/p:\n\ l\u00e4gg till i b\u00f6rjan av s\u00f6kv\u00e4gen till bootstrap-klassen\n\ -Xnoclassgc inaktivera skr\u00e4pinsamling f\u00f6r klass\n\ -Xincgc aktivera inkrementell skr\u00e4pinsaming\n\ -Xloggc: logga GC-status till en fil med tidsst\u00e4mpel\n\ -Xbatch inaktivera kompilering i bakgrunden\n\ -Xms st\u00e4ll in ursprunglig heapstorlek f\u00f6r Java\n\ -Xmx st\u00e4ll in st\u00f6rsta heapstorlek f\u00f6r Java\n\ -Xss st\u00e4ll in tr\u00e5dstackens storlek f\u00f6r Java\n\ -Xprof visa profileringsdata om processorn\n\ -Xfuture aktivera de mest rigor\u00f6sa kontrollerna och f\u00f6regrip framtida standardl\u00e4ge\n\ -Xrs minska anv\u00e4ndningen av signaler fr\u00e5n operativsystemet i Java/VM (mer information finns i dokumentationen)\n\ -Xcheck:jni utf\u00f6r ytterligare kontroller f\u00f6r JNI-funktioner\n\ -Xshare:off f\u00f6rs\u00f6k inte att anv\u00e4nda delade klassdata\n\ -Xshare:auto anv\u00e4nd om m\u00f6jligt delade klassdata (standard)\n\ -Xshare:on kr\u00e4v att delade klassdata anv\u00e4nds, skicka fel om s\u00e5 inte \u00e4r fallet.\n\n -X-alternativen betraktas inte som standard och kan \u00e4ndras utan att detta meddelas.\n diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties index e7b0352d0d7..55b5a06feb5 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ \u9ed8\u8ba4\u7684 VM \u4e3a {0 java.launcher.ergo.message2 =\ \u56e0\u4e3a\u60a8\u662f\u5728\u670d\u52a1\u5668\u7c7b\u8ba1\u7b97\u673a\u4e0a\u8fd0\u884c\u3002\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp <\u76ee\u5f55\u548c zip/jar \u6587\u4ef6\u7684\u7c7b\u641c\u7d22\u8def\u5f84>\n\ -classpath <\u76ee\u5f55\u548c zip/jar \u6587\u4ef6\u7684\u7c7b\u641c\u7d22\u8def\u5f84>\n\ \u4e00\u4e2a\u4ee5 {0} \u5206\u9694\u7684\u76ee\u5f55\u3001JAR \u5f52\u6863\u6587\u4ef6\n\ \u548c ZIP \u5f52\u6863\u6587\u4ef6\u7684\u5217\u8868\uff0c\u7528\u4e8e\u641c\u7d22\u7c7b\u6587\u4ef6\u3002\n\ -D=\n\ \u8bbe\u7f6e\u7cfb\u7edf\u5c5e\u6027\n\ -verbose[:class|gc|jni]\n\ \u542f\u7528\u8be6\u7ec6\u8f93\u51fa\n\ -version \u663e\u793a\u4ea7\u54c1\u7248\u672c\u5e76\u9000\u51fa\n\ -version:\n\ \u8981\u6c42\u8fd0\u884c\u6307\u5b9a\u7684\u7248\u672c\n\ -showversion \u663e\u793a\u4ea7\u54c1\u7248\u672c\u5e76\u7ee7\u7eed\n\ -jre-restrict-search | -jre-no-restrict-search\n\ \u5728\u7248\u672c\u641c\u7d22\u4e2d\u5305\u62ec/\u4e0d\u5305\u62ec\u7528\u6237\u79c1\u6709 JRE\n\ -? -help \u663e\u793a\u6b64\u5e2e\u52a9\u6d88\u606f\n\ -X \u663e\u793a\u6709\u5173\u975e\u6807\u51c6\u9009\u9879\u7684\u5e2e\u52a9\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ \u542f\u7528\u6307\u5b9a\u7c92\u5ea6\u7684\u65ad\u8a00\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ \u7981\u7528\u6307\u5b9a\u7c92\u5ea6\u7684\u65ad\u8a00\n\ -esa | -enablesystemassertions\n\ \u542f\u7528\u7cfb\u7edf\u65ad\u8a00\n\ -dsa | -disablesystemassertions\n\ \u7981\u7528\u7cfb\u7edf\u65ad\u8a00\n\ -agentlib:[=]\n\ \u88c5\u5165\u672c\u673a\u4ee3\u7406\u5e93 \uff0c\u4f8b\u5982\uff1a-agentlib:hprof\n\ \u53e6\u8bf7\u53c2\u89c1 -agentlib:jdwp=help \u548c -agentlib:hprof=help\n\ -agentpath:[=]\n\ \u4ee5\u5168\u8def\u5f84\u540d\u88c5\u5165\u672c\u673a\u4ee3\u7406\u5e93\n\ -javaagent:[=]\n\ \u88c5\u5165 Java \u7f16\u7a0b\u8bed\u8a00\u4ee3\u7406\uff0c\u8bf7\u53c2\u89c1 java.lang.instrument\n\ -splash:\n\ \u4f7f\u7528\u6307\u5b9a\u56fe\u50cf\u663e\u793a\u95ea\u73b0\u5c4f\u5e55\n\u6709\u5173\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u89c1 http://java.sun.com/javase/reference\u3002 +java.launcher.opt.footer =\ -cp <\u76ee\u5f55\u548c zip/jar \u6587\u4ef6\u7684\u7c7b\u641c\u7d22\u8def\u5f84>\n\ -classpath <\u76ee\u5f55\u548c zip/jar \u6587\u4ef6\u7684\u7c7b\u641c\u7d22\u8def\u5f84>\n\ \u4e00\u4e2a\u4ee5 {0} \u5206\u9694\u7684\u76ee\u5f55\u3001JAR \u5f52\u6863\u6587\u4ef6\n\ \u548c ZIP \u5f52\u6863\u6587\u4ef6\u7684\u5217\u8868\uff0c\u7528\u4e8e\u641c\u7d22\u7c7b\u6587\u4ef6\u3002\n\ -D=\n\ \u8bbe\u7f6e\u7cfb\u7edf\u5c5e\u6027\n\ -verbose[:class|gc|jni]\n\ \u542f\u7528\u8be6\u7ec6\u8f93\u51fa\n\ -version \u663e\u793a\u4ea7\u54c1\u7248\u672c\u5e76\u9000\u51fa\n\ -version:\n\ \u8981\u6c42\u8fd0\u884c\u6307\u5b9a\u7684\u7248\u672c\n\ -showversion \u663e\u793a\u4ea7\u54c1\u7248\u672c\u5e76\u7ee7\u7eed\n\ -jre-restrict-search | -no-jre-restrict-search\n\ \u5728\u7248\u672c\u641c\u7d22\u4e2d\u5305\u62ec/\u4e0d\u5305\u62ec\u7528\u6237\u79c1\u6709 JRE\n\ -? -help \u663e\u793a\u6b64\u5e2e\u52a9\u6d88\u606f\n\ -X \u663e\u793a\u6709\u5173\u975e\u6807\u51c6\u9009\u9879\u7684\u5e2e\u52a9\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ \u542f\u7528\u6307\u5b9a\u7c92\u5ea6\u7684\u65ad\u8a00\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ \u7981\u7528\u6307\u5b9a\u7c92\u5ea6\u7684\u65ad\u8a00\n\ -esa | -enablesystemassertions\n\ \u542f\u7528\u7cfb\u7edf\u65ad\u8a00\n\ -dsa | -disablesystemassertions\n\ \u7981\u7528\u7cfb\u7edf\u65ad\u8a00\n\ -agentlib:[=]\n\ \u88c5\u5165\u672c\u673a\u4ee3\u7406\u5e93 \uff0c\u4f8b\u5982\uff1a-agentlib:hprof\n\ \u53e6\u8bf7\u53c2\u89c1 -agentlib:jdwp=help \u548c -agentlib:hprof=help\n\ -agentpath:[=]\n\ \u4ee5\u5168\u8def\u5f84\u540d\u88c5\u5165\u672c\u673a\u4ee3\u7406\u5e93\n\ -javaagent:[=]\n\ \u88c5\u5165 Java \u7f16\u7a0b\u8bed\u8a00\u4ee3\u7406\uff0c\u8bf7\u53c2\u89c1 java.lang.instrument\n\ -splash:\n\ \u4f7f\u7528\u6307\u5b9a\u56fe\u50cf\u663e\u793a\u95ea\u73b0\u5c4f\u5e55\n\u6709\u5173\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u89c1 http://java.sun.com/javase/reference\u3002 # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed \u6df7\u5408\u6a21\u5f0f\u6267\u884c\uff08\u9ed8\u8ba4\uff09\n\ -Xint \u4ec5\u89e3\u91ca\u6a21\u5f0f\u6267\u884c\n\ -Xbootclasspath:<\u4ee5 {0} \u5206\u9694\u7684\u76ee\u5f55\u548c zip/jar \u6587\u4ef6>\n\ \u8bbe\u7f6e\u5f15\u5bfc\u7c7b\u548c\u8d44\u6e90\u7684\u641c\u7d22\u8def\u5f84\n\ -Xbootclasspath/a:<\u4ee5 {0} \u5206\u9694\u7684\u76ee\u5f55\u548c zip/jar \u6587\u4ef6>\n\ \u9644\u52a0\u5230\u5f15\u5bfc\u7c7b\u8def\u5f84\u5c3e\u90e8\n\ -Xbootclasspath/p:<\u4ee5 {0} \u5206\u9694\u7684\u76ee\u5f55\u548c zip/jar \u6587\u4ef6>\n\ \u7f6e\u4e8e\u5f15\u5bfc\u7c7b\u8def\u5f84\u524d\u9762\n\ -Xnoclassgc \u7981\u7528\u7c7b\u5783\u573e\u6536\u96c6\n\ -Xincgc \u542f\u7528\u589e\u91cf\u5783\u573e\u6536\u96c6\n\ -Xloggc:<\u6587\u4ef6> \u5c06 GC \u72b6\u6001\u8bb0\u5f55\u5230\u4e00\u4e2a\u5e26\u6709\u65f6\u95f4\u6233\u7684\u6587\u4ef6\n\ -Xbatch \u7981\u7528\u540e\u53f0\u7f16\u8bd1\n\ -Xms<\u5927\u5c0f> \u8bbe\u7f6e\u521d\u59cb Java \u5806\u5927\u5c0f\n\ -Xmx<\u5927\u5c0f> \u8bbe\u7f6e\u6700\u5927 Java \u5806\u5927\u5c0f\n\ -Xss<\u5927\u5c0f> \u8bbe\u7f6e Java \u7ebf\u7a0b\u5806\u6808\u5927\u5c0f\n\ -Xprof \u8f93\u51fa CPU \u914d\u7f6e\u6570\u636e\n\ -Xfuture \u542f\u7528\u6700\u4e25\u683c\u7684\u68c0\u67e5\uff0c\u672a\u6765\u53ef\u80fd\u4f1a\u6210\u4e3a\u9ed8\u8ba4\u9009\u9879\n\ -Xrs \u51cf\u5c11 Java/VM \u5bf9\u64cd\u4f5c\u7cfb\u7edf\u4fe1\u53f7\u7684\u4f7f\u7528\uff08\u8bf7\u53c2\u89c1\u6587\u6863\uff09\n\ -Xcheck:jni \u9488\u5bf9 JNI \u529f\u80fd\u6267\u884c\u989d\u5916\u7684\u68c0\u67e5\n\ -Xshare:off \u4e0d\u5c1d\u8bd5\u4f7f\u7528\u5171\u4eab\u7c7b\u6570\u636e\n\ -Xshare:auto \u5982\u679c\u53ef\u80fd\u7684\u8bdd\uff0c\u4f7f\u7528\u5171\u4eab\u7c7b\u6570\u636e\uff08\u9ed8\u8ba4\uff09\n\ -Xshare:on \u8981\u6c42\u4f7f\u7528\u5171\u4eab\u7c7b\u6570\u636e\uff0c\u5426\u5219\u4f1a\u5931\u8d25\u3002\n\n-X \u9009\u9879\u662f\u975e\u6807\u51c6\u9009\u9879\uff0c\u5982\u6709\u66f4\u6539\uff0c\u6055\u4e0d\u53e6\u884c\u901a\u77e5\u3002\n diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties index a04cbe71a7a..e5b87470ede 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ \u9810\u8a2d VM \u70ba {0} java.launcher.ergo.message2 =\ \u56e0\u70ba\u60a8\u6b63\u57f7\u884c\u65bc\u4f3a\u670d\u5668\u7d1a\u7684\u6a5f\u5668\u4e0a\u3002\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp <\u76ee\u9304\u548c zip/jar \u6a94\u6848\u7684\u985e\u5225\u641c\u5c0b\u8def\u5f91>\n\ -classpath <\u76ee\u9304\u548c zip/jar \u6a94\u6848\u7684\u985e\u5225\u641c\u5c0b\u8def\u5f91>\n\ {0} \u76ee\u9304\u3001JAR \u6b78\u6a94\n\ \u548c ZIP \u6b78\u6a94\u7684\u5206\u9694\u6e05\u55ae\uff0c\u7528\u65bc\u641c\u5c0b\u985e\u5225\u6a94\u6848\u3002\n\ -D=\n\ \u8a2d\u5b9a\u7cfb\u7d71\u7279\u6027\n\ -verbose[:class|gc|jni]\n\ \u555f\u7528\u8a73\u7d30\u8f38\u51fa\n\ -version \u5217\u5370\u7522\u54c1\u7248\u672c\u4e26\u7d50\u675f\n\ -version:\n\ \u9700\u8981\u57f7\u884c\u6307\u5b9a\u7684\u7248\u672c\n\ -showversion \u5217\u5370\u7522\u54c1\u7248\u672c\u4e26\u7e7c\u7e8c\n\ -jre-restrict-search | -jre-no-restrict-search\n\ \u5728\u7248\u672c\u641c\u5c0b\u4e2d\u5305\u542b/\u6392\u9664\u4f7f\u7528\u8005\u79c1\u7528 JRE\n\ -? -help \u5217\u5370\u6b64\u8aaa\u660e\u8a0a\u606f\n\ -X \u5217\u5370\u6709\u95dc\u975e\u6a19\u6e96\u9078\u9805\u7684\u8aaa\u660e\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ \u555f\u7528\u5177\u6709\u6307\u5b9a\u9846\u7c92\u6027\u7684\u5ba3\u544a\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ \u505c\u7528\u5177\u6709\u6307\u5b9a\u9846\u7c92\u6027\u7684\u5ba3\u544a\n\ -esa | -enablesystemassertions\n\ \u555f\u7528\u7cfb\u7d71\u5ba3\u544a\n\ -dsa | -disablesystemassertions\n\ \u505c\u7528\u7cfb\u7d71\u5ba3\u544a\n\ -agentlib:[=]\n\ \u8f09\u5165\u539f\u751f\u4ee3\u7406\u7a0b\u5f0f\u7a0b\u5f0f\u5eab \uff0c\u4f8b\u5982 -agentlib:hprof\n\ \u53e6\u8acb\u53c3\u95b1 -agentlib:jdwp=help \u548c -agentlib:hprof=help\n\ -agentpath:[=]\n\ \u4f9d\u64da\u5b8c\u6574\u8def\u5f91\u540d\u7a31\u8f09\u5165\u539f\u751f\u4ee3\u7406\u7a0b\u5f0f\n\ -javaagent:[=]\n\ \u8f09\u5165 Java \u7a0b\u5f0f\u8a2d\u8a08\u8a9e\u8a00\u4ee3\u7406\u7a0b\u5f0f\uff0c\u8acb\u53c3\u95b1 java.lang.instrument\n\ -splash:\n\ \u986f\u793a\u542b\u6709\u6307\u5b9a\u5f71\u50cf\u7684\u8edf\u9ad4\u8cc7\u8a0a\u756b\u9762\n\u8acb\u53c3\u95b1 http://java.sun.com/javase/reference\uff0c\u4ee5\u53d6\u5f97\u66f4\u591a\u8a73\u7d30\u8cc7\u8a0a\u3002 +java.launcher.opt.footer =\ -cp <\u76ee\u9304\u548c zip/jar \u6a94\u6848\u7684\u985e\u5225\u641c\u5c0b\u8def\u5f91>\n\ -classpath <\u76ee\u9304\u548c zip/jar \u6a94\u6848\u7684\u985e\u5225\u641c\u5c0b\u8def\u5f91>\n\ {0} \u76ee\u9304\u3001JAR \u6b78\u6a94\n\ \u548c ZIP \u6b78\u6a94\u7684\u5206\u9694\u6e05\u55ae\uff0c\u7528\u65bc\u641c\u5c0b\u985e\u5225\u6a94\u6848\u3002\n\ -D=\n\ \u8a2d\u5b9a\u7cfb\u7d71\u7279\u6027\n\ -verbose[:class|gc|jni]\n\ \u555f\u7528\u8a73\u7d30\u8f38\u51fa\n\ -version \u5217\u5370\u7522\u54c1\u7248\u672c\u4e26\u7d50\u675f\n\ -version:\n\ \u9700\u8981\u57f7\u884c\u6307\u5b9a\u7684\u7248\u672c\n\ -showversion \u5217\u5370\u7522\u54c1\u7248\u672c\u4e26\u7e7c\u7e8c\n\ -jre-restrict-search | -no-jre-restrict-search\n\ \u5728\u7248\u672c\u641c\u5c0b\u4e2d\u5305\u542b/\u6392\u9664\u4f7f\u7528\u8005\u79c1\u7528 JRE\n\ -? -help \u5217\u5370\u6b64\u8aaa\u660e\u8a0a\u606f\n\ -X \u5217\u5370\u6709\u95dc\u975e\u6a19\u6e96\u9078\u9805\u7684\u8aaa\u660e\n\ -ea[:...|:]\n\ -enableassertions[:...|:]\n\ \u555f\u7528\u5177\u6709\u6307\u5b9a\u9846\u7c92\u6027\u7684\u5ba3\u544a\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ \u505c\u7528\u5177\u6709\u6307\u5b9a\u9846\u7c92\u6027\u7684\u5ba3\u544a\n\ -esa | -enablesystemassertions\n\ \u555f\u7528\u7cfb\u7d71\u5ba3\u544a\n\ -dsa | -disablesystemassertions\n\ \u505c\u7528\u7cfb\u7d71\u5ba3\u544a\n\ -agentlib:[=]\n\ \u8f09\u5165\u539f\u751f\u4ee3\u7406\u7a0b\u5f0f\u7a0b\u5f0f\u5eab \uff0c\u4f8b\u5982 -agentlib:hprof\n\ \u53e6\u8acb\u53c3\u95b1 -agentlib:jdwp=help \u548c -agentlib:hprof=help\n\ -agentpath:[=]\n\ \u4f9d\u64da\u5b8c\u6574\u8def\u5f91\u540d\u7a31\u8f09\u5165\u539f\u751f\u4ee3\u7406\u7a0b\u5f0f\n\ -javaagent:[=]\n\ \u8f09\u5165 Java \u7a0b\u5f0f\u8a2d\u8a08\u8a9e\u8a00\u4ee3\u7406\u7a0b\u5f0f\uff0c\u8acb\u53c3\u95b1 java.lang.instrument\n\ -splash:\n\ \u986f\u793a\u542b\u6709\u6307\u5b9a\u5f71\u50cf\u7684\u8edf\u9ad4\u8cc7\u8a0a\u756b\u9762\n\u8acb\u53c3\u95b1 http://java.sun.com/javase/reference\uff0c\u4ee5\u53d6\u5f97\u66f4\u591a\u8a73\u7d30\u8cc7\u8a0a\u3002 # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed \u57f7\u884c\u6df7\u5408\u6a21\u5f0f (\u9810\u8a2d)\n\ -Xint \u50c5\u57f7\u884c\u89e3\u8b6f\u6a21\u5f0f\n\ -Xbootclasspath:<\u4ee5 {0} \u5206\u9694\u7684\u76ee\u9304\u548c zip/jar \u6a94\u6848>\n\ \u8a2d\u5b9a\u555f\u52d5\u985e\u5225\u548c\u8cc7\u6e90\u7684\u641c\u5c0b\u8def\u5f91\n\ -Xbootclasspath/a:<\u4ee5 {0} \u5206\u9694\u7684\u76ee\u9304\u548c zip/jar \u6a94\u6848>\n\ \u9644\u52a0\u81f3\u555f\u52d5\u985e\u5225\u7684\u672b\u5c3e\n\ -Xbootclasspath/p:<\u4ee5 {0} \u5206\u9694\u7684\u76ee\u9304\u548c zip/jar \u6a94\u6848>\n\ \u524d\u7f6e\u65bc\u555f\u52d5\u985e\u5225\u8def\u5f91\u7684\u524d\u9762\n\ -Xnoclassgc \u505c\u7528\u985e\u5225\u56de\u6536\u6536\u96c6\n\ -Xincgc \u555f\u7528\u905e\u589e\u56de\u6536\u6536\u96c6\n\ -Xloggc:<\u6a94\u6848> \u4f7f\u7528\u6642\u9593\u6233\u8a18\u5c07 GC \u72c0\u614b\u8a18\u9304\u81f3\u6a94\u6848\n\ -Xbatch \u505c\u7528\u80cc\u5f71\u7de8\u8b6f\n\ -Xms<\u5927\u5c0f> \u8a2d\u5b9a\u521d\u59cb Java \u5806\u758a\u5927\u5c0f\n\ -Xmx<\u5927\u5c0f> \u8a2d\u5b9a\u6700\u5927 Java \u5806\u758a\u5927\u5c0f\n\ -Xss<\u5927\u5c0f> \u8a2d\u5b9a java \u57f7\u884c\u7dd2\u5806\u758a\u5927\u5c0f\n\ -Xprof \u8f38\u51fa cpu \u8a2d\u5b9a\u6a94\u8cc7\u6599\n\ -Xfuture \u555f\u7528\u6700\u56b4\u683c\u7684\u6aa2\u67e5\uff0c\u9810\u671f\u672a\u4f86\u9810\u8a2d\u503c\n\ -Xrs \u964d\u4f4e Java/VM \u7684 OS \u8a0a\u865f\u4f7f\u7528 (\u8acb\u53c3\u95b1\u6587\u4ef6)\n\ -Xcheck:jni \u5c0d JNI \u529f\u80fd\u57f7\u884c\u5176\u4ed6\u6aa2\u67e5\n\ -Xshare:off \u4e0d\u5617\u8a66\u4f7f\u7528\u5171\u7528\u985e\u5225\u8cc7\u6599\n\ -Xshare:auto \u5982\u53ef\u80fd\uff0c\u4f7f\u7528\u5171\u7528\u985e\u5225\u8cc7\u6599 (\u9810\u8a2d)\n\ -Xshare:on \u9700\u8981\u4f7f\u7528\u5171\u7528\u985e\u5225\u8cc7\u6599\uff0c\u5426\u5247\u6703\u5931\u6557\u3002\n\n-X \u9078\u9805\u70ba\u975e\u6a19\u6e96\u9078\u9805\uff0c\u53ef\u80fd\u6703\u8b8a\u66f4\uff0c\u6055\u4e0d\u53e6\u884c\u901a\u77e5\u3002\n diff --git a/jdk/src/share/classes/sun/misc/BootClassLoaderHook.java b/jdk/src/share/classes/sun/misc/BootClassLoaderHook.java index a4c5e231dd7..970ad5ceacc 100644 --- a/jdk/src/share/classes/sun/misc/BootClassLoaderHook.java +++ b/jdk/src/share/classes/sun/misc/BootClassLoaderHook.java @@ -27,6 +27,8 @@ package sun.misc; import java.io.File; import java.io.IOException; +import java.net.URLStreamHandlerFactory; +import sun.misc.URLClassPath; /** * BootClassLoaderHook defines an interface for a hook to inject @@ -94,20 +96,6 @@ public abstract class BootClassLoaderHook { } } - private static final File[] EMPTY_FILE_ARRAY = new File[0]; - - /** - * Returns bootstrap class paths added by the hook. - */ - public static File[] getBootstrapPaths() { - BootClassLoaderHook hook = getHook(); - if (hook != null) { - return hook.getAdditionalBootstrapPaths(); - } else { - return EMPTY_FILE_ARRAY; - } - } - /** * Returns a pathname of a JAR or class that the hook loads * per this loadClass request; or null. @@ -133,10 +121,13 @@ public abstract class BootClassLoaderHook { public abstract boolean loadLibrary(String libname); /** - * Returns additional boot class paths added by the hook that - * should be searched by the boot class loader. + * Returns a bootstrap class path constructed by the hook. + * + * @param bcp VM's bootstrap class path + * @param factory Launcher's URL stream handler */ - public abstract File[] getAdditionalBootstrapPaths(); + public abstract URLClassPath getBootstrapClassPath(URLClassPath bcp, + URLStreamHandlerFactory factory); /** * Returns true if the current thread is in the process of doing diff --git a/jdk/src/share/classes/sun/misc/Launcher.java b/jdk/src/share/classes/sun/misc/Launcher.java index 2a8397d4886..3d7c5e3cc69 100644 --- a/jdk/src/share/classes/sun/misc/Launcher.java +++ b/jdk/src/share/classes/sun/misc/Launcher.java @@ -47,7 +47,6 @@ import java.security.Permissions; import java.security.Permission; import java.security.ProtectionDomain; import java.security.CodeSource; -import sun.security.action.GetPropertyAction; import sun.security.util.SecurityConstants; import sun.net.www.ParseUtil; @@ -57,6 +56,8 @@ Launcher */ public class Launcher { private static URLStreamHandlerFactory factory = new Factory(); private static Launcher launcher = new Launcher(); + private static String bootClassPath = + System.getProperty("sun.boot.class.path"); public static Launcher getLauncher() { return launcher; @@ -227,7 +228,8 @@ public class Launcher { File dir = new File(urls[i].getPath()).getParentFile(); if (dir != null && !dir.equals(prevDir)) { // Look in architecture-specific subdirectory first - String arch = System.getProperty("os.arch"); + // Read from the saved system properties to avoid deadlock + String arch = VM.getSavedProperty("os.arch"); if (arch != null) { File file = new File(new File(dir, arch), name); if (file.exists()) { @@ -377,19 +379,15 @@ public class Launcher { } } - private static URLClassPath bootstrapClassPath; - - public static synchronized URLClassPath getBootstrapClassPath() { - if (bootstrapClassPath == null) { - String prop = AccessController.doPrivileged( - new GetPropertyAction("sun.boot.class.path")); + private static class BootClassPathHolder { + static final URLClassPath bcp; + static { URL[] urls; - if (prop != null) { - final String path = prop; + if (bootClassPath != null) { urls = AccessController.doPrivileged( new PrivilegedAction() { public URL[] run() { - File[] classPath = getClassPath(path); + File[] classPath = getClassPath(bootClassPath); int len = classPath.length; Set seenDirs = new HashSet(); for (int i = 0; i < len; i++) { @@ -410,25 +408,16 @@ public class Launcher { } else { urls = new URL[0]; } - - bootstrapClassPath = new URLClassPath(urls, factory); - final File[] additionalBootStrapPaths = - BootClassLoaderHook.getBootstrapPaths(); - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - for (int i=0; i -1) - directMemory = l; - } - } - return directMemory; } + // User-controllable flag that determines if direct buffers should be page + // aligned. The "-XX:+PageAlignDirectMemory" option can be used to force + // buffers, allocated by ByteBuffer.allocateDirect, to be page aligned. + private static boolean pageAlignDirectMemory; + + // Returns {@code true} if the direct buffers should be page aligned. This + // variable is initialized by saveAndRemoveProperties. + public static boolean isDirectMemoryPageAligned() { + return pageAlignDirectMemory; + } + // A user-settable boolean to determine whether ClassLoader.loadClass should // accept array syntax. This value may be changed during VM initialization // via the system property "sun.lang.ClassLoader.allowArraySyntax". @@ -212,28 +201,89 @@ public class VM { private static boolean defaultAllowArraySyntax = false; private static boolean allowArraySyntax = defaultAllowArraySyntax; - // If this method is invoked during VM initialization, it initializes the - // allowArraySyntax boolean based on the value of the system property + // The allowArraySyntax boolean is initialized during system initialization + // in the saveAndRemoveProperties method. + // + // It is initialized based on the value of the system property // "sun.lang.ClassLoader.allowArraySyntax". If the system property is not // provided, the default for 1.5 is "true". In 1.6, the default will be // "false". If the system property is provided, then the value of // allowArraySyntax will be equal to "true" if Boolean.parseBoolean() // returns "true". Otherwise, the field will be set to "false". // - // If this method is invoked after the VM is booted, it returns the - // allowArraySyntax boolean set during initialization. - // public static boolean allowArraySyntax() { - if (!booted) { - String s - = System.getProperty("sun.lang.ClassLoader.allowArraySyntax"); - allowArraySyntax = (s == null - ? defaultAllowArraySyntax - : Boolean.parseBoolean(s)); - } return allowArraySyntax; } + /** + * Returns the system property of the specified key saved at + * system initialization time. This method should only be used + * for the system properties that are not changed during runtime. + * It accesses a private copy of the system properties so + * that user's locking of the system properties object will not + * cause the library to deadlock. + * + * Note that the saved system properties do not include + * the ones set by sun.misc.Version.init(). + * + */ + public static String getSavedProperty(String key) { + if (savedProps.isEmpty()) + throw new IllegalStateException("Should be non-empty if initialized"); + + return savedProps.getProperty(key); + } + + private static final Properties savedProps = new Properties(); + + // Save a private copy of the system properties and remove + // the system properties that are not intended for public access. + // + // This method can only be invoked during system initialization. + public static void saveAndRemoveProperties(Properties props) { + if (booted) + throw new IllegalStateException("System initialization has completed"); + + savedProps.putAll(props); + + // Set the maximum amount of direct memory. This value is controlled + // by the vm option -XX:MaxDirectMemorySize=. + // The maximum amount of allocatable direct buffer memory (in bytes) + // from the system property sun.nio.MaxDirectMemorySize set by the VM. + // The system property will be removed. + String s = (String)props.remove("sun.nio.MaxDirectMemorySize"); + if (s != null) { + if (s.equals("-1")) { + // -XX:MaxDirectMemorySize not given, take default + directMemory = Runtime.getRuntime().maxMemory(); + } else { + long l = Long.parseLong(s); + if (l > -1) + directMemory = l; + } + } + + // Check if direct buffers should be page aligned + s = (String)props.remove("sun.nio.PageAlignDirectMemory"); + if ("true".equals(s)) + pageAlignDirectMemory = true; + + // Set a boolean to determine whether ClassLoader.loadClass accepts + // array syntax. This value is controlled by the system property + // "sun.lang.ClassLoader.allowArraySyntax". + s = props.getProperty("sun.lang.ClassLoader.allowArraySyntax"); + allowArraySyntax = (s == null + ? defaultAllowArraySyntax + : Boolean.parseBoolean(s)); + + // Remove other private system properties + // used by java.lang.Integer.IntegerCache + props.remove("java.lang.Integer.IntegerCache.high"); + + // used by java.util.zip.ZipFile + props.remove("sun.zip.disableMemoryMapping"); + } + // Initialize any miscellenous operating system settings that need to be // set for the class libraries. // diff --git a/jdk/src/share/classes/sun/net/InetAddressCachePolicy.java b/jdk/src/share/classes/sun/net/InetAddressCachePolicy.java index 7b48f5765ad..a506a944e28 100644 --- a/jdk/src/share/classes/sun/net/InetAddressCachePolicy.java +++ b/jdk/src/share/classes/sun/net/InetAddressCachePolicy.java @@ -25,7 +25,6 @@ package sun.net; -import java.net.InetAddress; import java.security.PrivilegedAction; import java.security.Security; @@ -57,7 +56,7 @@ public final class InetAddressCachePolicy { * caching. For security reasons, this caching is made forever when * a security manager is set. */ - private static int cachePolicy; + private static int cachePolicy = FOREVER; /* The Java-level namelookup cache policy for negative lookups: * @@ -67,31 +66,24 @@ public final class InetAddressCachePolicy { * default value is 0. It can be set to some other value for * performance reasons. */ - private static int negativeCachePolicy; + private static int negativeCachePolicy = NEVER; /* * Whether or not the cache policy for successful lookups was set * using a property (cmd line). */ - private static boolean set = false; + private static boolean propertySet; /* * Whether or not the cache policy for negative lookups was set * using a property (cmd line). */ - private static boolean negativeSet = false; + private static boolean propertyNegativeSet; /* * Initialize */ static { - - set = false; - negativeSet = false; - - cachePolicy = FOREVER; - negativeCachePolicy = 0; - Integer tmp = null; try { @@ -110,7 +102,7 @@ public final class InetAddressCachePolicy { if (cachePolicy < 0) { cachePolicy = FOREVER; } - set = true; + propertySet = true; } else { tmp = java.security.AccessController.doPrivileged (new sun.security.action.GetIntegerAction(cachePolicyPropFallback)); @@ -119,7 +111,14 @@ public final class InetAddressCachePolicy { if (cachePolicy < 0) { cachePolicy = FOREVER; } - set = true; + propertySet = true; + } else { + /* No properties defined for positive caching. If there is no + * security manager then use the default positive cache value. + */ + if (System.getSecurityManager() == null) { + cachePolicy = DEFAULT_POSITIVE; + } } } @@ -140,7 +139,7 @@ public final class InetAddressCachePolicy { if (negativeCachePolicy < 0) { negativeCachePolicy = FOREVER; } - negativeSet = true; + propertyNegativeSet = true; } else { tmp = java.security.AccessController.doPrivileged (new sun.security.action.GetIntegerAction(negativeCachePolicyPropFallback)); @@ -149,17 +148,13 @@ public final class InetAddressCachePolicy { if (negativeCachePolicy < 0) { negativeCachePolicy = FOREVER; } - negativeSet = true; + propertyNegativeSet = true; } } } public static synchronized int get() { - if (!set && System.getSecurityManager() == null) { - return DEFAULT_POSITIVE; - } else { - return cachePolicy; - } + return cachePolicy; } public static synchronized int getNegative() { @@ -174,21 +169,17 @@ public final class InetAddressCachePolicy { * should be cached */ public static synchronized void setIfNotSet(int newPolicy) { - /* * When setting the new value we may want to signal that the * cache should be flushed, though this doesn't seem strictly * necessary. */ - - if (!set) { + if (!propertySet) { checkValue(newPolicy, cachePolicy); cachePolicy = newPolicy; } - } - /** * Sets the cache policy for negative lookups if the user has not * already specified a cache policy for it using a @@ -197,14 +188,12 @@ public final class InetAddressCachePolicy { * should be cached */ public static synchronized void setNegativeIfNotSet(int newPolicy) { - /* * When setting the new value we may want to signal that the * cache should be flushed, though this doesn't seem strictly * necessary. */ - - if (!negativeSet) { + if (!propertyNegativeSet) { // Negative caching does not seem to have any security // implications. // checkValue(newPolicy, negativeCachePolicy); @@ -213,13 +202,11 @@ public final class InetAddressCachePolicy { } private static void checkValue(int newPolicy, int oldPolicy) { - /* * If malicious code gets a hold of this method, prevent * setting the cache policy to something laxer or some * invalid negative value. */ - if (newPolicy == FOREVER) return; @@ -229,7 +216,6 @@ public final class InetAddressCachePolicy { throw new SecurityException("can't make InetAddress cache more lax"); - } } } diff --git a/jdk/src/share/classes/sun/net/NetworkClient.java b/jdk/src/share/classes/sun/net/NetworkClient.java index 01322c91acc..1e88dc884c4 100644 --- a/jdk/src/share/classes/sun/net/NetworkClient.java +++ b/jdk/src/share/classes/sun/net/NetworkClient.java @@ -40,6 +40,12 @@ import java.security.PrivilegedAction; * @author Jonathan Payne */ public class NetworkClient { + /* Default value of read timeout, if not specified (infinity) */ + public static final int DEFAULT_READ_TIMEOUT = -1; + + /* Default value of connect timeout, if not specified (infinity) */ + public static final int DEFAULT_CONNECT_TIMEOUT = -1; + protected Proxy proxy = Proxy.NO_PROXY; /** Socket for communicating with server. */ protected Socket serverSocket = null; @@ -53,8 +59,8 @@ public class NetworkClient { protected static int defaultSoTimeout; protected static int defaultConnectTimeout; - protected int readTimeout = -1; - protected int connectTimeout = -1; + protected int readTimeout = DEFAULT_READ_TIMEOUT; + protected int connectTimeout = DEFAULT_CONNECT_TIMEOUT; /* Name of encoding to use for output */ protected static String encoding; @@ -71,16 +77,12 @@ public class NetworkClient { return null; } }); - if (vals[0] == 0) - defaultSoTimeout = -1; - else + if (vals[0] != 0) { defaultSoTimeout = vals[0]; - - if (vals[1] == 0) - defaultConnectTimeout = -1; - else + } + if (vals[1] != 0) { defaultConnectTimeout = vals[1]; - + } encoding = encs[0]; try { @@ -232,7 +234,23 @@ public class NetworkClient { return connectTimeout; } + /** + * Sets the read timeout. + * + * Note: Public URLConnection (and protocol specific implementations) + * protect against negative timeout values being set. This implemenation, + * and protocol specific implementations, use -1 to represent the default + * read timeout. + * + * This method may be invoked with the default timeout value when the + * protocol handler is trying to reset the timeout after doing a + * potentially blocking internal operation, e.g. cleaning up unread + * response data, buffering error stream response data, etc + */ public void setReadTimeout(int timeout) { + if (timeout == DEFAULT_READ_TIMEOUT) + timeout = defaultSoTimeout; + if (serverSocket != null && timeout >= 0) { try { serverSocket.setSoTimeout(timeout); diff --git a/jdk/src/share/classes/sun/net/www/MimeTable.java b/jdk/src/share/classes/sun/net/www/MimeTable.java index 6d21fa0fd4e..085b97505d8 100644 --- a/jdk/src/share/classes/sun/net/www/MimeTable.java +++ b/jdk/src/share/classes/sun/net/www/MimeTable.java @@ -73,29 +73,32 @@ public class MimeTable implements FileNameMap { private static final String filePreamble = "sun.net.www MIME content-types table"; private static final String fileMagic = "#" + filePreamble; - private static MimeTable defaultInstance = null; MimeTable() { load(); } + private static class DefaultInstanceHolder { + static final MimeTable defaultInstance = getDefaultInstance(); + + static MimeTable getDefaultInstance() { + return java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public MimeTable run() { + MimeTable instance = new MimeTable(); + URLConnection.setFileNameMap(instance); + return instance; + } + }); + } + } + /** * Get the single instance of this class. First use will load the * table from a data file. */ public static MimeTable getDefaultTable() { - if (defaultInstance == null) { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Void run() { - defaultInstance = new MimeTable(); - URLConnection.setFileNameMap(defaultInstance); - return null; - } - }); - } - - return defaultInstance; + return DefaultInstanceHolder.defaultInstance; } /** diff --git a/jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java index 49af37825a2..826f1afc5ee 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java @@ -46,6 +46,7 @@ import java.net.ProxySelector; import java.util.StringTokenizer; import java.util.Iterator; import java.security.Permission; +import sun.net.NetworkClient; import sun.net.www.MessageHeader; import sun.net.www.MeteredStream; import sun.net.www.URLConnection; @@ -102,11 +103,11 @@ public class FtpURLConnection extends URLConnection { static final int BIN = 2; static final int DIR = 3; int type = NONE; - /* Redefine timeouts from java.net.URLConnection as we nee -1 to mean + /* Redefine timeouts from java.net.URLConnection as we need -1 to mean * not set. This is to ensure backward compatibility. */ - private int connectTimeout = -1; - private int readTimeout = -1; + private int connectTimeout = NetworkClient.DEFAULT_CONNECT_TIMEOUT;; + private int readTimeout = NetworkClient.DEFAULT_READ_TIMEOUT;; /** * For FTP URLs we need to have a special InputStream because we diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index 56ed6a40fa3..69f12a5c601 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -359,11 +359,11 @@ public class HttpURLConnection extends java.net.HttpURLConnection { private TunnelState tunnelState = TunnelState.NONE; - /* Redefine timeouts from java.net.URLConnection as we nee -1 to mean + /* Redefine timeouts from java.net.URLConnection as we need -1 to mean * not set. This is to ensure backward compatibility. */ - private int connectTimeout = -1; - private int readTimeout = -1; + private int connectTimeout = NetworkClient.DEFAULT_CONNECT_TIMEOUT; + private int readTimeout = NetworkClient.DEFAULT_READ_TIMEOUT; /* Logging support */ private static final PlatformLogger logger = @@ -1041,9 +1041,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection { throw new ProtocolException("Server rejected operation"); } } - if (oldTimeout > 0) { - http.setReadTimeout(oldTimeout); - } + + http.setReadTimeout(oldTimeout); + responseCode = -1; responses.reset(); // Proceed diff --git a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java index 208c36789b1..6d1bed731ee 100644 --- a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java +++ b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java @@ -699,15 +699,19 @@ public class FileChannelImpl static volatile long totalSize; static volatile long totalCapacity; - private long address; - private long size; - private int cap; + private volatile long address; + private final long size; + private final int cap; + private final FileDescriptor fd; - private Unmapper(long address, long size, int cap) { + private Unmapper(long address, long size, int cap, + FileDescriptor fd) + { assert (address != 0); this.address = address; this.size = size; this.cap = cap; + this.fd = fd; synchronized (Unmapper.class) { count++; @@ -722,6 +726,15 @@ public class FileChannelImpl unmap0(address, size); address = 0; + // if this mapping has a valid file descriptor then we close it + if (fd.valid()) { + try { + nd.close(fd); + } catch (IOException ignore) { + // nothing we can do + } + } + synchronized (Unmapper.class) { count--; totalSize -= size; @@ -784,10 +797,12 @@ public class FileChannelImpl } if (size == 0) { addr = 0; + // a valid file descriptor is not required + FileDescriptor dummy = new FileDescriptor(); if ((!writable) || (imode == MAP_RO)) - return Util.newMappedByteBufferR(0, 0, null); + return Util.newMappedByteBufferR(0, 0, dummy, null); else - return Util.newMappedByteBuffer(0, 0, null); + return Util.newMappedByteBuffer(0, 0, dummy, null); } int pagePosition = (int)(position % allocationGranularity); @@ -813,14 +828,31 @@ public class FileChannelImpl } } + // On Windows, and potentially other platforms, we need an open + // file descriptor for some mapping operations. + FileDescriptor mfd; + try { + mfd = nd.duplicateForMapping(fd); + } catch (IOException ioe) { + unmap0(addr, mapSize); + throw ioe; + } + assert (IOStatus.checkAll(addr)); assert (addr % allocationGranularity == 0); int isize = (int)size; - Unmapper um = new Unmapper(addr, size + pagePosition, isize); - if ((!writable) || (imode == MAP_RO)) - return Util.newMappedByteBufferR(isize, addr + pagePosition, um); - else - return Util.newMappedByteBuffer(isize, addr + pagePosition, um); + Unmapper um = new Unmapper(addr, mapSize, isize, mfd); + if ((!writable) || (imode == MAP_RO)) { + return Util.newMappedByteBufferR(isize, + addr + pagePosition, + mfd, + um); + } else { + return Util.newMappedByteBuffer(isize, + addr + pagePosition, + mfd, + um); + } } finally { threads.remove(ti); end(IOStatus.checkAll(addr)); diff --git a/jdk/src/share/classes/sun/nio/ch/FileDispatcher.java b/jdk/src/share/classes/sun/nio/ch/FileDispatcher.java index 4e90c9944f5..0e363514414 100644 --- a/jdk/src/share/classes/sun/nio/ch/FileDispatcher.java +++ b/jdk/src/share/classes/sun/nio/ch/FileDispatcher.java @@ -45,4 +45,12 @@ abstract class FileDispatcher extends NativeDispatcher { abstract void release(FileDescriptor fd, long pos, long size) throws IOException; + + /** + * Returns a dup of fd if a file descriptor is required for + * memory-mapping operations, otherwise returns an invalid + * FileDescriptor (meaning a newly allocated FileDescriptor) + */ + abstract FileDescriptor duplicateForMapping(FileDescriptor fd) + throws IOException; } diff --git a/jdk/src/share/classes/sun/nio/ch/Util.java b/jdk/src/share/classes/sun/nio/ch/Util.java index 50d280865cd..252a03dbb36 100644 --- a/jdk/src/share/classes/sun/nio/ch/Util.java +++ b/jdk/src/share/classes/sun/nio/ch/Util.java @@ -28,6 +28,7 @@ package sun.nio.ch; import java.lang.ref.SoftReference; import java.lang.reflect.*; import java.io.IOException; +import java.io.FileDescriptor; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.*; @@ -364,6 +365,7 @@ class Util { Constructor ctor = cl.getDeclaredConstructor( new Class[] { int.class, long.class, + FileDescriptor.class, Runnable.class }); ctor.setAccessible(true); directByteBufferConstructor = ctor; @@ -381,6 +383,7 @@ class Util { } static MappedByteBuffer newMappedByteBuffer(int size, long addr, + FileDescriptor fd, Runnable unmapper) { MappedByteBuffer dbb; @@ -390,6 +393,7 @@ class Util { dbb = (MappedByteBuffer)directByteBufferConstructor.newInstance( new Object[] { new Integer(size), new Long(addr), + fd, unmapper }); } catch (InstantiationException e) { throw new InternalError(); @@ -411,6 +415,7 @@ class Util { Constructor ctor = cl.getDeclaredConstructor( new Class[] { int.class, long.class, + FileDescriptor.class, Runnable.class }); ctor.setAccessible(true); directByteBufferRConstructor = ctor; @@ -428,6 +433,7 @@ class Util { } static MappedByteBuffer newMappedByteBufferR(int size, long addr, + FileDescriptor fd, Runnable unmapper) { MappedByteBuffer dbb; @@ -437,6 +443,7 @@ class Util { dbb = (MappedByteBuffer)directByteBufferRConstructor.newInstance( new Object[] { new Integer(size), new Long(addr), + fd, unmapper }); } catch (InstantiationException e) { throw new InternalError(); diff --git a/jdk/src/share/classes/sun/security/jca/Providers.java b/jdk/src/share/classes/sun/security/jca/Providers.java index 732c9f37ee4..9e2ad0e9fa9 100644 --- a/jdk/src/share/classes/sun/security/jca/Providers.java +++ b/jdk/src/share/classes/sun/security/jca/Providers.java @@ -159,15 +159,18 @@ public class Providers { * could not be loaded) removed. This is the list we need to * present to applications. */ - public static synchronized ProviderList getFullProviderList() { - ProviderList list = getThreadProviderList(); - if (list != null) { - ProviderList newList = list.removeInvalid(); - if (newList != list) { - changeThreadProviderList(newList); - list = newList; + public static ProviderList getFullProviderList() { + ProviderList list; + synchronized (Providers.class) { + list = getThreadProviderList(); + if (list != null) { + ProviderList newList = list.removeInvalid(); + if (newList != list) { + changeThreadProviderList(newList); + list = newList; + } + return list; } - return list; } list = getSystemProviderList(); ProviderList newList = list.removeInvalid(); diff --git a/jdk/src/share/classes/sun/tools/jar/CommandLine.java b/jdk/src/share/classes/sun/tools/jar/CommandLine.java index bf53dd3ffd7..acb13082f7b 100644 --- a/jdk/src/share/classes/sun/tools/jar/CommandLine.java +++ b/jdk/src/share/classes/sun/tools/jar/CommandLine.java @@ -36,7 +36,7 @@ import java.util.ArrayList; /** * Various utility methods for processing Java tool command line arguments. * - *

This is NOT part of any API suppored by Sun Microsystems. If + *

This is NOT part of any API supported by Oracle. If * you write code that depends on this, you do so at your own risk. * This code and its internal interfaces are subject to change or * deletion without notice. diff --git a/jdk/src/share/classes/sun/util/locale/BaseLocale.java b/jdk/src/share/classes/sun/util/locale/BaseLocale.java index a3314826f6b..2137dbd8691 100644 --- a/jdk/src/share/classes/sun/util/locale/BaseLocale.java +++ b/jdk/src/share/classes/sun/util/locale/BaseLocale.java @@ -64,12 +64,14 @@ public final class BaseLocale { public static BaseLocale getInstance(String language, String script, String region, String variant) { // JDK uses deprecated ISO639.1 language codes for he, yi and id - if (AsciiUtil.caseIgnoreMatch(language, "he")) { - language = "iw"; - } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) { - language = "ji"; - } else if (AsciiUtil.caseIgnoreMatch(language, "id")) { - language = "in"; + if (language != null) { + if (AsciiUtil.caseIgnoreMatch(language, "he")) { + language = "iw"; + } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) { + language = "ji"; + } else if (AsciiUtil.caseIgnoreMatch(language, "id")) { + language = "in"; + } } Key key = new Key(language, script, region, variant); diff --git a/jdk/src/share/classes/sun/util/logging/PlatformLogger.java b/jdk/src/share/classes/sun/util/logging/PlatformLogger.java index 499a5483a8c..0fedfff9f12 100644 --- a/jdk/src/share/classes/sun/util/logging/PlatformLogger.java +++ b/jdk/src/share/classes/sun/util/logging/PlatformLogger.java @@ -535,10 +535,6 @@ public class PlatformLogger { } void doLog(int level, String msg, Object... params) { - int paramsNumber = (params != null) ? params.length : 0; - for (int i = 0; i < paramsNumber; i++) { - params[i] = String.valueOf(params[i]); - } LoggingSupport.log(javaLogger, levelObjects.get(level), msg, params); } diff --git a/jdk/src/share/demo/nio/zipfs/Demo.java b/jdk/src/share/demo/nio/zipfs/Demo.java new file mode 100644 index 00000000000..3666dfd70de --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/Demo.java @@ -0,0 +1,664 @@ +/* + * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.io.*; +import java.nio.*; +import java.nio.channels.*; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.net.*; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +import static java.nio.file.StandardOpenOption.*; +import static java.nio.file.StandardCopyOption.*; + +/* + * ZipFileSystem usage demo + * + * java [-cp .../zipfs.jar:./] Demo action ZipfileName [...] + * + * To deploy the provider, either copy the zipfs.jar into JDK/JRE + * extensions directory or add + * /demo/nio/ZipFileSystem/zipfs.jar + * into your class path as showed above. + * + * @author Xueming Shen + */ + +public class Demo { + + static enum Action { + rename, // + // rename entry src to dst inside zipfile + + movein, // + // move an external src file into zipfile + // as entry dst + + moveout, // + // move a zipfile entry src out to dst + + copy, // + // copy entry src to dst inside zipfile + + copyin, // + // copy an external src file into zipfile + // as entry dst + + copyout, // + // copy zipfile entry src" out to file dst + + zzmove, // + // move entry path/dir from zfsrc to zfdst + + zzcopy, // + // copy path from zipfile zfsrc to zipfile + // zfdst + + attrs, // + // printout the attributes of entry path + + attrsspace, // + // printout the storespace attrs of entry path + + setmtime, // + // set the lastModifiedTime of entry path + + lsdir, // + // list dir's direct child files/dirs + + mkdir, // + + mkdirs, // + + rmdirs, // + + list, // + // recursively list all entries of dir + // via DirectoryStream + + tlist, // + // list with buildDirTree=true + + vlist, // + // recursively verbose list all entries of + // dir via DirectoryStream + + walk, // + // recursively walk all entries of dir + // via Files.walkFileTree + + twalk, // + // walk with buildDirTree=true + + extract, // + + update, // + + delete, // + + add, // + + create, // + // create a new zipfile if it doesn't exit + // and then add the file(s) into it. + + attrs2, // + // test different ways to print attrs + } + + public static void main(String[] args) throws Throwable { + + Action action = Action.valueOf(args[0]);; + Map env = env = new HashMap(); + if (action == Action.create) + env.put("createNew", true); + if (action == Action.tlist || action == Action.twalk) + env.put("buildDirTree", true); + + FileSystem fs = FileSystems.newFileSystem( + URI.create("zip" + Paths.get(args[1]).toUri().toString().substring(4)), + env, + null); + try { + FileSystem fs2; + Path path, src, dst; + boolean isRename = false; + switch (action) { + case rename: + src = fs.getPath(args[2]); + dst = fs.getPath(args[3]); + src.moveTo(dst); + break; + case moveout: + src = fs.getPath(args[2]); + dst = Paths.get(args[3]); + src.moveTo(dst); + break; + case movein: + src = Paths.get(args[2]); + dst = fs.getPath(args[3]); + src.moveTo(dst); + break; + case copy: + src = fs.getPath(args[2]); + dst = fs.getPath(args[3]); + src.copyTo(dst); + break; + case copyout: + src = fs.getPath(args[2]); + dst = Paths.get(args[3]); + src.copyTo(dst); + break; + case copyin: + src = Paths.get(args[2]); + dst = fs.getPath(args[3]); + src.copyTo(dst); + break; + case zzmove: + fs2 = FileSystems.newFileSystem( + URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)), + env, + null); + //sf1.getPath(args[3]).moveTo(fs2.getPath(args[3])); + z2zmove(fs, fs2, args[3]); + fs2.close(); + break; + case zzcopy: + fs2 = FileSystems.newFileSystem( + URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)), + env, + null); + //sf1.getPath(args[3]).copyTo(fs2.getPath(args[3])); + z2zcopy(fs, fs2, args[3]); + fs2.close(); + break; + case attrs: + for (int i = 2; i < args.length; i++) { + path = fs.getPath(args[i]); + System.out.println( + Attributes.readBasicFileAttributes(path).toString()); + } + break; + case setmtime: + DateFormat df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss"); + Date newDatetime = df.parse(args[2]); + for (int i = 3; i < args.length; i++) { + path = fs.getPath(args[i]); + path.setAttribute("lastModifiedTime", + FileTime.fromMillis(newDatetime.getTime())); + System.out.println( + Attributes.readBasicFileAttributes(path).toString()); + } + break; + case attrsspace: + path = fs.getPath("/"); + FileStore fstore = path.getFileStore(); + //System.out.println(fstore.getFileStoreAttributeView(FileStoreSpaceAttributeView.class) + // .readAttributes()); + // or + System.out.printf("filestore[%s]%n", fstore.name()); + System.out.printf(" totalSpace: %d%n", + (Long)fstore.getAttribute("space:totalSpace")); + System.out.printf(" usableSpace: %d%n", + (Long)fstore.getAttribute("space:usableSpace")); + System.out.printf(" unallocSpace: %d%n", + (Long)fstore.getAttribute("space:unallocatedSpace")); + break; + case list: + case tlist: + if (args.length < 3) + list(fs.getPath("/"), false); + else + list(fs.getPath(args[2]), false); + break; + case vlist: + if (args.length < 3) + list(fs.getPath("/"), true); + else + list(fs.getPath(args[2]), true); + break; + case twalk: + case walk: + walk(fs.getPath((args.length > 2)? args[2] : "/")); + break; + case extract: + if (args.length == 2) { + extract(fs, "/"); + } else { + for (int i = 2; i < args.length; i++) { + extract(fs, args[i]); + } + } + break; + case delete: + for (int i = 2; i < args.length; i++) + fs.getPath(args[i]).delete(); + break; + case create: + case add: + case update: + for (int i = 2; i < args.length; i++) { + update(fs, args[i]); + } + break; + case lsdir: + path = fs.getPath(args[2]); + final String fStr = (args.length > 3)?args[3]:""; + DirectoryStream ds = path.newDirectoryStream( + new DirectoryStream.Filter() { + public boolean accept(Path path) { + return path.toString().contains(fStr); + } + }); + for (Path p : ds) + System.out.println(p); + break; + case mkdir: + fs.getPath(args[2]).createDirectory(); + break; + case mkdirs: + mkdirs(fs.getPath(args[2])); + break; + case attrs2: + for (int i = 2; i < args.length; i++) { + path = fs.getPath(args[i]); + System.out.println("-------(1)---------"); + System.out.println( + Attributes.readBasicFileAttributes(path).toString()); + System.out.println("-------(2)---------"); + Map map = path.readAttributes("zip:*"); + for (Map.Entry e : map.entrySet()) { + System.out.printf(" %s : %s%n", e.getKey(), e.getValue()); + } + System.out.println("-------(3)---------"); + map = path.readAttributes("size,lastModifiedTime,isDirectory"); + for (Map.Entry e : map.entrySet()) { + System.out.printf(" %s : %s%n", e.getKey(), e.getValue()); + } + } + break; + } + } catch (Exception x) { + x.printStackTrace(); + } finally { + if (fs != null) + fs.close(); + } + } + + private static byte[] getBytes(String name) { + return name.getBytes(); + } + + private static String getString(byte[] name) { + return new String(name); + } + + private static void walk(Path path) throws IOException + { + Files.walkFileTree( + path, + new SimpleFileVisitor() { + private int indent = 0; + private void indent() { + int n = 0; + while (n++ < indent) + System.out.printf(" "); + } + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) + { + indent(); + System.out.printf("%s%n", file.getName().toString()); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) + { + indent(); + System.out.printf("[%s]%n", dir.toString()); + indent += 2; + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, + IOException ioe) + { + indent -= 2; + return FileVisitResult.CONTINUE; + } + }); + } + + private static void update(FileSystem fs, String path) throws Throwable{ + Path src = FileSystems.getDefault().getPath(path); + if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) { + DirectoryStream ds = src.newDirectoryStream(); + for (Path child : ds) + update(fs, child.toString()); + ds.close(); + } else { + Path dst = fs.getPath(path); + Path parent = dst.getParent(); + if (parent != null && parent.notExists()) + mkdirs(parent); + src.copyTo(dst, REPLACE_EXISTING); + } + } + + private static void extract(FileSystem fs, String path) throws Throwable{ + Path src = fs.getPath(path); + if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) { + DirectoryStream ds = src.newDirectoryStream(); + for (Path child : ds) + extract(fs, child.toString()); + ds.close(); + } else { + if (path.startsWith("/")) + path = path.substring(1); + Path dst = FileSystems.getDefault().getPath(path); + Path parent = dst.getParent(); + if (parent.notExists()) + mkdirs(parent); + src.copyTo(dst, REPLACE_EXISTING); + } + } + + // use DirectoryStream + private static void z2zcopy(FileSystem src, FileSystem dst, String path) + throws IOException + { + Path srcPath = src.getPath(path); + Path dstPath = dst.getPath(path); + + if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) { + if (!dstPath.exists()) { + try { + mkdirs(dstPath); + } catch (FileAlreadyExistsException x) {} + } + DirectoryStream ds = srcPath.newDirectoryStream(); + for (Path child : ds) { + z2zcopy(src, dst, + path + (path.endsWith("/")?"":"/") + child.getName()); + } + ds.close(); + } else { + //System.out.println("copying..." + path); + srcPath.copyTo(dstPath); + } + } + + // use TreeWalk to move + private static void z2zmove(FileSystem src, FileSystem dst, String path) + throws IOException + { + final Path srcPath = src.getPath(path).toAbsolutePath(); + final Path dstPath = dst.getPath(path).toAbsolutePath(); + + Files.walkFileTree(srcPath, new SimpleFileVisitor() { + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) + { + Path dst = srcPath.relativize(file); + dst = dstPath.resolve(dst); + try { + Path parent = dstPath.getParent(); + if (parent != null && parent.notExists()) + mkdirs(parent); + file.moveTo(dst); + } catch (IOException x) { + x.printStackTrace(); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) + { + Path dst = srcPath.relativize(dir); + dst = dstPath.resolve(dst); + try { + + if (dst.notExists()) + mkdirs(dst); + } catch (IOException x) { + x.printStackTrace(); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, + IOException ioe) + throws IOException + { + try { + dir.delete(); + } catch (IOException x) { + //x.printStackTrace(); + } + return FileVisitResult.CONTINUE; + } + }); + + } + + private static void mkdirs(Path path) throws IOException { + path = path.toAbsolutePath(); + Path parent = path.getParent(); + if (parent != null) { + if (parent.notExists()) + mkdirs(parent); + } + path.createDirectory(); + } + + private static void rmdirs(Path path) throws IOException { + while (path != null && path.getNameCount() != 0) { + path.delete(); + path = path.getParent(); + } + } + + private static void list(Path path, boolean verbose ) throws IOException { + if (verbose) + System.out.println(Attributes.readBasicFileAttributes(path).toString()); + else + System.out.printf(" %s%n", path.toString()); + if (path.notExists()) + return; + if (Attributes.readBasicFileAttributes(path).isDirectory()) { + DirectoryStream ds = path.newDirectoryStream(); + for (Path child : ds) + list(child, verbose); + ds.close(); + } + } + + // check the content of two paths are equal + private static void checkEqual(Path src, Path dst) throws IOException + { + //System.out.printf("checking <%s> vs <%s>...%n", + // src.toString(), dst.toString()); + + //streams + InputStream isSrc = src.newInputStream(); + InputStream isDst = dst.newInputStream(); + byte[] bufSrc = new byte[8192]; + byte[] bufDst = new byte[8192]; + + try { + int nSrc = 0; + while ((nSrc = isSrc.read(bufSrc)) != -1) { + int nDst = 0; + while (nDst < nSrc) { + int n = isDst.read(bufDst, nDst, nSrc - nDst); + if (n == -1) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nDst += n; + } + while (--nSrc >= 0) { + if (bufSrc[nSrc] != bufDst[nSrc]) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nSrc--; + } + } + } finally { + isSrc.close(); + isDst.close(); + } + + // channels + SeekableByteChannel chSrc = src.newByteChannel(); + SeekableByteChannel chDst = dst.newByteChannel(); + if (chSrc.size() != chDst.size()) { + System.out.printf("src[%s].size=%d, dst[%s].size=%d%n", + chSrc.toString(), chSrc.size(), + chDst.toString(), chDst.size()); + throw new RuntimeException("CHECK FAILED!"); + } + ByteBuffer bbSrc = ByteBuffer.allocate(8192); + ByteBuffer bbDst = ByteBuffer.allocate(8192); + + try { + int nSrc = 0; + while ((nSrc = chSrc.read(bbSrc)) != -1) { + int nDst = chDst.read(bbDst); + if (nSrc != nDst) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + while (--nSrc >= 0) { + if (bbSrc.get(nSrc) != bbDst.get(nSrc)) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nSrc--; + } + bbSrc.flip(); + bbDst.flip(); + } + } catch (IOException x) { + x.printStackTrace(); + } finally { + chSrc.close(); + chDst.close(); + } + } + + private static void fchCopy(Path src, Path dst) throws IOException + { + Set read = new HashSet<>(); + read.add(READ); + Set openwrite = new HashSet<>(); + openwrite.add(CREATE_NEW); + openwrite.add(WRITE); + + FileChannel srcFc = src.getFileSystem() + .provider() + .newFileChannel(src, read); + FileChannel dstFc = dst.getFileSystem() + .provider() + .newFileChannel(dst, openwrite); + + try { + ByteBuffer bb = ByteBuffer.allocate(8192); + while (srcFc.read(bb) >= 0) { + bb.flip(); + dstFc.write(bb); + bb.clear(); + } + } finally { + srcFc.close(); + dstFc.close(); + } + } + + private static void chCopy(Path src, Path dst) throws IOException + { + Set read = new HashSet<>(); + read.add(READ); + Set openwrite = new HashSet<>(); + openwrite.add(CREATE_NEW); + openwrite.add(WRITE); + + SeekableByteChannel srcCh = src.newByteChannel(read); + SeekableByteChannel dstCh = dst.newByteChannel(openwrite); + + try { + ByteBuffer bb = ByteBuffer.allocate(8192); + while (srcCh.read(bb) >= 0) { + bb.flip(); + dstCh.write(bb); + bb.clear(); + } + } finally { + srcCh.close(); + dstCh.close(); + } + } + + private static void streamCopy(Path src, Path dst) throws IOException + { + InputStream isSrc = src.newInputStream(); + OutputStream osDst = dst.newOutputStream(); + byte[] buf = new byte[8192]; + try { + int n = 0; + while ((n = isSrc.read(buf)) != -1) { + osDst.write(buf, 0, n); + } + } finally { + isSrc.close(); + osDst.close(); + } + } +} diff --git a/jdk/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider b/jdk/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider new file mode 100644 index 00000000000..ace131aa0fd --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider @@ -0,0 +1,3 @@ +com.sun.nio.zipfs.ZipFileSystemProvider +com.sun.nio.zipfs.JarFileSystemProvider + diff --git a/jdk/src/share/demo/nio/zipfs/README.txt b/jdk/src/share/demo/nio/zipfs/README.txt new file mode 100644 index 00000000000..227a67e270e --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/README.txt @@ -0,0 +1,29 @@ +ZipFileSystem is a file system provider that treats the contents of a zip or +JAR file as a java.nio.file.FileSystem. + +To deploy the provider you must copy zipfs.jar into your extensions +directory or else add /demo/nio/ZipFileSystem/zipfs.jar +to your class path. + +The factory methods defined by the java.nio.file.FileSystems class can be +used to create a FileSystem, eg: + + // use file type detection + Map env = Collections.emptyMap(); + Path jarfile = Path.get("foo.jar"); + FileSystem fs = FileSystems.newFileSystem(jarfile, env); + +-or + + // locate file system by URI + Map env = Collections.emptyMap(); + URI uri = URI.create("zip:///mydir/foo.jar"); + FileSystem fs = FileSystems.newFileSystem(uri, env); + +Once a FileSystem is created then classes in the java.nio.file package +can be used to access files in the zip/JAR file, eg: + + Path mf = fs.getPath("/META-INF/MANIFEST.MF"); + InputStream in = mf.newInputStream(); + + diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java new file mode 100644 index 00000000000..2fc9c83ef14 --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java @@ -0,0 +1,71 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Sun Microsystems nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.sun.nio.zipfs; + +import java.nio.file.*; +import java.nio.file.spi.*; +import java.nio.file.attribute.*; +import java.nio.file.spi.FileSystemProvider; + +import java.net.URI; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.channels.FileChannel; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class JarFileSystemProvider extends ZipFileSystemProvider +{ + + @Override + public String getScheme() { + return "jar"; + } + + @Override + protected Path uriToPath(URI uri) { + String scheme = uri.getScheme(); + if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) { + throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'"); + } + try { + String uristr = uri.toString(); + int end = uristr.indexOf("!/"); + uristr = uristr.substring(4, (end == -1) ? uristr.length() : end); + uri = new URI(uristr); + return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null)) + .toAbsolutePath(); + } catch (URISyntaxException e) { + throw new AssertionError(e); //never thrown + } + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java new file mode 100644 index 00000000000..92c5535ab19 --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; +import java.util.Arrays; + +/** + * Utility class for zipfile name and comment decoding and encoding + * + * @author Xueming Shen + */ + +final class ZipCoder { + + String toString(byte[] ba, int length) { + CharsetDecoder cd = decoder().reset(); + int len = (int)(length * cd.maxCharsPerByte()); + char[] ca = new char[len]; + if (len == 0) + return new String(ca); + ByteBuffer bb = ByteBuffer.wrap(ba, 0, length); + CharBuffer cb = CharBuffer.wrap(ca); + CoderResult cr = cd.decode(bb, cb, true); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + cr = cd.flush(cb); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + return new String(ca, 0, cb.position()); + } + + String toString(byte[] ba) { + return toString(ba, ba.length); + } + + byte[] getBytes(String s) { + CharsetEncoder ce = encoder().reset(); + char[] ca = s.toCharArray(); + int len = (int)(ca.length * ce.maxBytesPerChar()); + byte[] ba = new byte[len]; + if (len == 0) + return ba; + ByteBuffer bb = ByteBuffer.wrap(ba); + CharBuffer cb = CharBuffer.wrap(ca); + CoderResult cr = ce.encode(cb, bb, true); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + cr = ce.flush(bb); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + if (bb.position() == ba.length) // defensive copy? + return ba; + else + return Arrays.copyOf(ba, bb.position()); + } + + // assume invoked only if "this" is not utf8 + byte[] getBytesUTF8(String s) { + if (isutf8) + return getBytes(s); + if (utf8 == null) + utf8 = new ZipCoder(Charset.forName("UTF-8")); + return utf8.getBytes(s); + } + + String toStringUTF8(byte[] ba, int len) { + if (isutf8) + return toString(ba, len); + if (utf8 == null) + utf8 = new ZipCoder(Charset.forName("UTF-8")); + return utf8.toString(ba, len); + } + + boolean isUTF8() { + return isutf8; + } + + private Charset cs; + private boolean isutf8; + private ZipCoder utf8; + + private ZipCoder(Charset cs) { + this.cs = cs; + this.isutf8 = cs.name().equals("UTF-8"); + } + + static ZipCoder get(Charset charset) { + return new ZipCoder(charset); + } + + static ZipCoder get(String csn) { + try { + return new ZipCoder(Charset.forName(csn)); + } catch (Throwable t) { + t.printStackTrace(); + } + return new ZipCoder(Charset.defaultCharset()); + } + + private final ThreadLocal decTL = new ThreadLocal<>(); + private final ThreadLocal encTL = new ThreadLocal<>(); + + private CharsetDecoder decoder() { + CharsetDecoder dec = decTL.get(); + if (dec == null) { + dec = cs.newDecoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); + decTL.set(dec); + } + return dec; + } + + private CharsetEncoder encoder() { + CharsetEncoder enc = encTL.get(); + if (enc == null) { + enc = cs.newEncoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); + encTL.set(enc); + } + return enc; + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java new file mode 100644 index 00000000000..aa7073ac15e --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.nio.ByteBuffer; + +/** + * + * @author Xueming Shen + */ + +class ZipConstants { + /* + * Compression methods + */ + static final int METHOD_STORED = 0; + static final int METHOD_DEFLATED = 8; + static final int METHOD_DEFLATED64 = 9; + static final int METHOD_BZIP2 = 12; + static final int METHOD_LZMA = 14; + static final int METHOD_LZ77 = 19; + + /* + * General purpose big flag + */ + static final int FLAG_ENCRYPTED = 0x01; + static final int FLAG_DATADESCR = 0x08; // crc, size and csize in dd + static final int FLAG_EFS = 0x800; // If this bit is set the filename and + // comment fields for this file must be + // encoded using UTF-8. + /* + * Header signatures + */ + static long LOCSIG = 0x04034b50L; // "PK\003\004" + static long EXTSIG = 0x08074b50L; // "PK\007\008" + static long CENSIG = 0x02014b50L; // "PK\001\002" + static long ENDSIG = 0x06054b50L; // "PK\005\006" + + /* + * Header sizes in bytes (including signatures) + */ + static final int LOCHDR = 30; // LOC header size + static final int EXTHDR = 16; // EXT header size + static final int CENHDR = 46; // CEN header size + static final int ENDHDR = 22; // END header size + + /* + * Local file (LOC) header field offsets + */ + static final int LOCVER = 4; // version needed to extract + static final int LOCFLG = 6; // general purpose bit flag + static final int LOCHOW = 8; // compression method + static final int LOCTIM = 10; // modification time + static final int LOCCRC = 14; // uncompressed file crc-32 value + static final int LOCSIZ = 18; // compressed size + static final int LOCLEN = 22; // uncompressed size + static final int LOCNAM = 26; // filename length + static final int LOCEXT = 28; // extra field length + + /* + * Extra local (EXT) header field offsets + */ + static final int EXTCRC = 4; // uncompressed file crc-32 value + static final int EXTSIZ = 8; // compressed size + static final int EXTLEN = 12; // uncompressed size + + /* + * Central directory (CEN) header field offsets + */ + static final int CENVEM = 4; // version made by + static final int CENVER = 6; // version needed to extract + static final int CENFLG = 8; // encrypt, decrypt flags + static final int CENHOW = 10; // compression method + static final int CENTIM = 12; // modification time + static final int CENCRC = 16; // uncompressed file crc-32 value + static final int CENSIZ = 20; // compressed size + static final int CENLEN = 24; // uncompressed size + static final int CENNAM = 28; // filename length + static final int CENEXT = 30; // extra field length + static final int CENCOM = 32; // comment length + static final int CENDSK = 34; // disk number start + static final int CENATT = 36; // internal file attributes + static final int CENATX = 38; // external file attributes + static final int CENOFF = 42; // LOC header offset + + /* + * End of central directory (END) header field offsets + */ + static final int ENDSUB = 8; // number of entries on this disk + static final int ENDTOT = 10; // total number of entries + static final int ENDSIZ = 12; // central directory size in bytes + static final int ENDOFF = 16; // offset of first CEN header + static final int ENDCOM = 20; // zip file comment length + + /* + * ZIP64 constants + */ + static final long ZIP64_ENDSIG = 0x06064b50L; // "PK\006\006" + static final long ZIP64_LOCSIG = 0x07064b50L; // "PK\006\007" + static final int ZIP64_ENDHDR = 56; // ZIP64 end header size + static final int ZIP64_LOCHDR = 20; // ZIP64 end loc header size + static final int ZIP64_EXTHDR = 24; // EXT header size + static final int ZIP64_EXTID = 0x0001; // Extra field Zip64 header ID + + static final int ZIP64_MINVAL32 = 0xFFFF; + static final long ZIP64_MINVAL = 0xFFFFFFFFL; + + /* + * Zip64 End of central directory (END) header field offsets + */ + static final int ZIP64_ENDLEN = 4; // size of zip64 end of central dir + static final int ZIP64_ENDVEM = 12; // version made by + static final int ZIP64_ENDVER = 14; // version needed to extract + static final int ZIP64_ENDNMD = 16; // number of this disk + static final int ZIP64_ENDDSK = 20; // disk number of start + static final int ZIP64_ENDTOD = 24; // total number of entries on this disk + static final int ZIP64_ENDTOT = 32; // total number of entries + static final int ZIP64_ENDSIZ = 40; // central directory size in bytes + static final int ZIP64_ENDOFF = 48; // offset of first CEN header + static final int ZIP64_ENDEXT = 56; // zip64 extensible data sector + + /* + * Zip64 End of central directory locator field offsets + */ + static final int ZIP64_LOCDSK = 4; // disk number start + static final int ZIP64_LOCOFF = 8; // offset of zip64 end + static final int ZIP64_LOCTOT = 16; // total number of disks + + /* + * Zip64 Extra local (EXT) header field offsets + */ + static final int ZIP64_EXTCRC = 4; // uncompressed file crc-32 value + static final int ZIP64_EXTSIZ = 8; // compressed size, 8-byte + static final int ZIP64_EXTLEN = 16; // uncompressed size, 8-byte + + /* + * Extra field header ID + */ + static final int EXTID_ZIP64 = 0x0001; // ZIP64 + static final int EXTID_NTFS = 0x000a; // NTFS + static final int EXTID_UNIX = 0x000d; // UNIX + + + /* + * fields access methods + */ + /////////////////////////////////////////////////////// + static final int CH(byte[] b, int n) { + return b[n] & 0xff; + } + + static final int SH(byte[] b, int n) { + return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8); + } + + static final long LG(byte[] b, int n) { + return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL; + } + + static final long LL(byte[] b, int n) { + return (LG(b, n)) | (LG(b, n + 4) << 32); + } + + static final long GETSIG(byte[] b) { + return LG(b, 0); + } + + // local file (LOC) header fields + static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature + static final int LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract + static final int LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags + static final int LOCHOW(byte[] b) { return SH(b, 8); } // compression method + static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time + static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data + static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size + static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size + static final int LOCNAM(byte[] b) { return SH(b, 26);} // filename length + static final int LOCEXT(byte[] b) { return SH(b, 28);} // extra field length + + // extra local (EXT) header fields + static final long EXTCRC(byte[] b) { return LG(b, 4);} // crc of uncompressed data + static final long EXTSIZ(byte[] b) { return LG(b, 8);} // compressed size + static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size + + // end of central directory header (END) fields + static final int ENDSUB(byte[] b) { return SH(b, 8); } // number of entries on this disk + static final int ENDTOT(byte[] b) { return SH(b, 10);} // total number of entries + static final long ENDSIZ(byte[] b) { return LG(b, 12);} // central directory size + static final long ENDOFF(byte[] b) { return LG(b, 16);} // central directory offset + static final int ENDCOM(byte[] b) { return SH(b, 20);} // size of zip file comment + static final int ENDCOM(byte[] b, int off) { return SH(b, off + 20);} + + // zip64 end of central directory recoder fields + static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);} // total number of entries on disk + static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);} // total number of entries + static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);} // central directory size + static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);} // central directory offset + static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);} // zip64 end offset + + ////////////////////////////////////////// + static final int CH(ByteBuffer b, int pos) { + return b.get(pos) & 0xff; + } + static final int SH(ByteBuffer b, int pos) { + return b.getShort(pos) & 0xffff; + } + static final long LG(ByteBuffer b, int pos) { + return b.getInt(pos) & 0xffffffffL; + } + + // central directory header (END) fields + static final long CENSIG(ByteBuffer b, int pos) { return LG(b, pos + 0); } + static final int CENVEM(ByteBuffer b, int pos) { return SH(b, pos + 4); } + static final int CENVER(ByteBuffer b, int pos) { return SH(b, pos + 6); } + static final int CENFLG(ByteBuffer b, int pos) { return SH(b, pos + 8); } + static final int CENHOW(ByteBuffer b, int pos) { return SH(b, pos + 10);} + static final long CENTIM(ByteBuffer b, int pos) { return LG(b, pos + 12);} + static final long CENCRC(ByteBuffer b, int pos) { return LG(b, pos + 16);} + static final long CENSIZ(ByteBuffer b, int pos) { return LG(b, pos + 20);} + static final long CENLEN(ByteBuffer b, int pos) { return LG(b, pos + 24);} + static final int CENNAM(ByteBuffer b, int pos) { return SH(b, pos + 28);} + static final int CENEXT(ByteBuffer b, int pos) { return SH(b, pos + 30);} + static final int CENCOM(ByteBuffer b, int pos) { return SH(b, pos + 32);} + static final int CENDSK(ByteBuffer b, int pos) { return SH(b, pos + 34);} + static final int CENATT(ByteBuffer b, int pos) { return SH(b, pos + 36);} + static final long CENATX(ByteBuffer b, int pos) { return LG(b, pos + 38);} + static final long CENOFF(ByteBuffer b, int pos) { return LG(b, pos + 42);} + + /* The END header is followed by a variable length comment of size < 64k. */ + static final long END_MAXLEN = 0xFFFF + ENDHDR; + static final int READBLOCKSZ = 128; +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java new file mode 100644 index 00000000000..3052b34e59a --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.nio.file.DirectoryStream; +import java.nio.file.ClosedDirectoryStreamException; +import java.nio.file.NotDirectoryException; +import java.nio.file.Path; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.io.IOException; +import static com.sun.nio.zipfs.ZipUtils.*; + +/** + * + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal + */ + +public class ZipDirectoryStream implements DirectoryStream { + + private final ZipFileSystem zipfs; + private final byte[] path; + private final DirectoryStream.Filter filter; + private volatile boolean isClosed; + private volatile Iterator itr; + + ZipDirectoryStream(ZipPath zipPath, + DirectoryStream.Filter filter) + throws IOException + { + this.zipfs = zipPath.getFileSystem(); + this.path = zipPath.getResolvedPath(); + this.filter = filter; + // sanity check + if (!zipfs.isDirectory(path)) + throw new NotDirectoryException(zipPath.toString()); + } + + @Override + public synchronized Iterator iterator() { + if (isClosed) + throw new ClosedDirectoryStreamException(); + if (itr != null) + throw new IllegalStateException("Iterator has already been returned"); + + try { + itr = zipfs.iteratorOf(path, filter); + } catch (IOException e) { + throw new IllegalStateException(e); + } + return new Iterator() { + private Path next; + @Override + public boolean hasNext() { + if (isClosed) + return false; + return itr.hasNext(); + } + + @Override + public synchronized Path next() { + if (isClosed) + throw new NoSuchElementException(); + return itr.next(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + @Override + public synchronized void close() throws IOException { + isClosed = true; + } + + +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java new file mode 100644 index 00000000000..d4a9a67c9fc --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +package com.sun.nio.zipfs; + +import java.nio.file.ReadOnlyFileSystemException; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.FileAttributeView; +import java.nio.file.attribute.FileTime; +import java.io.IOException; +import java.util.LinkedHashMap; + +/* + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal + */ + +public class ZipFileAttributeView implements BasicFileAttributeView +{ + private static enum AttrID { + size, + creationTime, + lastAccessTime, + lastModifiedTime, + isDirectory, + isRegularFile, + isSymbolicLink, + isOther, + fileKey, + compressedSize, + crc, + method + }; + + private final ZipPath path; + private final boolean isZipView; + + private ZipFileAttributeView(ZipPath path, boolean isZipView) { + this.path = path; + this.isZipView = isZipView; + } + + static V get(ZipPath path, Class type) { + if (type == null) + throw new NullPointerException(); + if (type == BasicFileAttributeView.class) + return (V)new ZipFileAttributeView(path, false); + if (type == ZipFileAttributeView.class) + return (V)new ZipFileAttributeView(path, true); + return null; + } + + static ZipFileAttributeView get(ZipPath path, String type) { + if (type == null) + throw new NullPointerException(); + if (type.equals("basic")) + return new ZipFileAttributeView(path, false); + if (type.equals("zip")) + return new ZipFileAttributeView(path, true); + return null; + } + + @Override + public String name() { + return isZipView ? "zip" : "basic"; + } + + public ZipFileAttributes readAttributes() throws IOException + { + return path.getAttributes(); + } + + @Override + public void setTimes(FileTime lastModifiedTime, + FileTime lastAccessTime, + FileTime createTime) + throws IOException + { + path.setTimes(lastModifiedTime, lastAccessTime, createTime); + } + + void setAttribute(String attribute, Object value) + throws IOException + { + try { + if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime) + setTimes ((FileTime)value, null, null); + return; + } catch (IllegalArgumentException x) {} + throw new UnsupportedOperationException("'" + attribute + + "' is unknown or read-only attribute"); + } + + public Object getAttribute(String attribute, boolean domap) + throws IOException + { + ZipFileAttributes zfas = readAttributes(); + if (!domap) { + try { + return attribute(AttrID.valueOf(attribute), zfas); + } catch (IllegalArgumentException x) {} + return null; + } + LinkedHashMap map = new LinkedHashMap<>(); + if ("*".equals(attribute)) { + for (AttrID id : AttrID.values()) { + try { + map.put(id.name(), attribute(id, zfas)); + } catch (IllegalArgumentException x) {} + } + } else { + String[] as = attribute.split(","); + for (String a : as) { + try { + map.put(a, attribute(AttrID.valueOf(a), zfas)); + } catch (IllegalArgumentException x) {} + } + } + return map; + } + + Object attribute(AttrID id, ZipFileAttributes zfas) { + switch (id) { + case size: + return zfas.size(); + case creationTime: + return zfas.creationTime(); + case lastAccessTime: + return zfas.lastAccessTime(); + case lastModifiedTime: + return zfas.lastModifiedTime(); + case isDirectory: + return zfas.isDirectory(); + case isRegularFile: + return zfas.isRegularFile(); + case isSymbolicLink: + return zfas.isSymbolicLink(); + case isOther: + return zfas.isOther(); + case fileKey: + return zfas.fileKey(); + case compressedSize: + if (isZipView) + return zfas.compressedSize(); + break; + case crc: + if (isZipView) + return zfas.crc(); + break; + case method: + if (isZipView) + return zfas.method(); + break; + } + return null; + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java new file mode 100644 index 00000000000..157f9eb163a --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +package com.sun.nio.zipfs; + +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; +import java.util.Arrays; +import java.util.Formatter; +import static com.sun.nio.zipfs.ZipUtils.*; + +/** + * + * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal + */ + +public class ZipFileAttributes implements BasicFileAttributes + +{ + private final ZipFileSystem.Entry e; + + ZipFileAttributes(ZipFileSystem.Entry e) { + this.e = e; + } + + ///////// basic attributes /////////// + @Override + public FileTime creationTime() { + if (e.ctime != -1) + return FileTime.fromMillis(dosToJavaTime(e.ctime)); + return null; + } + + @Override + public boolean isDirectory() { + return e.isDir(); + } + + @Override + public boolean isOther() { + return false; + } + + @Override + public boolean isRegularFile() { + return !e.isDir(); + } + + @Override + public FileTime lastAccessTime() { + if (e.atime != -1) + return FileTime.fromMillis(dosToJavaTime(e.atime)); + return null; + } + + @Override + public FileTime lastModifiedTime() { + return FileTime.fromMillis(dosToJavaTime(e.mtime)); + } + + @Override + public long size() { + return e.size; + } + + @Override + public boolean isSymbolicLink() { + return false; + } + + @Override + public Object fileKey() { + return null; + } + + ///////// zip entry attributes /////////// + public byte[] name() { + return Arrays.copyOf(e.name, e.name.length); + } + + public long compressedSize() { + return e.csize; + } + + public long crc() { + return e.crc; + } + + public int method() { + return e.method; + } + + public byte[] extra() { + if (e.extra != null) + return Arrays.copyOf(e.extra, e.extra.length); + return null; + } + + public byte[] comment() { + if (e.comment != null) + return Arrays.copyOf(e.comment, e.comment.length); + return null; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + Formatter fm = new Formatter(sb); + fm.format("[/%s]%n", new String(e.name)); // TBD encoding + fm.format(" creationTime : %s%n", creationTime()); + if (lastAccessTime() != null) + fm.format(" lastAccessTime : %tc%n", lastAccessTime().toMillis()); + else + fm.format(" lastAccessTime : null%n"); + fm.format(" lastModifiedTime: %tc%n", lastModifiedTime().toMillis()); + fm.format(" isRegularFile : %b%n", isRegularFile()); + fm.format(" isDirectory : %b%n", isDirectory()); + fm.format(" isSymbolicLink : %b%n", isSymbolicLink()); + fm.format(" isOther : %b%n", isOther()); + fm.format(" fileKey : %s%n", fileKey()); + fm.format(" size : %d%n", size()); + fm.format(" compressedSize : %d%n", compressedSize()); + fm.format(" crc : %x%n", crc()); + fm.format(" method : %d%n", method()); + fm.close(); + return sb.toString(); + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileStore.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileStore.java new file mode 100644 index 00000000000..681509719e7 --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileStore.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.io.IOException; +import java.nio.file.FileStore; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.attribute.FileAttributeView; +import java.nio.file.attribute.FileStoreAttributeView; +import java.nio.file.attribute.FileStoreSpaceAttributeView; +import java.nio.file.attribute.FileStoreSpaceAttributes; +import java.nio.file.attribute.Attributes; +import java.nio.file.attribute.BasicFileAttributeView; +import java.util.Formatter; + +/* + * + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal + */ + +public class ZipFileStore extends FileStore { + + private final ZipFileSystem zfs; + + ZipFileStore(ZipPath zpath) { + this.zfs = (ZipFileSystem)zpath.getFileSystem(); + } + + @Override + public String name() { + return zfs.toString() + "/"; + } + + @Override + public String type() { + return "zipfs"; + } + + @Override + public boolean isReadOnly() { + return zfs.isReadOnly(); + } + + @Override + public boolean supportsFileAttributeView(Class type) { + return (type == BasicFileAttributeView.class || + type == ZipFileAttributeView.class); + } + + @Override + public boolean supportsFileAttributeView(String name) { + return name.equals("basic") || name.equals("zip"); + } + + @Override + @SuppressWarnings("unchecked") + public V getFileStoreAttributeView(Class type) { + if (type == null) + throw new NullPointerException(); + if (type == FileStoreSpaceAttributeView.class) + return (V) new ZipFileStoreAttributeView(this); + return null; + } + + @Override + public Object getAttribute(String attribute) throws IOException { + if (attribute.equals("space:totalSpace")) + return new ZipFileStoreAttributeView(this).readAttributes().totalSpace(); + if (attribute.equals("space:usableSpace")) + return new ZipFileStoreAttributeView(this).readAttributes().usableSpace(); + if (attribute.equals("space:unallocatedSpace")) + return new ZipFileStoreAttributeView(this).readAttributes().unallocatedSpace(); + throw new UnsupportedOperationException("does not support the given attribute"); + } + + private static class ZipFileStoreAttributeView implements FileStoreSpaceAttributeView { + + private final ZipFileStore fileStore; + + public ZipFileStoreAttributeView(ZipFileStore fileStore) { + this.fileStore = fileStore; + } + + @Override + public String name() { + return "space"; + } + + @Override + public FileStoreSpaceAttributes readAttributes() throws IOException { + final String file = fileStore.name(); + Path path = FileSystems.getDefault().getPath(file); + final long size = Attributes.readBasicFileAttributes(path).size(); + final FileStore fstore = path.getFileStore(); + final FileStoreSpaceAttributes fstoreAttrs = + Attributes.readFileStoreSpaceAttributes(fstore); + return new FileStoreSpaceAttributes() { + public long totalSpace() { + return size; + } + + public long usableSpace() { + if (!fstore.isReadOnly()) + return fstoreAttrs.usableSpace(); + return 0; + } + + public long unallocatedSpace() { + if (!fstore.isReadOnly()) + return fstoreAttrs.unallocatedSpace(); + return 0; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + Formatter fm = new Formatter(sb); + fm.format("FileStoreSpaceAttributes[%s]%n", file); + fm.format(" totalSpace: %d%n", totalSpace()); + fm.format(" usableSpace: %d%n", usableSpace()); + fm.format(" unallocSpace: %d%n", unallocatedSpace()); + fm.close(); + return sb.toString(); + } + }; + } + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java new file mode 100644 index 00000000000..152ca957c1d --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java @@ -0,0 +1,2257 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.MappedByteBuffer; +import java.nio.channels.*; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.nio.file.spi.*; +import java.net.URI; +import java.util.*; +import java.util.regex.Pattern; +import java.util.zip.CRC32; +import java.util.zip.Inflater; +import java.util.zip.Deflater; +import java.util.zip.InflaterInputStream; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.ZipException; +import java.util.zip.ZipError; +import static java.lang.Boolean.*; +import static com.sun.nio.zipfs.ZipConstants.*; +import static com.sun.nio.zipfs.ZipUtils.*; +import static java.nio.file.StandardOpenOption.*; +import static java.nio.file.StandardCopyOption.*; + +/** + * A FileSystem built on a zip file + * + * @author Xueming Shen + */ + +public class ZipFileSystem extends FileSystem { + + private final ZipFileSystemProvider provider; + private final ZipPath defaultdir; + private boolean readOnly = false; + private final Path zfpath; + private final ZipCoder zc; + + private final Object lock = new Object(); + + // configurable by env map + private final String defaultDir; // default dir for the file system + private final String nameEncoding; // default encoding for name/comment + private final boolean buildDirTree; // build a dir tree for directoryStream ops + private final boolean useTempFile; // use a temp file for newOS, default + // is to use BAOS for better performance + private final boolean createNew; // create a new zip if not exists + + ZipFileSystem(ZipFileSystemProvider provider, + Path zfpath, + Map env) + throws IOException + { + // configurable env setup + this.buildDirTree = TRUE.equals(env.get("buildDirTree")); + this.useTempFile = TRUE.equals(env.get("useTempFile")); + this.createNew = TRUE.equals(env.get("createNew")); + this.nameEncoding = env.containsKey("nameEncoding") ? + (String)env.get("nameEncoding") : "UTF-8"; + this.defaultDir = env.containsKey("default.dir") ? + (String)env.get("default.dir") : "/"; + if (this.defaultDir.charAt(0) != '/') + throw new IllegalArgumentException("default dir should be absolute"); + + this.provider = provider; + this.zfpath = zfpath; + if (zfpath.notExists()) { + if (createNew) { + OutputStream os = zfpath.newOutputStream(CREATE_NEW, WRITE); + new END().write(os, 0); + os.close(); + } else { + throw new FileSystemNotFoundException(zfpath.toString()); + } + } + zfpath.checkAccess(AccessMode.READ); // sm and existence check + try { + zfpath.checkAccess(AccessMode.WRITE); + } catch (AccessDeniedException x) { + this.readOnly = true; + } + this.zc = ZipCoder.get(nameEncoding); + this.defaultdir = new ZipPath(this, getBytes(defaultDir)); + initZipFile(); + } + + @Override + public FileSystemProvider provider() { + return provider; + } + + @Override + public String getSeparator() { + return "/"; + } + + @Override + public boolean isOpen() { + return isOpen; + } + + @Override + public boolean isReadOnly() { + return readOnly; + } + + private void checkWritable() throws IOException { + if (readOnly) + throw new ReadOnlyFileSystemException(); + } + + @Override + public Iterable getRootDirectories() { + ArrayList pathArr = new ArrayList<>(); + pathArr.add(new ZipPath(this, new byte[]{'/'})); + return pathArr; + } + + ZipPath getDefaultDir() { // package private + return defaultdir; + } + + @Override + public ZipPath getPath(String path) { + if (path.length() == 0) + throw new InvalidPathException(path, "path should not be empty"); + return new ZipPath(this, getBytes(path)); + } + + @Override + public UserPrincipalLookupService getUserPrincipalLookupService() { + throw new UnsupportedOperationException(); + } + + @Override + public WatchService newWatchService() { + throw new UnsupportedOperationException(); + } + + FileStore getFileStore(ZipPath path) { + return new ZipFileStore(path); + } + + @Override + public Iterable getFileStores() { + ArrayList list = new ArrayList(1); + list.add(new ZipFileStore(new ZipPath(this, new byte[]{'/'}))); + return list; + } + + private static final Set supportedFileAttributeViews = + Collections.unmodifiableSet( + new HashSet(Arrays.asList("basic", "zip"))); + + @Override + public Set supportedFileAttributeViews() { + return supportedFileAttributeViews; + } + + @Override + public String toString() { + return zfpath.toString(); + } + + Path getZipFile() { + return zfpath; + } + + private static final String GLOB_SYNTAX = "glob"; + private static final String REGEX_SYNTAX = "regex"; + + @Override + public PathMatcher getPathMatcher(String syntaxAndInput) { + int pos = syntaxAndInput.indexOf(':'); + if (pos <= 0 || pos == syntaxAndInput.length()) { + throw new IllegalArgumentException(); + } + String syntax = syntaxAndInput.substring(0, pos); + String input = syntaxAndInput.substring(pos + 1); + String expr; + if (syntax.equals(GLOB_SYNTAX)) { + expr = toRegexPattern(input); + } else { + if (syntax.equals(REGEX_SYNTAX)) { + expr = input; + } else { + throw new UnsupportedOperationException("Syntax '" + syntax + + "' not recognized"); + } + } + // return matcher + final Pattern pattern = Pattern.compile(expr); + return new PathMatcher() { + @Override + public boolean matches(Path path) { + return pattern.matcher(path.toString()).matches(); + } + }; + } + + @Override + public void close() throws IOException { + synchronized (lock) { + if (!isOpen) + return; + isOpen = false; + if (!streams.isEmpty()) { + synchronized(streams) { + for (InputStream is: streams) + is.close(); + } + } + sync(); + ch.close(); + } + synchronized (inflaters) { + for (Inflater inf : inflaters) + inf.end(); + } + synchronized (deflaters) { + for (Deflater def : deflaters) + def.end(); + } + for (Path p: tmppaths) { + try { + p.deleteIfExists(); + } catch (IOException x) { + x.printStackTrace(); + } + } + provider.removeFileSystem(zfpath); + } + + ZipFileAttributes[] getAllAttributes() throws IOException { + ensureOpen(); + int n = inodes.size(); + ZipFileAttributes[] zes = new ZipFileAttributes[n]; + Iterator itr = inodes.values().iterator(); + int i = 0; + while(itr.hasNext()) { + zes[i++] = new ZipFileAttributes(Entry.readCEN(cen, itr.next().pos)); + } + return zes; + } + + EntryName[] getEntryNames() throws IOException { + ensureOpen(); + return inodes.keySet().toArray(new EntryName[0]); + } + + ZipFileAttributes getFileAttributes(byte[] path) + throws IOException + { + synchronized (lock) { + Entry e = getEntry0(path); + if (e == null) { + if (path.length == 0) { + e = new Entry(new byte[0]); // root + } else if (buildDirTree) { + IndexNode inode = getDirs().get(new EntryName(path)); + if (inode == null) + return null; + e = new Entry(inode.name); + } else { + return null; + } + e.method = METHOD_STORED; // STORED for dir + BasicFileAttributes bfas = Attributes.readBasicFileAttributes(zfpath); + if (bfas.lastModifiedTime() != null) + e.mtime = javaToDosTime(bfas.lastModifiedTime().toMillis()); + if (bfas.lastAccessTime() != null) + e.atime = javaToDosTime(bfas.lastAccessTime().toMillis()); + if (bfas.creationTime() != null) + e.ctime = javaToDosTime(bfas.creationTime().toMillis()); + } + return new ZipFileAttributes(e); + } + } + + void setTimes(byte[] path, FileTime mtime, FileTime atime, FileTime ctime) + throws IOException + { + checkWritable(); + synchronized (lock) { + Entry e = getEntry0(path); // ensureOpen checked + if (e == null) + throw new NoSuchFileException(getString(path)); + if (e.type == Entry.CEN) + e.type = Entry.COPY; // copy e + if (mtime != null) + e.mtime = javaToDosTime(mtime.toMillis()); + if (atime != null) + e.atime = javaToDosTime(atime.toMillis()); + if (ctime != null) + e.ctime = javaToDosTime(ctime.toMillis()); + update(e); + } + } + + boolean exists(byte[] path) + throws IOException + { + return getEntry0(path) != null; + } + + boolean isDirectory(byte[] path) + throws IOException + { + synchronized (lock) { + if (buildDirTree) { + return getDirs().containsKey(new EntryName(path)); + } + Entry e = getEntry0(path); + return (e != null && e.isDir()) || path.length == 0; + } + } + + private ZipPath toZipPath(byte[] path) { + // make it absolute + byte[] p = new byte[path.length + 1]; + p[0] = '/'; + System.arraycopy(path, 0, p, 1, path.length); + return new ZipPath(this, p); + } + + // returns the list of child paths of "path" + Iterator iteratorOf(byte[] path, + DirectoryStream.Filter filter) + throws IOException + { + synchronized (lock) { + if (buildDirTree) { + IndexNode inode = getDirs().get(new EntryName(path)); + if (inode == null) + throw new NotDirectoryException(getString(path)); + List list = new ArrayList(); + IndexNode child = inode.child; + while (child != null) { + ZipPath zp = toZipPath(child.name); + if (filter == null || filter.accept(zp)) + list.add(zp); + child = child.sibling; + } + return list.iterator(); + } + + if (!isDirectory(path)) + throw new NotDirectoryException(getString(path)); + List list = new ArrayList(); + EntryName[] entries = getEntryNames(); + path = toDirectoryPath(path); + for (EntryName en :entries) { + if (!isParentOf(path, en.name)) // is "path" the parent of "name" + continue; + int off = path.length; + while (off < en.name.length) { + if (en.name[off] == '/') + break; + off++; + } + if (off < (en.name.length - 1)) + continue; + ZipPath zp = toZipPath(en.name); + if (filter == null || filter.accept(zp)) + list.add(zp); + } + return list.iterator(); + } + } + + void createDirectory(byte[] dir, FileAttribute... attrs) + throws IOException + { + checkWritable(); + dir = toDirectoryPath(dir); + synchronized (lock) { + ensureOpen(); + // pseudo root dir, or exiting dir + if (dir.length == 0 || exists(dir)) + throw new FileAlreadyExistsException(getString(dir)); + checkParents(dir); + + Entry e = new Entry(dir, Entry.NEW); + e.method = METHOD_STORED; // STORED for dir + update(e); + } + } + + void copyFile(boolean deletesrc, byte[]src, byte[] dst, CopyOption... options) + throws IOException + { + checkWritable(); + if (Arrays.equals(src, dst)) + return; // do nothing, src and dst are the same + synchronized (lock) { + Entry eSrc = getEntry0(src); // ensureOpen checked + if (eSrc == null) + throw new NoSuchFileException(getString(src)); + if (eSrc.isDir()) { // spec says to create dst dir + createDirectory(dst); + return; + } + boolean hasReplace = false; + boolean hasCopyAttrs = false; + for (CopyOption opt : options) { + if (opt == REPLACE_EXISTING) + hasReplace = true; + else if (opt == COPY_ATTRIBUTES) + hasCopyAttrs = true; + } + Entry eDst = getEntry0(dst); + if (eDst != null) { + if (!hasReplace) + throw new FileAlreadyExistsException(getString(dst)); + } else { + checkParents(dst); + } + Entry u = new Entry(eSrc, Entry.COPY); // copy eSrc entry + u.name = dst; // change name + // don't touch the "nlen and elen" here. writeLOC() always + // re-calculate from "name" and "extra" for the correct length, + // copyLOCEntry however needs the original lengths to skip the + // loc header. + // u.nlen = dst.length; + if (eSrc.type == Entry.NEW || eSrc.type == Entry.FILECH) + { + u.type = eSrc.type; // make it the same type + if (!deletesrc) { // if it's not "rename", just take the data + if (eSrc.bytes != null) + u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length); + else if (eSrc.file != null) { + u.file = getTempPathForEntry(null); + eSrc.file.copyTo(u.file, REPLACE_EXISTING); + } + } + } + if (!hasCopyAttrs) + u.mtime = u.atime= u.ctime = javaToDosTime(System.currentTimeMillis()); + update(u); + if (deletesrc) + updateDelete(eSrc); + } + } + + // Returns an output stream for writing the contents into the specified + // entry. + OutputStream newOutputStream(byte[] path, OpenOption... options) + throws IOException + { + checkWritable(); + boolean hasCreateNew = false; + boolean hasCreate = false; + boolean hasAppend = false; + for (OpenOption opt: options) { + if (opt == READ) + throw new IllegalArgumentException("READ not allowed"); + if (opt == CREATE_NEW) + hasCreateNew = true; + if (opt == CREATE) + hasCreate = true; + if (opt == APPEND) + hasAppend = true; + } + synchronized (lock) { + Entry e = getEntry0(path); + if (e != null) { + if (e.isDir() || hasCreateNew) + throw new FileAlreadyExistsException(getString(path)); + if (hasAppend) { + InputStream is = getInputStream(e); + OutputStream os = getOutputStream(new Entry(e, Entry.NEW)); + copyStream(is, os); + is.close(); + return os; + } + return getOutputStream(new Entry(e, Entry.NEW)); + } else { + if (!hasCreate && !hasCreateNew) + throw new NoSuchFileException(getString(path)); + checkParents(path); + return getOutputStream(new Entry(path, Entry.NEW)); + } + } + } + + // Returns an input stream for reading the contents of the specified + // file entry. + InputStream newInputStream(byte[] path) throws IOException { + synchronized (lock) { + Entry e = getEntry0(path); + if (e == null) + throw new NoSuchFileException(getString(path)); + if (e.isDir()) + throw new FileSystemException(getString(path), "is a directory", null); + return getInputStream(e); + } + } + + private void checkOptions(Set options) { + // check for options of null type and option is an intance of StandardOpenOption + for (OpenOption option : options) { + if (option == null) + throw new NullPointerException(); + if (!(option instanceof StandardOpenOption)) + throw new IllegalArgumentException(); + } + } + + // Returns a Writable/ReadByteChannel for now. Might consdier to use + // newFileChannel() instead, which dump the entry data into a regular + // file on the default file system and create a FileChannel on top of + // it. + SeekableByteChannel newByteChannel(byte[] path, + Set options, + FileAttribute... attrs) + throws IOException + { + checkOptions(options); + if (options.contains(StandardOpenOption.WRITE) || + options.contains(StandardOpenOption.APPEND)) { + checkWritable(); + final WritableByteChannel wbc = Channels.newChannel(newOutputStream(path, + options.toArray(new OpenOption[0]))); + long leftover = 0;; + if (options.contains(StandardOpenOption.APPEND)) { + Entry e = getEntry0(path); + if (e != null && e.size >= 0) + leftover = e.size; + } + final long offset = leftover; + return new SeekableByteChannel() { + long written = offset; + public boolean isOpen() { + return wbc.isOpen(); + } + public long position() throws IOException { + return written; + } + public SeekableByteChannel position(long pos) throws IOException { + throw new UnsupportedOperationException(); + } + public int read(ByteBuffer dst) throws IOException { + throw new UnsupportedOperationException(); + } + public SeekableByteChannel truncate(long size) throws IOException { + throw new UnsupportedOperationException(); + } + public int write(ByteBuffer src) throws IOException { + int n = wbc.write(src); + written += n; + return n; + } + public long size() throws IOException { + return written; + } + public void close() throws IOException { + wbc.close(); + } + }; + } else { + Entry e = getEntry0(path); + if (e == null || e.isDir()) + throw new NoSuchFileException(getString(path)); + final ReadableByteChannel rbc = + Channels.newChannel(getInputStream(e)); + final long size = e.size; + return new SeekableByteChannel() { + long read = 0; + public boolean isOpen() { + return rbc.isOpen(); + } + public long position() throws IOException { + return read; + } + public SeekableByteChannel position(long pos) throws IOException { + throw new UnsupportedOperationException(); + } + public int read(ByteBuffer dst) throws IOException { + return rbc.read(dst); + } + public SeekableByteChannel truncate(long size) throws IOException { + throw new NonWritableChannelException(); + } + public int write (ByteBuffer src) throws IOException { + throw new NonWritableChannelException(); + } + public long size() throws IOException { + return size; + } + public void close() throws IOException { + rbc.close(); + } + }; + } + } + + // Returns a FileChannel of the specified entry. + // + // This implementation creates a temporary file on the default file system, + // copy the entry data into it if the entry exists, and then create a + // FileChannel on top of it. + FileChannel newFileChannel(byte[] path, + Set options, + FileAttribute... attrs) + throws IOException + { + checkOptions(options); + final boolean forWrite = (options.contains(StandardOpenOption.WRITE) || + options.contains(StandardOpenOption.APPEND)); + Entry e = getEntry0(path); + if (forWrite) { + checkWritable(); + if (e == null) { + if (!options.contains(StandardOpenOption.CREATE_NEW)) + throw new NoSuchFileException(getString(path)); + } else { + if (options.contains(StandardOpenOption.CREATE_NEW)) + throw new FileAlreadyExistsException(getString(path)); + if (e.isDir()) + throw new FileAlreadyExistsException("directory <" + + getString(path) + "> exists"); + } + options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile + } else if (e == null || e.isDir()) { + throw new NoSuchFileException(getString(path)); + } + + final boolean isFCH = (e != null && e.type == Entry.FILECH); + final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path); + final FileChannel fch = tmpfile.getFileSystem() + .provider() + .newFileChannel(tmpfile, options, attrs); + final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH); + if (forWrite) { + u.flag = FLAG_DATADESCR; + u.method = METHOD_DEFLATED; + } + // is there a better way to hook into the FileChannel's close method? + return new FileChannel() { + public int write(ByteBuffer src) throws IOException { + return fch.write(src); + } + public long write(ByteBuffer[] srcs, int offset, int length) + throws IOException + { + return fch.write(srcs, offset, length); + } + public long position() throws IOException { + return fch.position(); + } + public FileChannel position(long newPosition) + throws IOException + { + fch.position(newPosition); + return this; + } + public long size() throws IOException { + return fch.size(); + } + public FileChannel truncate(long size) + throws IOException + { + fch.truncate(size); + return this; + } + public void force(boolean metaData) + throws IOException + { + fch.force(metaData); + } + public long transferTo(long position, long count, + WritableByteChannel target) + throws IOException + { + return fch.transferTo(position, count, target); + } + public long transferFrom(ReadableByteChannel src, + long position, long count) + throws IOException + { + return fch.transferFrom(src, position, count); + } + public int read(ByteBuffer dst) throws IOException { + return fch.read(dst); + } + public int read(ByteBuffer dst, long position) + throws IOException + { + return fch.read(dst, position); + } + public long read(ByteBuffer[] dsts, int offset, int length) + throws IOException + { + return fch.read(dsts, offset, length); + } + public int write(ByteBuffer src, long position) + throws IOException + { + return fch.write(src, position); + } + public MappedByteBuffer map(MapMode mode, + long position, long size) + throws IOException + { + throw new UnsupportedOperationException(); + } + public FileLock lock(long position, long size, boolean shared) + throws IOException + { + return fch.lock(position, size, shared); + } + public FileLock tryLock(long position, long size, boolean shared) + throws IOException + { + return fch.tryLock(position, size, shared); + } + protected void implCloseChannel() throws IOException { + fch.close(); + if (forWrite) { + u.mtime = javaToDosTime(System.currentTimeMillis()); + u.size = Attributes.readBasicFileAttributes(u.file).size(); + update(u); + } else { + if (!isFCH) // if this is a new fch for reading + removeTempPathForEntry(tmpfile); + } + } + }; + } + + // the outstanding input streams that need to be closed + private Set streams = + Collections.synchronizedSet(new HashSet()); + + // the ex-channel and ex-path that need to close when their outstanding + // input streams are all closed by the obtainers. + private Set exChClosers = new HashSet<>(); + + private Set tmppaths = new HashSet<>(); + private Path getTempPathForEntry(byte[] path) throws IOException { + Path tmpPath = createTempFileInSameDirectoryAs(zfpath); + tmppaths.add(tmpPath); + + if (path != null) { + Entry e = getEntry0(path); + if (e != null) { + InputStream is = newInputStream(path); + OutputStream os = tmpPath.newOutputStream(WRITE); + try { + copyStream(is, os); + } finally { + is.close(); + os.close(); + } + } + } + return tmpPath; + } + + private void removeTempPathForEntry(Path path) throws IOException { + path.delete(); + tmppaths.remove(path); + } + + // check if all parents really exit. ZIP spec does not require + // the existence of any "parent directory". + private void checkParents(byte[] path) throws IOException { + while ((path = getParent(path)) != null) { + if (!inodes.containsKey(new EntryName(path))) + throw new NoSuchFileException(getString(path)); + } + } + + private static byte[] getParent(byte[] path) { + int off = path.length - 1; + if (off > 0 && path[off] == '/') // isDirectory + off--; + while (off > 0 && path[off] != '/') { off--; } + if (off == 0) + return null; // top entry + return Arrays.copyOf(path, off + 1); + } + + // If "starter" is the parent directory of "path" + private static boolean isParentOf(byte[] p, byte[] c) { + final int plen = p.length; + if (plen == 0) // root dir + return true; + if (plen >= c.length) + return false; + int n = 0; + while (n < plen) { + if (p[n] != c[n]) + return false; + n++; + } + if (p[n - 1] != '/' && (c[n] != '/' || n == c.length - 1)) + return false; + return true; + } + + /////////////////////////////////////////////////////////////////// + private void initZipFile() throws IOException { + ch = zfpath.newByteChannel(READ); + initCEN(); + } + + private volatile boolean isOpen = true; + private SeekableByteChannel ch; // channel to the zipfile + ByteBuffer cen; // CEN & ENDHDR + private END end; + private long locpos; // position of first LOC header (usually 0) + + // name -> pos (in cen), package private for ZipInfo + LinkedHashMap inodes; + + byte[] getBytes(String name) { + return zc.getBytes(name); + } + String getString(byte[] name) { + return zc.toString(name); + } + + protected void finalize() throws IOException { + close(); + } + + private long getDataPos(Entry e) throws IOException { + if (e.locoff == -1) { + Entry e2 = getEntry0(e.name); + if (e2 == null) + throw new ZipException("invalid loc for entry <" + e.name + ">"); + e.locoff = e2.locoff; + } + byte[] buf = new byte[LOCHDR]; + if (readFullyAt(buf, 0, buf.length, e.locoff) != buf.length) + throw new ZipException("invalid loc for entry <" + e.name + ">"); + return locpos + e.locoff + LOCHDR + LOCNAM(buf) + LOCEXT(buf); + } + + // Reads len bytes of data from the specified offset into buf. + // Returns the total number of bytes read. + // Each/every byte read from here (except the cen, which is mapped). + private long readFullyAt(byte[] buf, int off, long len, long pos) + throws IOException + { + ByteBuffer bb = ByteBuffer.wrap(buf); + bb.position(off); + bb.limit((int)(off + len)); + return readFullyAt(bb, pos); + } + + private long readFullyAt(ByteBuffer bb, long pos) + throws IOException + { + synchronized(ch) { + return ch.position(pos).read(bb); + } + } + + // Searches for end of central directory (END) header. The contents of + // the END header will be read and placed in endbuf. Returns the file + // position of the END header, otherwise returns -1 if the END header + // was not found or an error occurred. + private END findEND() throws IOException + { + byte[] buf = new byte[READBLOCKSZ]; + long ziplen = ch.size(); + long minHDR = (ziplen - END_MAXLEN) > 0 ? ziplen - END_MAXLEN : 0; + long minPos = minHDR - (buf.length - ENDHDR); + + for (long pos = ziplen - buf.length; pos >= minPos; pos -= (buf.length - ENDHDR)) + { + int off = 0; + if (pos < 0) { + // Pretend there are some NUL bytes before start of file + off = (int)-pos; + Arrays.fill(buf, 0, off, (byte)0); + } + int len = buf.length - off; + if (readFullyAt(buf, off, len, pos + off) != len) + zerror("zip END header not found"); + + // Now scan the block backwards for END header signature + for (int i = buf.length - ENDHDR; i >= 0; i--) { + if (buf[i+0] == (byte)'P' && + buf[i+1] == (byte)'K' && + buf[i+2] == (byte)'\005' && + buf[i+3] == (byte)'\006' && + (pos + i + ENDHDR + ENDCOM(buf, i) == ziplen)) { + // Found END header + buf = Arrays.copyOfRange(buf, i, i + ENDHDR); + END end = new END(); + end.endsub = ENDSUB(buf); + end.centot = ENDTOT(buf); + end.cenlen = ENDSIZ(buf); + end.cenoff = ENDOFF(buf); + end.comlen = ENDCOM(buf); + end.endpos = pos + i; + if (end.cenlen == ZIP64_MINVAL || + end.cenoff == ZIP64_MINVAL || + end.centot == ZIP64_MINVAL32) + { + // need to find the zip64 end; + byte[] loc64 = new byte[ZIP64_LOCHDR]; + if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR) + != loc64.length) { + return end; + } + long end64pos = ZIP64_LOCOFF(loc64); + byte[] end64buf = new byte[ZIP64_ENDHDR]; + if (readFullyAt(end64buf, 0, end64buf.length, end64pos) + != end64buf.length) { + return end; + } + // end64 found, re-calcualte everything. + end.cenlen = ZIP64_ENDSIZ(end64buf); + end.cenoff = ZIP64_ENDOFF(end64buf); + end.centot = (int)ZIP64_ENDTOT(end64buf); // assume total < 2g + end.endpos = end64pos; + } + return end; + } + } + } + zerror("zip END header not found"); + return null; //make compiler happy + } + + // Reads zip file central directory. Returns the file position of first + // CEN header, otherwise returns -1 if an error occured. If zip->msg != NULL + // then the error was a zip format error and zip->msg has the error text. + // Always pass in -1 for knownTotal; it's used for a recursive call. + private long initCEN() throws IOException { + end = findEND(); + if (end.endpos == 0) { + inodes = new LinkedHashMap(10); + locpos = 0; + return 0; // only END header present + } + if (end.cenlen > end.endpos) + zerror("invalid END header (bad central directory size)"); + long cenpos = end.endpos - end.cenlen; // position of CEN table + + // Get position of first local file (LOC) header, taking into + // account that there may be a stub prefixed to the zip file. + locpos = cenpos - end.cenoff; + if (locpos < 0) + zerror("invalid END header (bad central directory offset)"); + + // read in the CEN and END + cen = ByteBuffer.allocate((int)(end.cenlen + ENDHDR)); + if (readFullyAt(cen, cenpos) != end.cenlen + ENDHDR) { + zerror("read CEN tables failed"); + } + cen.order(ByteOrder.LITTLE_ENDIAN).flip(); + + // Iterate through the entries in the central directory + inodes = new LinkedHashMap(end.centot + 1); + int pos = 0; + int limit = cen.remaining() - ENDHDR; + int i = 0; + byte[] bBuf = new byte[1024]; + while (pos < limit) { + if (CENSIG(cen, pos) != CENSIG) + zerror("invalid CEN header (bad signature)"); + int method = CENHOW(cen, pos); + int nlen = CENNAM(cen, pos); + int elen = CENEXT(cen, pos); + int clen = CENCOM(cen, pos); + if ((CENFLG(cen, pos) & 1) != 0) + zerror("invalid CEN header (encrypted entry)"); + if (method != METHOD_STORED && method != METHOD_DEFLATED) + zerror("invalid CEN header (bad compression method: " + method + ")"); + if (pos + CENHDR + nlen > limit) + zerror("invalid CEN header (bad header size)"); + if (bBuf.length < nlen) + bBuf = new byte[nlen]; + cen.position(pos + CENHDR); + byte[] name = new byte[nlen]; + cen.get(name); + inodes.put(new EntryName(name), new IndexNode(name, pos)); + // skip ext and comment + cen.position(pos += (CENHDR + nlen + elen + clen)); + i++; + } + if (cen.remaining() != ENDHDR) { + zerror("invalid CEN header (bad header size)"); + } + dirs = null; // clear the dir map + return cenpos; + } + + private void ensureOpen() throws IOException { + if (!isOpen) + throw new ClosedFileSystemException(); + } + + // Creates a new empty temporary file in the same directory as the + // specified file. A variant of File.createTempFile. + private static Path createTempFileInSameDirectoryAs(Path path) + throws IOException + { + Path parent = path.toAbsolutePath().getParent(); + String dir = (parent == null)? "." : parent.toString(); + return File.createTempFile("zipfstmp", null, new File(dir)).toPath(); + } + + ////////////////////update & sync ////////////////////////////////////// + + private boolean hasUpdate = false; + private void updateDelete(Entry e) { + EntryName en = new EntryName(e.name); + inodes.remove(en); + hasUpdate = true; + } + + private void update(Entry e) { + EntryName en = new EntryName(e.name); + inodes.put(en, e); + hasUpdate = true; + } + + // copy over the whole LOC entry (header if necessary, data and ext) from + // old zip to the new one. + private long copyLOCEntry(Entry e, boolean updateHeader, + OutputStream os, + long written, byte[] buf) + throws IOException + { + long locoff = e.locoff; // where to read + e.locoff = written; // update the e.locoff with new value + + // calculate the size need to write out + long size = 0; + // if there is A ext + if ((e.flag & FLAG_DATADESCR) != 0) { + if (e.size >= ZIP64_MINVAL || e.csize >= ZIP64_MINVAL) + size = 24; + else + size = 16; + } + if (updateHeader) { // if we need update the loc header + locoff += LOCHDR + e.nlen + e.elen; // skip header + size += e.csize; + written = e.writeLOC(os) + size; + } else { + size += LOCHDR + e.nlen + e.elen + e.csize; + written = size; + } + int n; + while (size > 0 && + (n = (int)readFullyAt(buf, 0, buf.length, locoff)) != -1) + { + if (size < n) + n = (int)size; + os.write(buf, 0, n); + size -= n; + locoff += n; + } + return written; + } + + // sync the zip file system, if there is any udpate + private void sync() throws IOException { + assert Thread.holdsLock(this); + + // check ex-closer + if (!exChClosers.isEmpty()) { + for (ExChannelCloser ecc : exChClosers) { + if (ecc.streams.isEmpty()) { + ecc.ch.close(); + ecc.path.delete(); + exChClosers.remove(ecc); + } + } + } + if (!hasUpdate) + return; + + Path tmpFile = createTempFileInSameDirectoryAs(zfpath); + OutputStream os = tmpFile.newOutputStream(WRITE); + ArrayList elist = new ArrayList<>(inodes.size()); + long written = 0; + byte[] buf = new byte[8192]; + Entry e = null; + + // write loc + for (IndexNode inode : inodes.values()) { + if (inode instanceof Entry) { // an updated inode + e = (Entry)inode; + try { + if (e.type == Entry.COPY) { + // entry copy: the only thing changed is the "name" + // and "nlen" in LOC header, so we udpate/rewrite the + // LOC in new file and simply copy the rest (data and + // ext) without enflating/deflating from the old zip + // file LOC entry. + written += copyLOCEntry(e, true, os, written, buf); + } else { // NEW or FILECH + e.locoff = written; + written += e.writeLOC(os); // write loc header + if (e.bytes != null) { // in-memory, deflated + os.write(e.bytes); // already + written += e.bytes.length; + } else if (e.file != null) { // tmp file + InputStream is = e.file.newInputStream(); + int n; + if (e.type == Entry.NEW) { // deflated already + while ((n = is.read(buf)) != -1) { + os.write(buf, 0, n); + written += n; + } + } else if (e.type == Entry.FILECH) { + // the data are not deflated, use ZEOS + OutputStream os2 = new EntryOutputStream(e, os); + while ((n = is.read(buf)) != -1) { + os2.write(buf, 0, n); + } + os2.close(); + written += e.csize; + if ((e.flag & FLAG_DATADESCR) != 0) + written += e.writeEXT(os); + } + is.close(); + e.file.delete(); + tmppaths.remove(e.file); + } else { + // dir, 0-length data + } + } + elist.add(e); + } catch (IOException x) { + x.printStackTrace(); // skip any in-accurate entry + } + } else { // unchanged inode + e = Entry.readCEN(cen, inode.pos); + try { + written += copyLOCEntry(e, false, os, written, buf); + elist.add(e); + } catch (IOException x) { + x.printStackTrace(); // skip any wrong entry + } + } + } + + // now write back the cen and end table + end.cenoff = written; + for (Entry entry : elist) { + written += entry.writeCEN(os); + } + end.centot = elist.size(); + end.cenlen = written - end.cenoff; + end.write(os, written); + os.close(); + + if (!streams.isEmpty()) { + // There are outstanding input streams open on existing "ch", + // so, don't close the "cha" and delete the "file for now, let + // the "ex-channel-closer" to handle them + ExChannelCloser ecc = new ExChannelCloser( + createTempFileInSameDirectoryAs(zfpath), + ch, + streams); + zfpath.moveTo(ecc.path, REPLACE_EXISTING); + exChClosers.add(ecc); + streams = Collections.synchronizedSet(new HashSet()); + } else { + ch.close(); + zfpath.delete(); + } + tmpFile.moveTo(zfpath, REPLACE_EXISTING); + hasUpdate = false; // clear + + if (isOpen) { + ch = zfpath.newByteChannel(READ); // re-fresh "ch" and "cen" + initCEN(); + } + //System.out.println("->sync() done!"); + } + + private Entry getEntry0(byte[] path) throws IOException { + assert Thread.holdsLock(this); + + if (path == null) + throw new NullPointerException("path"); + if (path.length == 0) + return null; + EntryName en = new EntryName(path); + IndexNode inode = null; + synchronized (lock) { + ensureOpen(); + if ((inode = inodes.get(en)) == null) { + if (path[path.length -1] == '/') // already has a slash + return null; + path = Arrays.copyOf(path, path.length + 1); + path[path.length - 1] = '/'; + en.name(path); + if ((inode = inodes.get(en)) == null) + return null; + } + if (inode instanceof Entry) + return (Entry)inode; + return Entry.readCEN(cen, inode.pos); + } + } + + // Test if the "name" a parent directory of any entry (dir empty) + boolean isAncestor(byte[] name) { + for (Map.Entry entry : inodes.entrySet()) { + byte[] ename = entry.getKey().name; + if (isParentOf(name, ename)) + return true; + } + return false; + } + + public void deleteFile(byte[] path, boolean failIfNotExists) + throws IOException + { + checkWritable(); + synchronized(lock) { + Entry e = getEntry0(path); + if (e == null) { + if (path != null && path.length == 0) + throw new ZipException("root directory can't not be delete"); + if (failIfNotExists) + throw new NoSuchFileException(getString(path)); + } else { + if (e.isDir() && isAncestor(path)) + throw new DirectoryNotEmptyException(getString(path)); + updateDelete(e); + } + } + } + + private static void copyStream(InputStream is, OutputStream os) + throws IOException + { + byte[] copyBuf = new byte[8192]; + int n; + while ((n = is.read(copyBuf)) != -1) { + os.write(copyBuf, 0, n); + } + } + + // Returns an out stream for either + // (1) writing the contents of a new entry, if the entry exits, or + // (2) updating/replacing the contents of the specified existing entry. + private OutputStream getOutputStream(Entry e) throws IOException { + + ensureOpen(); + if (e.mtime == -1) + e.mtime = javaToDosTime(System.currentTimeMillis()); + if (e.method == -1) + e.method = METHOD_DEFLATED; // TBD: use default method + // store size, compressed size, and crc-32 in LOC header + e.flag = 0; + if (zc.isUTF8()) + e.flag |= FLAG_EFS; + OutputStream os; + if (useTempFile) { + e.file = getTempPathForEntry(null); + os = e.file.newOutputStream(WRITE); + } else { + os = new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192); + } + return new EntryOutputStream(e, os); + } + + private InputStream getInputStream(Entry e) + throws IOException + { + InputStream eis = null; + + if (e.type == Entry.NEW) { + if (e.bytes != null) + eis = new ByteArrayInputStream(e.bytes); + else if (e.file != null) + eis = e.file.newInputStream(); + else + throw new ZipException("update entry data is missing"); + } else if (e.type == Entry.FILECH) { + // FILECH result is un-compressed. + eis = e.file.newInputStream(); + // TBD: wrap to hook close() + // streams.add(eis); + return eis; + } else { // untouced CEN or COPY + eis = new EntryInputStream(e, ch); + } + if (e.method == METHOD_DEFLATED) { + // MORE: Compute good size for inflater stream: + long bufSize = e.size + 2; // Inflater likes a bit of slack + if (bufSize > 65536) + bufSize = 8192; + final long size = e.size;; + eis = new InflaterInputStream(eis, getInflater(), (int)bufSize) { + + private boolean isClosed = false; + public void close() throws IOException { + if (!isClosed) { + releaseInflater(inf); + this.in.close(); + isClosed = true; + } + } + // Override fill() method to provide an extra "dummy" byte + // at the end of the input stream. This is required when + // using the "nowrap" Inflater option. (it appears the new + // zlib in 7 does not need it, but keep it for now) + protected void fill() throws IOException { + if (eof) { + throw new EOFException( + "Unexpected end of ZLIB input stream"); + } + len = this.in.read(buf, 0, buf.length); + if (len == -1) { + buf[0] = 0; + len = 1; + eof = true; + } + inf.setInput(buf, 0, len); + } + private boolean eof; + + public int available() throws IOException { + if (isClosed) + return 0; + long avail = size - inf.getBytesWritten(); + return avail > (long) Integer.MAX_VALUE ? + Integer.MAX_VALUE : (int) avail; + } + }; + } else if (e.method != METHOD_STORED) { + throw new ZipException("invalid compression method"); + } + streams.add(eis); + return eis; + } + + // Inner class implementing the input stream used to read + // a (possibly compressed) zip file entry. + private class EntryInputStream extends InputStream { + private SeekableByteChannel zfch; // local ref to zipfs's "ch". zipfs.ch might + // point to a new channel after sync() + private long pos; // current position within entry data + protected long rem; // number of remaining bytes within entry + protected long size; // uncompressed size of this entry + + EntryInputStream(Entry e, SeekableByteChannel zfch) + throws IOException + { + this.zfch = zfch; + rem = e.csize; + size = e.size; + pos = getDataPos(e); + } + public int read(byte b[], int off, int len) throws IOException { + ensureOpen(); + if (rem == 0) { + return -1; + } + if (len <= 0) { + return 0; + } + if (len > rem) { + len = (int) rem; + } + // readFullyAt() + long n = 0; + ByteBuffer bb = ByteBuffer.wrap(b); + bb.position(off); + bb.limit(off + len); + synchronized(zfch) { + n = zfch.position(pos).read(bb); + } + if (n > 0) { + pos += n; + rem -= n; + } + if (rem == 0) { + close(); + } + return (int)n; + } + public int read() throws IOException { + byte[] b = new byte[1]; + if (read(b, 0, 1) == 1) { + return b[0] & 0xff; + } else { + return -1; + } + } + public long skip(long n) throws IOException { + ensureOpen(); + if (n > rem) + n = rem; + pos += n; + rem -= n; + if (rem == 0) { + close(); + } + return n; + } + public int available() { + return rem > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) rem; + } + + public long size() { + return size; + } + public void close() { + rem = 0; + streams.remove(this); + } + } + + class EntryOutputStream extends DeflaterOutputStream + { + private CRC32 crc; + private Entry e; + private long written; + + EntryOutputStream(Entry e, OutputStream os) + throws IOException + { + super(os, getDeflater()); + if (e == null) + throw new NullPointerException("Zip entry is null"); + this.e = e; + crc = new CRC32(); + } + + @Override + public void write(byte b[], int off, int len) throws IOException { + if (e.type != Entry.FILECH) // only from sync + ensureOpen(); + if (off < 0 || len < 0 || off > b.length - len) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + switch (e.method) { + case METHOD_DEFLATED: + super.write(b, off, len); + break; + case METHOD_STORED: + written += len; + out.write(b, off, len); + break; + default: + throw new ZipException("invalid compression method"); + } + crc.update(b, off, len); + } + + @Override + public void close() throws IOException { + // TBD ensureOpen(); + switch (e.method) { + case METHOD_DEFLATED: + finish(); + e.size = def.getBytesRead(); + e.csize = def.getBytesWritten(); + e.crc = crc.getValue(); + break; + case METHOD_STORED: + // we already know that both e.size and e.csize are the same + e.size = e.csize = written; + e.crc = crc.getValue(); + break; + default: + throw new ZipException("invalid compression method"); + } + //crc.reset(); + if (out instanceof ByteArrayOutputStream) + e.bytes = ((ByteArrayOutputStream)out).toByteArray(); + + if (e.type == Entry.FILECH) { + releaseDeflater(def); + return; + } + super.close(); + releaseDeflater(def); + update(e); + } + } + + private static void zerror(String msg) { + throw new ZipError(msg); + } + + // Maxmum number of de/inflater we cache + private final int MAX_FLATER = 20; + // List of available Inflater objects for decompression + private List inflaters = new ArrayList<>(); + + // Gets an inflater from the list of available inflaters or allocates + // a new one. + private Inflater getInflater() { + synchronized (inflaters) { + int size = inflaters.size(); + if (size > 0) { + Inflater inf = (Inflater)inflaters.remove(size - 1); + return inf; + } else { + return new Inflater(true); + } + } + } + + // Releases the specified inflater to the list of available inflaters. + private void releaseInflater(Inflater inf) { + synchronized (inflaters) { + if (inflaters.size() < MAX_FLATER) { + inf.reset(); + inflaters.add(inf); + } else { + inf.end(); + } + } + } + + // List of available Deflater objects for compression + private List deflaters = new ArrayList<>(); + + // Gets an deflater from the list of available deflaters or allocates + // a new one. + private Deflater getDeflater() { + synchronized (deflaters) { + int size = deflaters.size(); + if (size > 0) { + Deflater def = (Deflater)deflaters.remove(size - 1); + return def; + } else { + return new Deflater(Deflater.DEFAULT_COMPRESSION, true); + } + } + } + + // Releases the specified inflater to the list of available inflaters. + private void releaseDeflater(Deflater def) { + synchronized (deflaters) { + if (inflaters.size() < MAX_FLATER) { + def.reset(); + deflaters.add(def); + } else { + def.end(); + } + } + } + + // End of central directory record + static class END { + int disknum; + int sdisknum; + int endsub; // endsub + int centot; // 4 bytes + long cenlen; // 4 bytes + long cenoff; // 4 bytes + int comlen; // comment length + byte[] comment; + + /* members of Zip64 end of central directory locator */ + int diskNum; + long endpos; + int disktot; + + void write(OutputStream os, long offset) throws IOException { + boolean hasZip64 = false; + long xlen = cenlen; + long xoff = cenoff; + if (xlen >= ZIP64_MINVAL) { + xlen = ZIP64_MINVAL; + hasZip64 = true; + } + if (xoff >= ZIP64_MINVAL) { + xoff = ZIP64_MINVAL; + hasZip64 = true; + } + int count = centot; + if (count >= ZIP64_MINVAL32) { + count = ZIP64_MINVAL32; + hasZip64 = true; + } + if (hasZip64) { + long off64 = offset; + //zip64 end of central directory record + writeInt(os, ZIP64_ENDSIG); // zip64 END record signature + writeLong(os, ZIP64_ENDHDR - 12); // size of zip64 end + writeShort(os, 45); // version made by + writeShort(os, 45); // version needed to extract + writeInt(os, 0); // number of this disk + writeInt(os, 0); // central directory start disk + writeLong(os, centot); // number of directory entires on disk + writeLong(os, centot); // number of directory entires + writeLong(os, cenlen); // length of central directory + writeLong(os, cenoff); // offset of central directory + + //zip64 end of central directory locator + writeInt(os, ZIP64_LOCSIG); // zip64 END locator signature + writeInt(os, 0); // zip64 END start disk + writeLong(os, off64); // offset of zip64 END + writeInt(os, 1); // total number of disks (?) + } + writeInt(os, ENDSIG); // END record signature + writeShort(os, 0); // number of this disk + writeShort(os, 0); // central directory start disk + writeShort(os, count); // number of directory entries on disk + writeShort(os, count); // total number of directory entries + writeInt(os, xlen); // length of central directory + writeInt(os, xoff); // offset of central directory + if (comment != null) { // zip file comment + writeShort(os, comment.length); + writeBytes(os, comment); + } else { + writeShort(os, 0); + } + } + } + + // wrapper for the byte[] name + static class EntryName { + byte[] name; + int hashcode; // node is hashable/hashed by its name + + public EntryName (byte[] name) { + name(name); + } + + void name(byte[] name) { + this.name = name; + this.hashcode = Arrays.hashCode(name); + } + + public boolean equals(Object other) { + if (!(other instanceof EntryName)) + return false; + return Arrays.equals(name, ((EntryName)other).name); + } + + public int hashCode() { + return hashcode; + } + } + + // can simply use Integer instead, if we don't use it to + // build a internal node tree. + static class IndexNode { + byte[] name; + int pos = -1; // postion in cen table, -1 menas the + // entry does not exists in zip file + IndexNode(byte[] name, int pos) { + this.name = name; + this.pos = pos; + } + + IndexNode() {} + + IndexNode sibling; + IndexNode child; // 1st child + } + + static class Entry extends IndexNode { + + static final int CEN = 1; // entry read from cen + static final int NEW = 2; // updated contents in bytes or file + static final int FILECH = 3; // fch update in "file" + static final int COPY = 4; // copy of a CEN entry + + byte[] bytes; // updated content bytes + Path file; // use tmp file to store bytes; + int type = CEN; // default is the entry read from cen + + // entry attributes + int version; + int flag; + int method = -1; // compression method + long mtime = -1; // last modification time (in DOS time) + long atime = -1; // last access time + long ctime = -1; // create time + long crc = -1; // crc-32 of entry data + long csize = -1; // compressed size of entry data + long size = -1; // uncompressed size of entry data + int nlen; + int elen; + byte[] extra; + + // loc + long startPos; + long endPos; // exclusive + + // cen + int versionMade; + int disk; + int attrs; + long attrsEx; + long locoff; + + int clen; + byte[] comment; + + // ZIP64 flag + boolean hasZip64; + + Entry() {} + + Entry(byte[] name) { + this.name = name; + //this.nlen = name.length; + this.mtime = javaToDosTime(System.currentTimeMillis()); + this.crc = 0; + this.size = 0; + this.csize = 0; + this.method = METHOD_DEFLATED; + } + + Entry(byte[] name, int type) { + this(name); + this.type = type; + } + + Entry (byte[] name, Path file, int type) { + this(name, type); + this.file = file; + this.method = METHOD_STORED; + } + + Entry(Entry e) { + this.version = e.version; + this.name = e.name; // copyOf? + this.nlen = e.nlen; + this.ctime = e.ctime; + this.atime = e.atime; + this.mtime = e.mtime; + this.crc = e.crc; + this.size = e.size; + this.csize = e.csize; + this.method = e.method; + this.extra = (e.extra == null)? + null:Arrays.copyOf(e.extra, e.extra.length); + this.elen = e.elen; + this.versionMade = e.versionMade; + this.disk = e.disk; + this.attrs = e.attrs; + this.attrsEx = e.attrsEx; + this.locoff = e.locoff; + this.clen = e.clen; + this.comment = (e.comment == null)? + null:Arrays.copyOf(e.comment, e.comment.length); + this.startPos = e.startPos; + this.endPos = e.endPos; + this.hasZip64 = e.hasZip64;; + } + + Entry (Entry e, int type) { + this(e); + this.type = type; + } + + boolean isDir() { + return name != null && + (name.length == 0 || + name[name.length - 1] == '/'); + } + + int version() throws ZipException { + if (method == METHOD_DEFLATED) + return 20; + else if (method == METHOD_STORED) + return 10; + throw new ZipException("unsupported compression method"); + } + + ///////////////////// CEN ////////////////////// + static Entry readCEN(ByteBuffer cen, int pos) throws IOException + { + return new Entry().cen(cen, pos); + } + + private Entry cen(ByteBuffer cen, int pos) throws IOException + { + if (CENSIG(cen, pos) != CENSIG) + zerror("invalid CEN header (bad signature)"); + versionMade = CENVEM(cen, pos); + version = CENVER(cen, pos); + flag = CENFLG(cen, pos); + method = CENHOW(cen, pos); + mtime = CENTIM(cen, pos); + crc = CENCRC(cen, pos); + csize = CENSIZ(cen, pos); + size = CENLEN(cen, pos); + nlen = CENNAM(cen, pos); + elen = CENEXT(cen, pos); + clen = CENCOM(cen, pos); + disk = CENDSK(cen, pos); + attrs = CENATT(cen, pos); + attrsEx = CENATX(cen, pos); + locoff = CENOFF(cen, pos); + + cen.position(pos + CENHDR); + name = new byte[nlen]; + cen.get(name); + + if (elen > 0) { + extra = new byte[elen]; + cen.get(extra); + if (csize == ZIP64_MINVAL || size == ZIP64_MINVAL || + locoff == ZIP64_MINVAL) { + int off = 0; + while (off + 4 < elen) { + // extra spec: HeaderID+DataSize+Data + int sz = SH(extra, off + 2); + if (SH(extra, off) == EXTID_ZIP64) { + off += 4; + if (size == ZIP64_MINVAL) { + // if invalid zip64 extra fields, just skip + if (sz < 8 || (off + 8) > elen) + break; + size = LL(extra, off); + sz -= 8; + off += 8; + } + if (csize == ZIP64_MINVAL) { + if (sz < 8 || (off + 8) > elen) + break; + csize = LL(extra, off); + sz -= 8; + off += 8; + } + if (locoff == ZIP64_MINVAL) { + if (sz < 8 || (off + 8) > elen) + break; + locoff = LL(extra, off); + sz -= 8; + off += 8; + } + break; + } + off += (sz + 4); + } + } + } + if (clen > 0) { + comment = new byte[clen]; + cen.get(comment); + } + return this; + } + + int writeCEN(OutputStream os) throws IOException + { + int written = CENHDR; + int version0 = version(); + + long csize0 = csize; + long size0 = size; + long locoff0 = locoff; + int e64len = 0; + + // confirm size/length + nlen = (name != null) ? name.length : 0; + elen = (extra != null) ? extra.length : 0; + clen = (comment != null) ? comment.length : 0; + + boolean hasZip64 = false; + if (csize >= ZIP64_MINVAL) { + csize0 = ZIP64_MINVAL; + e64len += 8; // csize(8) + hasZip64 = true; + } + if (size >= ZIP64_MINVAL) { + size0 = ZIP64_MINVAL; // size(8) + e64len += 8; + hasZip64 = true; + } + if (locoff >= ZIP64_MINVAL) { + locoff0 = ZIP64_MINVAL; + e64len += 8; // offset(8) + hasZip64 = true; + } + writeInt(os, CENSIG); // CEN header signature + if (hasZip64) { + writeShort(os, 45); // ver 4.5 for zip64 + writeShort(os, 45); + } else { + writeShort(os, version0); // version made by + writeShort(os, version0); // version needed to extract + } + writeShort(os, flag); // general purpose bit flag + writeShort(os, method); // compression method + writeInt(os, mtime); // last modification time + writeInt(os, crc); // crc-32 + writeInt(os, csize0); // compressed size + writeInt(os, size0); // uncompressed size + writeShort(os, name.length); + + if (hasZip64) { + // + headid(2) + datasize(2) + writeShort(os, e64len + 4 + elen); + } else { + writeShort(os, elen); + } + if (comment != null) { + writeShort(os, Math.min(clen, 0xffff)); + } else { + writeShort(os, 0); + } + writeShort(os, 0); // starting disk number + writeShort(os, 0); // internal file attributes (unused) + writeInt(os, 0); // external file attributes (unused) + writeInt(os, locoff0); // relative offset of local header + writeBytes(os, name); + if (hasZip64) { + writeShort(os, EXTID_ZIP64);// Zip64 extra + writeShort(os, e64len); + if (size0 == ZIP64_MINVAL) + writeLong(os, size); + if (csize0 == ZIP64_MINVAL) + writeLong(os, csize); + if (locoff0 == ZIP64_MINVAL) + writeLong(os, locoff); + } + if (extra != null) { + writeBytes(os, extra); + } + if (comment != null) { + //TBD: 0, Math.min(commentBytes.length, 0xffff)); + writeBytes(os, comment); + } + return CENHDR + nlen + elen + clen + (hasZip64?(e64len + 4):0); + } + + ///////////////////// LOC ////////////////////// + static Entry readLOC(ZipFileSystem zf, long pos) + throws IOException + { + return readLOC(zf, pos, new byte[1024]); + } + + static Entry readLOC(ZipFileSystem zf, long pos, byte[] buf) + throws IOException + { + return new Entry().loc(zf, pos, buf); + } + + Entry loc(ZipFileSystem zf, long pos, byte[] buf) + throws IOException + { + assert (buf.length >= LOCHDR); + if (zf.readFullyAt(buf, 0, LOCHDR , pos) != LOCHDR) { + throw new ZipException("loc: reading failed"); + } + if (LOCSIG(buf) != LOCSIG) { + throw new ZipException("loc: wrong sig ->" + + Long.toString(LOCSIG(buf), 16)); + } + startPos = pos; + version = LOCVER(buf); + flag = LOCFLG(buf); + method = LOCHOW(buf); + mtime = LOCTIM(buf); + crc = LOCCRC(buf); + csize = LOCSIZ(buf); + size = LOCLEN(buf); + nlen = LOCNAM(buf); + elen = LOCEXT(buf); + + name = new byte[nlen]; + if (zf.readFullyAt(name, 0, nlen, pos + LOCHDR) != nlen) { + throw new ZipException("loc: name reading failed"); + } + if (elen > 0) { + extra = new byte[elen]; + if (zf.readFullyAt(extra, 0, elen, pos + LOCHDR + nlen) + != elen) { + throw new ZipException("loc: ext reading failed"); + } + } + pos += (LOCHDR + nlen + elen); + if ((flag & FLAG_DATADESCR) != 0) { + // Data Descriptor + Entry e = zf.getEntry0(name); // get the size/csize from cen + if (e == null) + throw new ZipException("loc: name not found in cen"); + size = e.size; + csize = e.csize; + pos += (method == METHOD_STORED ? size : csize); + if (size >= ZIP64_MINVAL || csize >= ZIP64_MINVAL) + pos += 24; + else + pos += 16; + } else { + boolean hasZip64 = false; + if (extra != null && + (size == ZIP64_MINVAL || csize == ZIP64_MINVAL)) { + // zip64 ext: must include both size and csize + int off = 0; + while (off + 20 < elen) { // HeaderID+DataSize+Data + int sz = SH(extra, off + 2); + if (SH(extra, off) == EXTID_ZIP64 && sz == 16) { + size = LL(extra, off + 4); + csize = LL(extra, off + 12); + hasZip64 = true; + break; + } + off += (sz + 4); + } + } + pos += (method == METHOD_STORED ? size : csize); + } + endPos = pos; + return this; + } + + int writeLOC(OutputStream os) + throws IOException + { + writeInt(os, LOCSIG); // LOC header signature + + int version = version(); + if ((flag & FLAG_DATADESCR) != 0) { + writeShort(os, version()); // version needed to extract + writeShort(os, flag); // general purpose bit flag + writeShort(os, method); // compression method + writeInt(os, mtime); // last modification time + + // store size, uncompressed size, and crc-32 in data descriptor + // immediately following compressed entry data + writeInt(os, 0); + writeInt(os, 0); + writeInt(os, 0); + } else { + if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) { + hasZip64 = true; + writeShort(os, 45); // ver 4.5 for zip64 + } else { + writeShort(os, version()); // version needed to extract + } + writeShort(os, flag); // general purpose bit flag + writeShort(os, method); // compression method + writeInt(os, mtime); // last modification time + writeInt(os, crc); // crc-32 + if (hasZip64) { + writeInt(os, ZIP64_MINVAL); + writeInt(os, ZIP64_MINVAL); + //TBD: e.elen += 20; //headid(2) + size(2) + size(8) + csize(8) + } else { + writeInt(os, csize); // compressed size + writeInt(os, size); // uncompressed size + } + } + writeShort(os, name.length); + writeShort(os, elen + (hasZip64 ? 20 : 0)); + writeBytes(os, name); + if (hasZip64) { + // TBD: should we update extra directory? + writeShort(os, EXTID_ZIP64); + writeShort(os, 16); + writeLong(os, size); + writeLong(os, csize); + } + if (extra != null) { + writeBytes(os, extra); + } + return LOCHDR + name.length + elen + (hasZip64 ? 20 : 0); + } + + // Data Descriptior + int writeEXT(OutputStream os) + throws IOException + { + writeInt(os, EXTSIG); // EXT header signature + writeInt(os, crc); // crc-32 + if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) { + writeLong(os, csize); + writeLong(os, size); + return 24; + } else { + writeInt(os, csize); // compressed size + writeInt(os, size); // uncompressed size + return 16; + } + } + + // read NTFS, UNIX and ZIP64 data from cen.extra + void readExtra() { + if (extra == null) + return; + int elen = extra.length; + int off = 0; + while (off + 4 < elen) { + // extra spec: HeaderID+DataSize+Data + int sz = SH(extra, off + 2); + int tag = SH(extra, off); + off += 4; + int pos = off; + if (pos + sz > elen) // invalid data + break; + switch (tag) { + case EXTID_ZIP64 : + if (size == ZIP64_MINVAL) { + if (pos + 8 > elen) // invalid zip64 extra + break; // fields, just skip + size = LL(extra, pos); + pos += 8; + } + if (csize == ZIP64_MINVAL) { + if (pos + 8 > elen) + break; + csize = LL(extra, pos); + pos += 8; + } + if (locoff == ZIP64_MINVAL) { + if (pos + 8 > elen) + break; + locoff = LL(extra, pos); + pos += 8; + } + break; + case EXTID_NTFS: + pos += 4; // reserved 4 bytes + if (SH(extra, pos) != 0x0001) + break; + if (SH(extra, pos + 2) != 24) + break; + mtime = LL(extra, pos + 4); + atime = LL(extra, pos + 12); + ctime = LL(extra, pos + 20); + break; + case EXTID_UNIX: + atime = LG(extra, pos); + mtime = LG(extra, pos + 4); + break; + default: // unknow + } + off += sz; + } + } + } + + private static class ExChannelCloser { + Path path; + SeekableByteChannel ch; + Set streams; + ExChannelCloser(Path path, + SeekableByteChannel ch, + Set streams) + { + this.path = path; + this.ch = ch; + this.streams = streams; + } + } + + // ZIP directory has two issues: + // (1) ZIP spec does not require the ZIP file to include + // directory entry + // (2) all entries are not stored/organized in a "tree" + // structure. + // A possible solution is to build the node tree ourself as + // implemented below. + private HashMap dirs; + private IndexNode root; + private IndexNode addToDir(EntryName child) { + IndexNode cinode = dirs.get(child); + if (cinode != null) + return cinode; + + byte[] cname = child.name; + byte[] pname = getParent(cname); + IndexNode pinode; + + if (pname != null) + pinode = addToDir(new EntryName(pname)); + else + pinode = root; + cinode = inodes.get(child); + if (cname[cname.length -1] != '/') { // not a dir + cinode.sibling = pinode.child; + pinode.child = cinode; + return null; + } + cinode = dirs.get(child); + if (cinode == null) // pseudo directry entry + cinode = new IndexNode(cname, -1); + cinode.sibling = pinode.child; + pinode.child = cinode; + + dirs.put(child, cinode); + return cinode; + } + + private HashMap getDirs() + throws IOException + { + if (hasUpdate) + sync(); + if (dirs != null) + return dirs; + dirs = new HashMap(); + byte[] empty = new byte[0]; + root = new IndexNode(empty, -1); + dirs.put(new EntryName(empty), root); + + EntryName[] names = inodes.keySet().toArray(new EntryName[0]); + int i = names.length; + while (--i >= 0) { + addToDir(names[i]); + } + // for (int i EntryName en : inodes.keySet()) { + // addToDir(en); + // } + return dirs; + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java new file mode 100644 index 00000000000..a43b2cf7de3 --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.io.IOException; +import java.nio.channels.FileChannel; +import java.nio.file.FileRef; +import java.nio.file.FileSystem; +import java.nio.file.FileSystemNotFoundException; +import java.nio.file.FileSystemAlreadyExistsException; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.ProviderMismatchException; +import java.nio.file.attribute.FileAttribute; +import java.nio.file.spi.FileSystemProvider; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/* + * + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal + */ + +public class ZipFileSystemProvider extends FileSystemProvider { + private final Map filesystems = new HashMap<>(); + + public ZipFileSystemProvider() {} + + @Override + public String getScheme() { + return "zip"; + } + + protected Path uriToPath(URI uri) { + String scheme = uri.getScheme(); + if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) { + throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'"); + } + try { + return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null)) + .toAbsolutePath(); + } catch (URISyntaxException e) { + throw new AssertionError(e); //never thrown + } + } + + @Override + public FileSystem newFileSystem(URI uri, Map env) + throws IOException + { + return newFileSystem(uriToPath(uri), env); + } + + @Override + public FileSystem newFileSystem(FileRef file, Map env) + throws IOException + { + if (!(file instanceof Path)) + throw new UnsupportedOperationException(); + Path path = (Path)file; + if (!path.toUri().getScheme().equalsIgnoreCase("file")) { + throw new UnsupportedOperationException(); + } + return newFileSystem(path, env); + } + + private FileSystem newFileSystem(Path path, Map env) + throws IOException + { + synchronized(filesystems) { + if (filesystems.containsKey(path)) + throw new FileSystemAlreadyExistsException(); + ZipFileSystem zipfs = new ZipFileSystem(this, path, env); + filesystems.put(path, zipfs); + return zipfs; + } + } + + @Override + public Path getPath(URI uri) { + FileSystem fs = getFileSystem(uri); + String fragment = uri.getFragment(); + if (fragment == null) { + throw new IllegalArgumentException("URI: " + + uri + + " does not contain path fragment ex. zip:///c:/foo.zip#/BAR"); + } + return fs.getPath(fragment); + } + + @Override + public FileChannel newFileChannel(Path path, + Set options, + FileAttribute... attrs) + throws IOException + { + if (path == null) + throw new NullPointerException("path is null"); + if (path instanceof ZipPath) + return ((ZipPath)path).newFileChannel(options, attrs); + throw new ProviderMismatchException(); + } + + @Override + public FileSystem getFileSystem(URI uri) { + synchronized (filesystems) { + ZipFileSystem zipfs = filesystems.get(uriToPath(uri)); + if (zipfs == null) + throw new FileSystemNotFoundException(); + return zipfs; + } + } + + void removeFileSystem(Path zfpath) { + synchronized (filesystems) { + filesystems.remove(zfpath); + } + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java new file mode 100644 index 00000000000..741376daf0d --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.io.PrintStream; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import com.sun.nio.zipfs.ZipFileSystem.Entry; +import static com.sun.nio.zipfs.ZipConstants.*; +import static com.sun.nio.zipfs.ZipUtils.*; + +/** + * Print the loc and cen tables of the ZIP file + * + * @author Xueming Shen + */ + +public class ZipInfo { + + public static void main(String[] args) throws Throwable { + if (args.length < 2) { + print("Usage: java ZipInfo [cen|loc] zfname"); + } else { + Map env = Collections.emptyMap(); + ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider() + .newFileSystem(Paths.get(args[1]), env)); + + long pos = 0; + + if ("loc".equals(args[0])) { + print("[Local File Header]%n"); + byte[] buf = new byte[1024]; + for (int i = 0; i < zfs.getEntryNames().length; i++) { + Entry loc = Entry.readLOC(zfs, pos, buf); + print("--------loc[%x]--------%n", pos); + printLOC(loc); + pos = loc.endPos; + } + } if ("cen".equals(args[0])) { + int i = 0; + Iterator itr = zfs.inodes.values().iterator(); + print("[Central Directory Header]%n"); + while (itr.hasNext()) { + Entry cen = Entry.readCEN(zfs.cen, itr.next().pos); + print("--------cen[%d]--------%n", i); + printCEN(cen); + i++; + } + } + zfs.close(); + } + } + + static void print(String fmt, Object... objs) { + System.out.printf(fmt, objs); + } + + static void printLOC(Entry loc) { + print(" [%x, %x]%n", loc.startPos, loc.endPos); + print(" Signature : %8x%n", LOCSIG); + print(" Version : %4x [%d.%d]%n", + loc.version, loc. version/10, loc. version%10); + print(" Flag : %4x%n", loc.flag); + print(" Method : %4x%n", loc. method); + print(" LastMTime : %8x [%tc]%n", + loc.mtime, dosToJavaTime(loc.mtime)); + print(" CRC : %8x%n", loc.crc); + print(" CSize : %8x%n", loc.csize); + print(" Size : %8x%n", loc.size); + print(" NameLength : %4x [%s]%n", + loc.nlen, new String(loc.name)); + print(" ExtraLength : %4x%n", loc.elen); + if (loc.hasZip64) + print(" *ZIP64*%n"); + } + + static void printCEN(Entry cen) { + print(" Signature : %08x%n", CENSIG); + print(" VerMadeby : %4x [%d.%d]%n", + cen.versionMade, cen.versionMade/10, cen.versionMade%10); + print(" VerExtract : %4x [%d.%d]%n", + cen.version, cen.version/10, cen.version%10); + print(" Flag : %4x%n", cen.flag); + print(" Method : %4x%n", cen.method); + print(" LastMTime : %8x [%tc]%n", + cen.mtime, dosToJavaTime(cen.mtime)); + print(" CRC : %8x%n", cen.crc); + print(" CSize : %8x%n", cen.csize); + print(" Size : %8x%n", cen.size); + print(" NameLen : %4x [%s]%n", + cen.nlen, new String(cen.name)); + print(" ExtraLen : %4x%n", cen.elen); + print(" CommentLen : %4x%n", cen.clen); + print(" DiskStart : %4x%n", cen.disk); + print(" Attrs : %4x%n", cen.attrs); + print(" AttrsEx : %8x%n", cen.attrsEx); + print(" LocOff : %8x%n", cen.locoff); + if (cen.hasZip64) + print(" *ZIP64*%n"); + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java new file mode 100644 index 00000000000..1ceab8fc81a --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java @@ -0,0 +1,964 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.io.File; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URI; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.SeekableByteChannel; +import java.nio.file.*; +import java.nio.file.DirectoryStream.Filter; +import java.nio.file.spi.FileSystemProvider; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.FileAttribute; +import java.nio.file.attribute.FileAttributeView; +import java.nio.file.attribute.FileTime; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import static java.nio.file.StandardOpenOption.*; +import static java.nio.file.StandardCopyOption.*; + +/** + * + * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal + */ + +public class ZipPath extends Path { + + private final ZipFileSystem zfs; + private final byte[] path; + private volatile int[] offsets; + private int hashcode = 0; // cached hashcode (created lazily) + + ZipPath(ZipFileSystem zfs, byte[] path) { + this(zfs, path, false); + } + + ZipPath(ZipFileSystem zfs, byte[] path, boolean normalized) + { + this.zfs = zfs; + if (normalized) + this.path = path; + else + this.path = normalize(path); + } + + @Override + public ZipPath getRoot() { + if (this.isAbsolute()) + return new ZipPath(zfs, new byte[]{path[0]}); + else + return null; + } + + @Override + public Path getName() { + initOffsets(); + int count = offsets.length; + if (count == 0) + return null; // no elements so no name + if (count == 1 && path[0] != '/') + return this; + int lastOffset = offsets[count-1]; + int len = path.length - lastOffset; + byte[] result = new byte[len]; + System.arraycopy(path, lastOffset, result, 0, len); + return new ZipPath(zfs, result); + } + + @Override + public ZipPath getParent() { + initOffsets(); + int count = offsets.length; + if (count == 0) // no elements so no parent + return null; + int len = offsets[count-1] - 1; + if (len <= 0) // parent is root only (may be null) + return getRoot(); + byte[] result = new byte[len]; + System.arraycopy(path, 0, result, 0, len); + return new ZipPath(zfs, result); + } + + @Override + public int getNameCount() { + initOffsets(); + return offsets.length; + } + + @Override + public ZipPath getName(int index) { + initOffsets(); + if (index < 0 || index >= offsets.length) + throw new IllegalArgumentException(); + int begin = offsets[index]; + int len; + if (index == (offsets.length-1)) + len = path.length - begin; + else + len = offsets[index+1] - begin - 1; + // construct result + byte[] result = new byte[len]; + System.arraycopy(path, begin, result, 0, len); + return new ZipPath(zfs, result); + } + + @Override + public ZipPath subpath(int beginIndex, int endIndex) { + initOffsets(); + if (beginIndex < 0 || + beginIndex >= offsets.length || + endIndex > offsets.length || + beginIndex >= endIndex) + throw new IllegalArgumentException(); + + // starting offset and length + int begin = offsets[beginIndex]; + int len; + if (endIndex == offsets.length) + len = path.length - begin; + else + len = offsets[endIndex] - begin - 1; + // construct result + byte[] result = new byte[len]; + System.arraycopy(path, begin, result, 0, len); + return new ZipPath(zfs, result); + } + + @Override + public ZipPath toRealPath(boolean resolveLinks) throws IOException { + ZipPath realPath = new ZipPath(zfs, getResolvedPath()); + realPath.checkAccess(); + return realPath; + } + + @Override + public boolean isHidden() { + return false; + } + + @Override + public ZipPath toAbsolutePath() { + if (isAbsolute()) { + return this; + } else { + //add / bofore the existing path + byte[] defaultdir = zfs.getDefaultDir().path; + int defaultlen = defaultdir.length; + boolean endsWith = (defaultdir[defaultlen - 1] == '/'); + byte[] t = null; + if (endsWith) + t = new byte[defaultlen + path.length]; + else + t = new byte[defaultlen + 1 + path.length]; + System.arraycopy(defaultdir, 0, t, 0, defaultlen); + if (!endsWith) + t[defaultlen++] = '/'; + System.arraycopy(path, 0, t, defaultlen, path.length); + return new ZipPath(zfs, t, true); // normalized + } + } + + @Override + public URI toUri() { + String zfPath = zfs.toString(); + if (File.separatorChar == '\\') // replace all separators by '/' + zfPath = "/" + zfPath.replace("\\", "/"); + try { + return new URI("zip", "", + zfPath, + zfs.getString(toAbsolutePath().path)); + } catch (Exception ex) { + throw new AssertionError(ex); + } + } + + private boolean equalsNameAt(ZipPath other, int index) { + int mbegin = offsets[index]; + int mlen = 0; + if (index == (offsets.length-1)) + mlen = path.length - mbegin; + else + mlen = offsets[index + 1] - mbegin - 1; + int obegin = other.offsets[index]; + int olen = 0; + if (index == (other.offsets.length - 1)) + olen = other.path.length - obegin; + else + olen = other.offsets[index + 1] - obegin - 1; + if (mlen != olen) + return false; + int n = 0; + while(n < mlen) { + if (path[mbegin + n] != other.path[obegin + n]) + return false; + n++; + } + return true; + } + + @Override + public Path relativize(Path other) { + final ZipPath o = checkPath(other); + if (o.equals(this)) + return null; + if (/* this.getFileSystem() != o.getFileSystem() || */ + this.isAbsolute() != o.isAbsolute()) { + throw new IllegalArgumentException(); + } + int mc = this.getNameCount(); + int oc = o.getNameCount(); + int n = Math.min(mc, oc); + int i = 0; + while (i < n) { + if (!equalsNameAt(o, i)) + break; + i++; + } + int dotdots = mc - i; + int len = dotdots * 3 - 1; + if (i < oc) + len += (o.path.length - o.offsets[i] + 1); + byte[] result = new byte[len]; + + int pos = 0; + while (dotdots > 0) { + result[pos++] = (byte)'.'; + result[pos++] = (byte)'.'; + if (pos < len) // no tailing slash at the end + result[pos++] = (byte)'/'; + dotdots--; + } + if (i < oc) + System.arraycopy(o.path, o.offsets[i], + result, pos, + o.path.length - o.offsets[i]); + return new ZipPath(getFileSystem(), result); + } + + @Override + public ZipFileSystem getFileSystem() { + return zfs; + } + + @Override + public boolean isAbsolute() { + return (this.path[0] == '/'); + } + + @Override + public ZipPath resolve(Path other) { + if (other == null) + return this; + final ZipPath o = checkPath(other); + if (o.isAbsolute()) + return o; + byte[] resolved = null; + if (this.path[path.length - 1] == '/') { + resolved = new byte[path.length + o.path.length]; + System.arraycopy(path, 0, resolved, 0, path.length); + System.arraycopy(o.path, 0, resolved, path.length, o.path.length); + } else { + resolved = new byte[path.length + 1 + o.path.length]; + System.arraycopy(path, 0, resolved, 0, path.length); + resolved[path.length] = '/'; + System.arraycopy(o.path, 0, resolved, path.length + 1, o.path.length); + } + return new ZipPath(zfs, resolved); + } + + @Override + public ZipPath resolve(String other) { + return resolve(getFileSystem().getPath(other)); + } + + @Override + public boolean startsWith(Path other) { + final ZipPath o = checkPath(other); + if (o.isAbsolute() != this.isAbsolute()) + return false; + final int oCount = o.getNameCount(); + if (getNameCount() < oCount) + return false; + for (int i = 0; i < oCount; i++) { + if (!o.getName(i).equals(getName(i))) + return false; + } + return true; + } + + @Override + public boolean endsWith(Path other) { + final ZipPath o = checkPath(other); + if (o.isAbsolute()) + return this.isAbsolute() ? this.equals(o) : false; + int i = o.getNameCount(); + int j = this.getNameCount(); + if (j < i) + return false; + for (--i, --j; i >= 0; i--, j--) { + if (!o.getName(i).equals(this.getName(j))) + return false; + } + return true; + } + + @Override + public Path normalize() { + byte[] resolved = getResolved(); + if (resolved == path) // no change + return this; + if (resolved.length == 0) + return null; + return new ZipPath(zfs, resolved, true); + } + + private ZipPath checkPath(Path path) { + if (path == null) + throw new NullPointerException(); + if (!(path instanceof ZipPath)) + throw new ProviderMismatchException(); + return (ZipPath) path; + } + + // create offset list if not already created + private void initOffsets() { + if (offsets == null) { + int count, index; + // count names + count = 0; + index = 0; + while (index < path.length) { + byte c = path[index++]; + if (c != '/') { + count++; + while (index < path.length && path[index] != '/') + index++; + } + } + // populate offsets + int[] result = new int[count]; + count = 0; + index = 0; + while (index < path.length) { + byte c = path[index]; + if (c == '/') { + index++; + } else { + result[count++] = index++; + while (index < path.length && path[index] != '/') + index++; + } + } + synchronized (this) { + if (offsets == null) + offsets = result; + } + } + } + + // resolved path for locating zip entry inside the zip file, + // the result path does not contain ./ and .. components + private volatile byte[] resolved = null; + byte[] getResolvedPath() { + byte[] r = resolved; + if (r == null) { + if (isAbsolute()) + r = getResolved(); + else + r = toAbsolutePath().getResolvedPath(); + if (r[0] == '/') + r = Arrays.copyOfRange(r, 1, r.length); + resolved = r; + } + return resolved; + } + + // removes redundant slashs, replace "\" to zip separator "/" + // and check for invalid characters + private byte[] normalize(byte[] path) { + if (path.length == 0) + return path; + byte prevC = 0; + for (int i = 0; i < path.length; i++) { + byte c = path[i]; + if (c == '\\') + return normalize(path, i); + if (c == (byte)'/' && prevC == '/') + return normalize(path, i - 1); + if (c == '\u0000') + throw new InvalidPathException(zfs.getString(path), + "Path: nul character not allowed"); + prevC = c; + } + return path; + } + + private byte[] normalize(byte[] path, int off) { + byte[] to = new byte[path.length]; + int n = 0; + while (n < off) { + to[n] = path[n]; + n++; + } + int m = n; + byte prevC = 0; + while (n < path.length) { + byte c = path[n++]; + if (c == (byte)'\\') + c = (byte)'/'; + if (c == (byte)'/' && prevC == (byte)'/') + continue; + if (c == '\u0000') + throw new InvalidPathException(zfs.getString(path), + "Path: nul character not allowed"); + to[m++] = c; + prevC = c; + } + if (m > 1 && to[m - 1] == '/') + m--; + return (m == to.length)? to : Arrays.copyOf(to, m); + } + + // Remove DotSlash(./) and resolve DotDot (..) components + private byte[] getResolved() { + if (path.length == 0) + return path; + for (int i = 0; i < path.length; i++) { + byte c = path[i]; + if (c == (byte)'.') + return resolve0(); + } + return path; + } + + // TBD: performance, avoid initOffsets + private byte[] resolve0() { + byte[] to = new byte[path.length]; + int nc = getNameCount(); + int[] lastM = new int[nc]; + int lastMOff = -1; + int m = 0; + for (int i = 0; i < nc; i++) { + int n = offsets[i]; + int len = (i == offsets.length - 1)? + (path.length - n):(offsets[i + 1] - n - 1); + if (len == 1 && path[n] == (byte)'.') + continue; + if (len == 2 && path[n] == '.' && path[n + 1] == '.') { + if (lastMOff >= 0) { + m = lastM[lastMOff--]; // retreat + continue; + } + if (path[0] == '/') { // "/../xyz" skip + if (m == 0) + to[m++] = '/'; + } else { // "../xyz" -> "../xyz" + if (m != 0 && to[m-1] != '/') + to[m++] = '/'; + while (len-- > 0) + to[m++] = path[n++]; + } + continue; + } + if (m == 0 && path[0] == '/' || // absolute path + m != 0 && to[m-1] != '/') { // not the first name + to[m++] = '/'; + } + lastM[++lastMOff] = m; + while (len-- > 0) + to[m++] = path[n++]; + } + if (m > 1 && to[m - 1] == '/') + m--; + return (m == to.length)? to : Arrays.copyOf(to, m); + } + + @Override + public String toString() { + return zfs.getString(path); + } + + @Override + public int hashCode() { + int h = hashcode; + if (h == 0) + hashcode = h = Arrays.hashCode(path); + return h; + } + + @Override + public boolean equals(Object obj) { + return obj != null && + obj instanceof ZipPath && + this.zfs == ((ZipPath)obj).zfs && + compareTo((Path) obj) == 0; + } + + @Override + public int compareTo(Path other) { + final ZipPath o = checkPath(other); + int len1 = this.path.length; + int len2 = o.path.length; + + int n = Math.min(len1, len2); + byte v1[] = this.path; + byte v2[] = o.path; + + int k = 0; + while (k < n) { + int c1 = v1[k] & 0xff; + int c2 = v2[k] & 0xff; + if (c1 != c2) + return c1 - c2; + k++; + } + return len1 - len2; + } + + @Override + public Path createSymbolicLink( + Path target, FileAttribute... attrs) throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Path createLink( + Path existing) throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Path readSymbolicLink() throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Path createDirectory(FileAttribute... attrs) + throws IOException + { + zfs.createDirectory(getResolvedPath(), attrs); + return this; + } + + public final Path createFile(FileAttribute... attrs) + throws IOException + { + OutputStream os = newOutputStream(CREATE_NEW, WRITE); + try { + os.close(); + } catch (IOException x) {} + return this; + } + + @Override + public InputStream newInputStream(OpenOption... options) + throws IOException { + if (options.length > 0) { + for (OpenOption opt : options) { + if (opt != READ) + throw new UnsupportedOperationException("'" + opt + "' not allowed"); + } + } + return zfs.newInputStream(getResolvedPath()); + } + + private static final DirectoryStream.Filter acceptAllFilter = + new DirectoryStream.Filter() { + @Override public boolean accept(Path entry) { return true; } + }; + + @Override + public final DirectoryStream newDirectoryStream() throws IOException { + return newDirectoryStream(acceptAllFilter); + } + + @Override + public DirectoryStream newDirectoryStream(Filter filter) + throws IOException + { + return new ZipDirectoryStream(this, filter); + } + + @Override + public final DirectoryStream newDirectoryStream(String glob) + throws IOException + { + // avoid creating a matcher if all entries are required. + if (glob.equals("*")) + return newDirectoryStream(); + + // create a matcher and return a filter that uses it. + final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob); + DirectoryStream.Filter filter = new DirectoryStream.Filter() { + @Override + public boolean accept(Path entry) { + return matcher.matches(entry.getName()); + } + }; + return newDirectoryStream(filter); + } + + @Override + public final void delete() throws IOException { + zfs.deleteFile(getResolvedPath(), true); + } + + @Override + public final void deleteIfExists() throws IOException { + zfs.deleteFile(getResolvedPath(), false); + } + + ZipFileAttributes getAttributes() throws IOException + { + ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath()); + if (zfas == null) + throw new NoSuchFileException(toString()); + return zfas; + } + + @Override + @SuppressWarnings("unchecked") + public V getFileAttributeView(Class type, + LinkOption... options) + { + return (V)ZipFileAttributeView.get(this, type); + } + + @Override + public void setAttribute(String attribute, + Object value, + LinkOption... options) + throws IOException + { + String type = null; + String attr = null; + int colonPos = attribute.indexOf(':'); + if (colonPos == -1) { + type = "basic"; + attr = attribute; + } else { + type = attribute.substring(0, colonPos++); + attr = attribute.substring(colonPos); + } + ZipFileAttributeView view = ZipFileAttributeView.get(this, type); + if (view == null) + throw new UnsupportedOperationException("view <" + view + "> is not supported"); + view.setAttribute(attr, value); + } + + void setTimes(FileTime mtime, FileTime atime, FileTime ctime) + throws IOException + { + zfs.setTimes(getResolvedPath(), mtime, atime, ctime); + } + + private Object getAttributesImpl(String attribute, boolean domap) + throws IOException + { + String view = null; + String attr = null; + int colonPos = attribute.indexOf(':'); + if (colonPos == -1) { + view = "basic"; + attr = attribute; + } else { + view = attribute.substring(0, colonPos++); + attr = attribute.substring(colonPos); + } + ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view); + if (zfv == null) { + throw new UnsupportedOperationException("view not supported"); + } + return zfv.getAttribute(attr, domap); + } + + @Override + public Object getAttribute(String attribute, LinkOption... options) + throws IOException + { + return getAttributesImpl(attribute, false); + } + + @Override + public Map readAttributes(String attribute, LinkOption... options) + throws IOException + { + return (Map)getAttributesImpl(attribute, true); + } + + @Override + public FileStore getFileStore() throws IOException { + // each ZipFileSystem only has one root (as requested for now) + if (exists()) + return zfs.getFileStore(this); + throw new NoSuchFileException(zfs.getString(path)); + } + + @Override + public boolean isSameFile(Path other) throws IOException { + if (other == null || + this.getFileSystem() != other.getFileSystem()) + return false; + this.checkAccess(); + other.checkAccess(); + return Arrays.equals(this.getResolvedPath(), + ((ZipPath)other).getResolvedPath()); + } + + public WatchKey register( + WatchService watcher, + WatchEvent.Kind[] events, + WatchEvent.Modifier... modifiers) { + if (watcher == null || events == null || modifiers == null) { + throw new NullPointerException(); + } + throw new UnsupportedOperationException(); + } + + @Override + public WatchKey register(WatchService watcher, WatchEvent.Kind... events) { + return register(watcher, events, new WatchEvent.Modifier[0]); + } + + @Override + public Iterator iterator() { + return new Iterator() { + private int i = 0; + + @Override + public boolean hasNext() { + return (i < getNameCount()); + } + + @Override + public Path next() { + if (i < getNameCount()) { + Path result = getName(i); + i++; + return result; + } else { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() { + throw new ReadOnlyFileSystemException(); + } + }; + } + + @Override + public SeekableByteChannel newByteChannel(Set options, + FileAttribute... attrs) + throws IOException + { + return zfs.newByteChannel(getResolvedPath(), options, attrs); + } + + + FileChannel newFileChannel(Set options, + FileAttribute... attrs) + throws IOException + { + return zfs.newFileChannel(getResolvedPath(), options, attrs); + } + + @Override + public SeekableByteChannel newByteChannel(OpenOption... options) + throws IOException { + Set set = new HashSet(options.length); + Collections.addAll(set, options); + return newByteChannel(set); + } + + @Override + public void checkAccess(AccessMode... modes) throws IOException { + boolean w = false; + boolean x = false; + for (AccessMode mode : modes) { + switch (mode) { + case READ: + break; + case WRITE: + w = true; + break; + case EXECUTE: + x = true; + break; + default: + throw new UnsupportedOperationException(); + } + } + ZipFileAttributes attrs = zfs.getFileAttributes(getResolvedPath()); + if (attrs == null && (path.length != 1 || path[0] != '/')) + throw new NoSuchFileException(toString()); + if (w) { + if (zfs.isReadOnly()) + throw new AccessDeniedException(toString()); + } + if (x) + throw new AccessDeniedException(toString()); + + } + + @Override + public boolean exists() { + if (path.length == 1 && path[0] == '/') + return true; + try { + return zfs.exists(getResolvedPath()); + } catch (IOException x) {} + return false; + } + + @Override + public boolean notExists() { + return !exists(); + } + + + @Override + public OutputStream newOutputStream(OpenOption... options) + throws IOException + { + if (options.length == 0) + return zfs.newOutputStream(getResolvedPath(), + CREATE_NEW, WRITE); + return zfs.newOutputStream(getResolvedPath(), options); + } + + @Override + public Path moveTo(Path target, CopyOption... options) + throws IOException + { + if (this.zfs.provider() == target.getFileSystem().provider() && + this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile())) + { + zfs.copyFile(true, + getResolvedPath(), + ((ZipPath)target).getResolvedPath(), + options); + } else { + copyToTarget(target, options); + delete(); + } + return target; + } + + @Override + public Path copyTo(Path target, CopyOption... options) + throws IOException + { + if (this.zfs.provider() == target.getFileSystem().provider() && + this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile())) + { + zfs.copyFile(false, + getResolvedPath(), + ((ZipPath)target).getResolvedPath(), + options); + } else { + copyToTarget(target, options); + } + return target; + } + + private void copyToTarget(Path target, CopyOption... options) + throws IOException + { + boolean replaceExisting = false; + boolean copyAttrs = false; + for (CopyOption opt : options) { + if (opt == REPLACE_EXISTING) + replaceExisting = true; + else if (opt == COPY_ATTRIBUTES) + copyAttrs = false; + } + // attributes of source file + ZipFileAttributes zfas = getAttributes(); + // check if target exists + boolean exists; + if (replaceExisting) { + try { + target.deleteIfExists(); + exists = false; + } catch (DirectoryNotEmptyException x) { + exists = true; + } + } else { + exists = target.exists(); + } + if (exists) + throw new FileAlreadyExistsException(target.toString()); + + if (zfas.isDirectory()) { + // create directory or file + target.createDirectory(); + } else { + InputStream is = zfs.newInputStream(getResolvedPath()); + try { + OutputStream os = target.newOutputStream(); + try { + byte[] buf = new byte[8192]; + int n = 0; + while ((n = is.read(buf)) != -1) { + os.write(buf, 0, n); + } + } finally { + os.close(); + } + } finally { + is.close(); + } + } + if (copyAttrs) { + BasicFileAttributeView view = + target.getFileAttributeView(BasicFileAttributeView.class); + try { + view.setTimes(zfas.lastModifiedTime(), null, null); + } catch (IOException x) { + // rollback? + try { + target.delete(); + } catch (IOException ignore) { } + throw x; + } + } + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java new file mode 100644 index 00000000000..b3106e09fa3 --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Date; +import java.util.regex.PatternSyntaxException; + +/** + * + * @author Xueming Shen + */ + +class ZipUtils { + + /* + * Writes a 16-bit short to the output stream in little-endian byte order. + */ + public static void writeShort(OutputStream os, int v) throws IOException { + os.write((v >>> 0) & 0xff); + os.write((v >>> 8) & 0xff); + } + + /* + * Writes a 32-bit int to the output stream in little-endian byte order. + */ + public static void writeInt(OutputStream os, long v) throws IOException { + os.write((int)((v >>> 0) & 0xff)); + os.write((int)((v >>> 8) & 0xff)); + os.write((int)((v >>> 16) & 0xff)); + os.write((int)((v >>> 24) & 0xff)); + } + + /* + * Writes a 64-bit int to the output stream in little-endian byte order. + */ + public static void writeLong(OutputStream os, long v) throws IOException { + os.write((int)((v >>> 0) & 0xff)); + os.write((int)((v >>> 8) & 0xff)); + os.write((int)((v >>> 16) & 0xff)); + os.write((int)((v >>> 24) & 0xff)); + os.write((int)((v >>> 32) & 0xff)); + os.write((int)((v >>> 40) & 0xff)); + os.write((int)((v >>> 48) & 0xff)); + os.write((int)((v >>> 56) & 0xff)); + } + + /* + * Writes an array of bytes to the output stream. + */ + public static void writeBytes(OutputStream os, byte[] b) + throws IOException + { + os.write(b, 0, b.length); + } + + /* + * Writes an array of bytes to the output stream. + */ + public static void writeBytes(OutputStream os, byte[] b, int off, int len) + throws IOException + { + os.write(b, off, len); + } + + /* + * Append a slash at the end, if it does not have one yet + */ + public static byte[] toDirectoryPath(byte[] dir) { + if (dir.length != 0 && dir[dir.length - 1] != '/') { + dir = Arrays.copyOf(dir, dir.length + 1); + dir[dir.length - 1] = '/'; + } + return dir; + } + + /* + * Converts DOS time to Java time (number of milliseconds since epoch). + */ + public static long dosToJavaTime(long dtime) { + Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80), + (int)(((dtime >> 21) & 0x0f) - 1), + (int)((dtime >> 16) & 0x1f), + (int)((dtime >> 11) & 0x1f), + (int)((dtime >> 5) & 0x3f), + (int)((dtime << 1) & 0x3e)); + return d.getTime(); + } + + /* + * Converts Java time to DOS time. + */ + public static long javaToDosTime(long time) { + Date d = new Date(time); + int year = d.getYear() + 1900; + if (year < 1980) { + return (1 << 21) | (1 << 16); + } + return (year - 1980) << 25 | (d.getMonth() + 1) << 21 | + d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 | + d.getSeconds() >> 1; + } + + private static final String regexMetaChars = ".^$+{[]|()"; + private static final String globMetaChars = "\\*?[{"; + private static boolean isRegexMeta(char c) { + return regexMetaChars.indexOf(c) != -1; + } + private static boolean isGlobMeta(char c) { + return globMetaChars.indexOf(c) != -1; + } + private static char EOL = 0; //TBD + private static char next(String glob, int i) { + if (i < glob.length()) { + return glob.charAt(i); + } + return EOL; + } + + /* + * Creates a regex pattern from the given glob expression. + * + * @throws PatternSyntaxException + */ + public static String toRegexPattern(String globPattern) { + boolean inGroup = false; + StringBuilder regex = new StringBuilder("^"); + + int i = 0; + while (i < globPattern.length()) { + char c = globPattern.charAt(i++); + switch (c) { + case '\\': + // escape special characters + if (i == globPattern.length()) { + throw new PatternSyntaxException("No character to escape", + globPattern, i - 1); + } + char next = globPattern.charAt(i++); + if (isGlobMeta(next) || isRegexMeta(next)) { + regex.append('\\'); + } + regex.append(next); + break; + case '/': + regex.append(c); + break; + case '[': + // don't match name separator in class + regex.append("[[^/]&&["); + if (next(globPattern, i) == '^') { + // escape the regex negation char if it appears + regex.append("\\^"); + i++; + } else { + // negation + if (next(globPattern, i) == '!') { + regex.append('^'); + i++; + } + // hyphen allowed at start + if (next(globPattern, i) == '-') { + regex.append('-'); + i++; + } + } + boolean hasRangeStart = false; + char last = 0; + while (i < globPattern.length()) { + c = globPattern.charAt(i++); + if (c == ']') { + break; + } + if (c == '/') { + throw new PatternSyntaxException("Explicit 'name separator' in class", + globPattern, i - 1); + } + // TBD: how to specify ']' in a class? + if (c == '\\' || c == '[' || + c == '&' && next(globPattern, i) == '&') { + // escape '\', '[' or "&&" for regex class + regex.append('\\'); + } + regex.append(c); + + if (c == '-') { + if (!hasRangeStart) { + throw new PatternSyntaxException("Invalid range", + globPattern, i - 1); + } + if ((c = next(globPattern, i++)) == EOL || c == ']') { + break; + } + if (c < last) { + throw new PatternSyntaxException("Invalid range", + globPattern, i - 3); + } + regex.append(c); + hasRangeStart = false; + } else { + hasRangeStart = true; + last = c; + } + } + if (c != ']') { + throw new PatternSyntaxException("Missing ']", globPattern, i - 1); + } + regex.append("]]"); + break; + case '{': + if (inGroup) { + throw new PatternSyntaxException("Cannot nest groups", + globPattern, i - 1); + } + regex.append("(?:(?:"); + inGroup = true; + break; + case '}': + if (inGroup) { + regex.append("))"); + inGroup = false; + } else { + regex.append('}'); + } + break; + case ',': + if (inGroup) { + regex.append(")|(?:"); + } else { + regex.append(','); + } + break; + case '*': + if (next(globPattern, i) == '*') { + // crosses directory boundaries + regex.append(".*"); + i++; + } else { + // within directory boundary + regex.append("[^/]*"); + } + break; + case '?': + regex.append("[^/]"); + break; + default: + if (isRegexMeta(c)) { + regex.append('\\'); + } + regex.append(c); + } + } + if (inGroup) { + throw new PatternSyntaxException("Missing '}", globPattern, i - 1); + } + return regex.append('$').toString(); + } +} diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.3/zcrc32.c b/jdk/src/share/native/java/util/zip/zlib-1.2.3/zcrc32.c index 580e26c83c4..0fd9a92c05e 100644 --- a/jdk/src/share/native/java/util/zip/zlib-1.2.3/zcrc32.c +++ b/jdk/src/share/native/java/util/zip/zlib-1.2.3/zcrc32.c @@ -406,7 +406,7 @@ uLong ZEXPORT crc32_combine(crc1, crc2, len2) return crc1; /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320L; /* CRC-32 polynomial */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ row = 1; for (n = 1; n < GF2_DIM; n++) { odd[n] = row; diff --git a/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c b/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c index 7466b94cb12..dc8f65fd5c5 100644 --- a/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c +++ b/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -114,8 +114,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Encrypt { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; - CK_BYTE IBUF[MAX_STACK_BUFFER_LEN]; - CK_BYTE OBUF[MAX_STACK_BUFFER_LEN]; + CK_BYTE_PTR inBufP; CK_BYTE_PTR outBufP; CK_ULONG ckEncryptedPartLen; @@ -125,50 +124,27 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Encrypt ckSessionHandle = jLongToCKULong(jSessionHandle); - if (jInLen > MAX_STACK_BUFFER_LEN) { - inBufP = (CK_BYTE_PTR)malloc((size_t)jInLen); - if (inBufP == NULL) { - JNU_ThrowOutOfMemoryError(env, 0); + inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL); + if (inBufP == NULL) { return 0; } + + outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL); + if (outBufP == NULL) { + // Make sure to release inBufP + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); return 0; - } - } else { - inBufP = IBUF; - } - (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP); - if ((*env)->ExceptionCheck(env)) { - if (inBufP != IBUF) { free(inBufP); } - return 0; } ckEncryptedPartLen = jOutLen; - if (jOutLen > MAX_STACK_BUFFER_LEN) { - outBufP = (CK_BYTE_PTR)malloc((size_t)jOutLen); - if (outBufP == NULL) { - if (inBufP != IBUF) { - free(inBufP); - } - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - } else { - outBufP = OBUF; - } - rv = (*ckpFunctions->C_Encrypt)(ckSessionHandle, inBufP, jInLen, - outBufP, &ckEncryptedPartLen); + rv = (*ckpFunctions->C_Encrypt)(ckSessionHandle, + (CK_BYTE_PTR)(inBufP + jInOfs), jInLen, + (CK_BYTE_PTR)(outBufP + jOutOfs), + &ckEncryptedPartLen); - if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { - if (ckEncryptedPartLen > 0) { - (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckEncryptedPartLen, - (jbyte *)outBufP); - } - } - if (inBufP != IBUF) { - free(inBufP); - } - if (outBufP != OBUF) { - free(outBufP); - } + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); + + ckAssertReturnValueOK(env, rv); return ckEncryptedPartLen; } #endif @@ -193,8 +169,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptUpdate { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; - CK_BYTE IBUF[MAX_STACK_BUFFER_LEN]; - CK_BYTE OBUF[MAX_STACK_BUFFER_LEN]; + CK_BYTE_PTR inBufP; CK_BYTE_PTR outBufP; CK_ULONG ckEncryptedPartLen; @@ -205,64 +180,45 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptUpdate ckSessionHandle = jLongToCKULong(jSessionHandle); if (directIn != 0) { - inBufP = (CK_BYTE_PTR)(directIn + jInOfs); + inBufP = (CK_BYTE_PTR) directIn; } else { - if (jInLen > MAX_STACK_BUFFER_LEN) { - inBufP = (CK_BYTE_PTR)malloc((size_t)jInLen); - if (inBufP == NULL) { - JNU_ThrowOutOfMemoryError(env, 0); + inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL); + if (inBufP == NULL) { return 0; } + } + + if (directOut != 0) { + outBufP = (CK_BYTE_PTR) directOut; + } else { + outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL); + if (outBufP == NULL) { + // Make sure to release inBufP + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); return 0; - } - } else { - inBufP = IBUF; - } - (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP); - if ((*env)->ExceptionCheck(env)) { - if (directIn == 0 && inBufP != IBUF) { free(inBufP); } - return 0; } } ckEncryptedPartLen = jOutLen; - if (directOut != 0) { - outBufP = (CK_BYTE_PTR)(directOut + jOutOfs); - } else { - if (jOutLen > MAX_STACK_BUFFER_LEN) { - outBufP = (CK_BYTE_PTR)malloc((size_t)jOutLen); - if (outBufP == NULL) { - if (directIn == 0 && inBufP != IBUF) { - free(inBufP); - } - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - } else { - outBufP = OBUF; - } - } //printf("EU: inBufP=%i, jInOfs=%i, jInLen=%i, outBufP=%i\n", // inBufP, jInOfs, jInLen, outBufP); rv = (*ckpFunctions->C_EncryptUpdate)(ckSessionHandle, - inBufP, jInLen, - outBufP, &ckEncryptedPartLen); + (CK_BYTE_PTR)(inBufP + jInOfs), jInLen, + (CK_BYTE_PTR)(outBufP + jOutOfs), + &ckEncryptedPartLen); //printf("EU: ckEncryptedPartLen=%i\n", ckEncryptedPartLen); - if (directIn == 0 && inBufP != IBUF) { - free(inBufP); + if (directIn == 0) { + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); } - if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { - if (directOut == 0 && ckEncryptedPartLen > 0) { - (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckEncryptedPartLen, - (jbyte *)outBufP); - } - } - if (directOut == 0 && outBufP != OBUF) { - free(outBufP); + if (directOut == 0) { + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); } + + ckAssertReturnValueOK(env, rv); + return ckEncryptedPartLen; } #endif @@ -284,7 +240,6 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptFinal { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; - CK_BYTE BUF[MAX_STACK_BUFFER_LEN]; CK_BYTE_PTR outBufP; CK_ULONG ckLastEncryptedPartLen; @@ -293,31 +248,29 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptFinal ckSessionHandle = jLongToCKULong(jSessionHandle); - ckLastEncryptedPartLen = jOutLen; if (directOut != 0) { - outBufP = (CK_BYTE_PTR)(directOut + jOutOfs); + outBufP = (CK_BYTE_PTR) directOut; } else { - // output length should always be less than MAX_STACK_BUFFER_LEN - outBufP = BUF; + outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL); + if (outBufP == NULL) { return 0; } } + ckLastEncryptedPartLen = jOutLen; + //printf("EF: outBufP=%i\n", outBufP); - rv = (*ckpFunctions->C_EncryptFinal)(ckSessionHandle, outBufP, + rv = (*ckpFunctions->C_EncryptFinal)(ckSessionHandle, + (CK_BYTE_PTR)(outBufP + jOutOfs), &ckLastEncryptedPartLen); //printf("EF: ckLastEncryptedPartLen=%i", ckLastEncryptedPartLen); - if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { - if (directOut == 0 && ckLastEncryptedPartLen > 0) { - (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckLastEncryptedPartLen, - (jbyte *)outBufP); - } + if (directOut == 0) { + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); } - if (directOut == 0 && outBufP != BUF) { - free(outBufP); - } + ckAssertReturnValueOK(env, rv); + return ckLastEncryptedPartLen; } #endif @@ -381,8 +334,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; - CK_BYTE IBUF[MAX_STACK_BUFFER_LEN]; - CK_BYTE OBUF[MAX_STACK_BUFFER_LEN]; + CK_BYTE_PTR inBufP; CK_BYTE_PTR outBufP; CK_ULONG ckPartLen; @@ -392,49 +344,27 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt ckSessionHandle = jLongToCKULong(jSessionHandle); - if (jInLen > MAX_STACK_BUFFER_LEN) { - inBufP = (CK_BYTE_PTR)malloc((size_t)jInLen); - if (inBufP == NULL) { - JNU_ThrowOutOfMemoryError(env, 0); + inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL); + if (inBufP == NULL) { return 0; } + + outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL); + if (outBufP == NULL) { + // Make sure to release inBufP + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); return 0; - } - } else { - inBufP = IBUF; - } - (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP); - if ((*env)->ExceptionCheck(env)) { - if (inBufP != IBUF) { free(inBufP); } - return 0; } ckPartLen = jOutLen; - if (jOutLen > MAX_STACK_BUFFER_LEN) { - outBufP = (CK_BYTE_PTR)malloc((size_t)jOutLen); - if (outBufP == NULL) { - if (inBufP != IBUF) { - free(inBufP); - } - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - } else { - outBufP = OBUF; - } - rv = (*ckpFunctions->C_Decrypt)(ckSessionHandle, inBufP, jInLen, - outBufP, &ckPartLen); - if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { - if (ckPartLen > 0) { - (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckPartLen, - (jbyte *)outBufP); - } - } - if (inBufP != IBUF) { - free(inBufP); - } - if (outBufP != OBUF) { - free(outBufP); - } + rv = (*ckpFunctions->C_Decrypt)(ckSessionHandle, + (CK_BYTE_PTR)(inBufP + jInOfs), jInLen, + (CK_BYTE_PTR)(outBufP + jOutOfs), + &ckPartLen); + + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); + + ckAssertReturnValueOK(env, rv); return ckPartLen; } @@ -460,8 +390,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptUpdate { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; - CK_BYTE IBUF[MAX_STACK_BUFFER_LEN]; - CK_BYTE OBUF[MAX_STACK_BUFFER_LEN]; + CK_BYTE_PTR inBufP; CK_BYTE_PTR outBufP; CK_ULONG ckDecryptedPartLen; @@ -472,59 +401,39 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptUpdate ckSessionHandle = jLongToCKULong(jSessionHandle); if (directIn != 0) { - inBufP = (CK_BYTE_PTR)(directIn + jInOfs); + inBufP = (CK_BYTE_PTR) directIn; } else { - if (jInLen > MAX_STACK_BUFFER_LEN) { - inBufP = (CK_BYTE_PTR)malloc((size_t)jInLen); - if (inBufP == NULL) { - JNU_ThrowOutOfMemoryError(env, 0); + inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL); + if (inBufP == NULL) { return 0; } + } + + if (directOut != 0) { + outBufP = (CK_BYTE_PTR) directOut; + } else { + outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL); + if (outBufP == NULL) { + // Make sure to release inBufP + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); return 0; - } - } else { - inBufP = IBUF; - } - (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP); - if ((*env)->ExceptionCheck(env)) { - if (directIn == 0 && inBufP != IBUF) { free(inBufP); } - return 0; } } ckDecryptedPartLen = jOutLen; - if (directOut != 0) { - outBufP = (CK_BYTE_PTR)(directOut + jOutOfs); - } else { - if (jOutLen > MAX_STACK_BUFFER_LEN) { - outBufP = (CK_BYTE_PTR)malloc((size_t)jOutLen); - if (outBufP == NULL) { - if (directIn == 0 && inBufP != IBUF) { - free(inBufP); - } - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - } else { - outBufP = OBUF; - } + + rv = (*ckpFunctions->C_DecryptUpdate)(ckSessionHandle, + (CK_BYTE_PTR)(inBufP + jInOfs), jInLen, + (CK_BYTE_PTR)(outBufP + jOutOfs), + &ckDecryptedPartLen); + if (directIn == 0) { + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); } - rv = (*ckpFunctions->C_DecryptUpdate)(ckSessionHandle, inBufP, jInLen, - outBufP, &ckDecryptedPartLen); - - if (directIn == 0 && inBufP != IBUF) { - free(inBufP); + if (directOut == 0) { + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); } - if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { - if (directOut == 0 && ckDecryptedPartLen > 0) { - (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckDecryptedPartLen, - (jbyte *)outBufP); - } - } + ckAssertReturnValueOK(env, rv); - if (directOut == 0 && outBufP != OBUF) { - free(outBufP); - } return ckDecryptedPartLen; } @@ -547,7 +456,6 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptFinal { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; - CK_BYTE BUF[MAX_STACK_BUFFER_LEN]; CK_BYTE_PTR outBufP; CK_ULONG ckLastPartLen; @@ -556,27 +464,26 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptFinal ckSessionHandle = jLongToCKULong(jSessionHandle); - ckLastPartLen = jOutLen; if (directOut != 0) { - outBufP = (CK_BYTE_PTR)(directOut + jOutOfs); + outBufP = (CK_BYTE_PTR) directOut; } else { - // jOutLen should always be less than MAX_STACK_BUFFER_LEN - outBufP = BUF; + outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL); + if (outBufP == NULL) { return 0; } } - rv = (*ckpFunctions->C_DecryptFinal)(ckSessionHandle, outBufP, + ckLastPartLen = jOutLen; + + rv = (*ckpFunctions->C_DecryptFinal)(ckSessionHandle, + (CK_BYTE_PTR)(outBufP + jOutOfs), &ckLastPartLen); - if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { - if (directOut == 0 && ckLastPartLen > 0) { - (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckLastPartLen, - (jbyte *)outBufP); - } + if (directOut == 0) { + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); + } - if (directOut == 0 && outBufP != BUF) { - free(outBufP); - } + ckAssertReturnValueOK(env, rv); + return ckLastPartLen; } #endif diff --git a/jdk/src/solaris/bin/java_md.c b/jdk/src/solaris/bin/java_md.c index ca1ce5b9f0b..441d41efe25 100644 --- a/jdk/src/solaris/bin/java_md.c +++ b/jdk/src/solaris/bin/java_md.c @@ -868,7 +868,7 @@ LocateJRE(manifest_info* info) while (dp != NULL) { cp = JLI_StrChr(dp, (int)':'); if (cp != NULL) - *cp = (char)NULL; + *cp = '\0'; if ((target = ProcessDir(info, dp)) != NULL) break; dp = cp; diff --git a/jdk/src/solaris/bin/jexec.c b/jdk/src/solaris/bin/jexec.c index 24ba47ed94d..951b42bfe6a 100644 --- a/jdk/src/solaris/bin/jexec.c +++ b/jdk/src/solaris/bin/jexec.c @@ -221,6 +221,7 @@ int main(int argc, const char * argv[]) { * implies an error in the exec. */ free(nargv); errorExit(errno, BAD_EXEC_MSG); + return 0; // keep the compiler happy } diff --git a/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java b/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java index ba2b78c4e0e..57a0492ddee 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java @@ -64,7 +64,10 @@ class GtkFileDialogPeer extends XDialogPeer implements FileDialogPeer { accessor.setFile(fd, null); accessor.setFiles(fd, null, null); } else { - accessor.setDirectory(fd, directory); + // Fix 6987233: add the trailing slash if it's absent + accessor.setDirectory(fd, directory + + (directory.endsWith(File.separator) ? + "" : File.separator)); accessor.setFile(fd, filenames[0]); accessor.setFiles(fd, directory, filenames); } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java index c40e87b894a..45c29daa6fd 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java @@ -705,12 +705,8 @@ public class XBaseWindow { throw new IllegalStateException("Attempt to resize uncreated window"); } insLog.fine("Setting bounds on " + this + " to (" + x + ", " + y + "), " + width + "x" + height); - if (width <= 0) { - width = 1; - } - if (height <= 0) { - height = 1; - } + width = Math.max(MIN_SIZE, width); + height = Math.max(MIN_SIZE, height); XToolkit.awtLock(); try { XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(), x,y,width,height); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java index 5618fa6f58c..340747f689c 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java @@ -763,12 +763,8 @@ abstract class XDecoratedPeer extends XWindowPeer { } private void checkShellRectSize(Rectangle shellRect) { - if (shellRect.width < 0) { - shellRect.width = 1; - } - if (shellRect.height < 0) { - shellRect.height = 1; - } + shellRect.width = Math.max(MIN_SIZE, shellRect.width); + shellRect.height = Math.max(MIN_SIZE, shellRect.height); } private void checkShellRectPos(Rectangle shellRect) { diff --git a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java index 221ffb5e326..e9d0fcb6e7a 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java @@ -28,9 +28,12 @@ package sun.awt.X11; import sun.awt.EmbeddedFrame; import java.awt.*; import java.awt.AWTKeyStroke; +import java.util.logging.Logger; public class XEmbeddedFrame extends EmbeddedFrame { + private static final Logger log = Logger.getLogger(XEmbeddedFrame.class.getName()); + long handle; public XEmbeddedFrame() { } @@ -70,6 +73,21 @@ public class XEmbeddedFrame extends EmbeddedFrame { this(handle, supportsXEmbed, false); } + /* + * The method shouldn't be called in case of active XEmbed. + */ + public boolean traverseIn(boolean direction) { + XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer(); + if (peer != null) { + if (peer.supportsXEmbed() && peer.isXEmbedActive()) { + log.fine("The method shouldn't be called when XEmbed is active!"); + } else { + return super.traverseIn(direction); + } + } + return false; + } + protected boolean traverseOut(boolean direction) { XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer(); if (direction == FORWARD) { @@ -81,6 +99,20 @@ public class XEmbeddedFrame extends EmbeddedFrame { return true; } + /* + * The method shouldn't be called in case of active XEmbed. + */ + public void synthesizeWindowActivation(boolean doActivate) { + XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer(); + if (peer != null) { + if (peer.supportsXEmbed() && peer.isXEmbedActive()) { + log.fine("The method shouldn't be called when XEmbed is active!"); + } else { + peer.synthesizeFocusInOut(doActivate); + } + } + } + public void registerAccelerator(AWTKeyStroke stroke) { XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer(); if (xefp != null) { diff --git a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java index 5825277207b..9fee20f90df 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java @@ -35,6 +35,8 @@ import sun.util.logging.PlatformLogger; import sun.awt.EmbeddedFrame; import sun.awt.SunToolkit; +import static sun.awt.X11.XConstants.*; + public class XEmbeddedFramePeer extends XFramePeer { private static final PlatformLogger xembedLog = PlatformLogger.getLogger("sun.awt.X11.xembed.XEmbeddedFramePeer"); @@ -305,4 +307,20 @@ public class XEmbeddedFramePeer extends XFramePeer { EmbeddedFrame frame = (EmbeddedFrame)target; frame.notifyModalBlocked(blocker, blocked); } + + public void synthesizeFocusInOut(boolean doFocus) { + XFocusChangeEvent xev = new XFocusChangeEvent(); + + XToolkit.awtLock(); + try { + xev.set_type(doFocus ? FocusIn : FocusOut); + xev.set_window(getFocusProxy().getWindow()); + xev.set_mode(NotifyNormal); + XlibWrapper.XSendEvent(XToolkit.getDisplay(), getFocusProxy().getWindow(), false, + NoEventMask, xev.pData); + } finally { + XToolkit.awtUnlock(); + xev.dispose(); + } + } } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java index fd8622bd694..192a8f568e9 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java @@ -1482,8 +1482,19 @@ public final class XToolkit extends UNIXToolkit implements Runnable { try { if (numberOfButtons == 0) { numberOfButtons = getNumberOfButtonsImpl(); + numberOfButtons = (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons; + //4th and 5th buttons are for wheel and shouldn't be reported as buttons. + //If we have more than 3 physical buttons and a wheel, we report N-2 buttons. + //If we have 3 physical buttons and a wheel, we report 3 buttons. + //If we have 1,2,3 physical buttons, we report it as is i.e. 1,2 or 3 respectively. + if (numberOfButtons >=5) { + numberOfButtons -= 2; + } else if (numberOfButtons == 4 || numberOfButtons ==5){ + numberOfButtons = 3; + } } - return (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons; + //Assume don't have to re-query the number again and again. + return numberOfButtons; } finally { awtUnlock(); } diff --git a/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java b/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java index 41656baaafe..6f17340372e 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java +++ b/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java @@ -94,6 +94,12 @@ class FileDispatcherImpl extends FileDispatcher preClose0(fd); } + FileDescriptor duplicateForMapping(FileDescriptor fd) { + // file descriptor not required for mapping operations; okay + // to return invalid file descriptor. + return new FileDescriptor(); + } + // -- Native methods -- static native int read0(FileDescriptor fd, long address, int len) diff --git a/jdk/src/solaris/native/java/net/Inet4AddressImpl.c b/jdk/src/solaris/native/java/net/Inet4AddressImpl.c index 0e9969eebe3..d9ddc1d6ef2 100644 --- a/jdk/src/solaris/native/java/net/Inet4AddressImpl.c +++ b/jdk/src/solaris/native/java/net/Inet4AddressImpl.c @@ -381,7 +381,15 @@ ping4(JNIEnv *env, jint fd, struct sockaddr_in* him, jint timeout, n = sendto(fd, sendbuf, plen, 0, (struct sockaddr *)him, sizeof(struct sockaddr)); if (n < 0 && errno != EINPROGRESS ) { - NET_ThrowNew(env, errno, "Can't send ICMP packet"); +#ifdef __linux__ + if (errno != EINVAL) + /* + * On some Linuxes, when bound to the loopback interface, sendto + * will fail and errno will be set to EINVAL. When that happens, + * don't throw an exception, just return false. + */ +#endif /*__linux__ */ + NET_ThrowNew(env, errno, "Can't send ICMP packet"); close(fd); return JNI_FALSE; } diff --git a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c index 4c5e928c560..93572ae293b 100644 --- a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c +++ b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c @@ -506,7 +506,16 @@ ping6(JNIEnv *env, jint fd, struct sockaddr_in6* him, jint timeout, plen = sizeof(struct icmp6_hdr) + sizeof(tv); n = sendto(fd, sendbuf, plen, 0, (struct sockaddr*) him, sizeof(struct sockaddr_in6)); if (n < 0 && errno != EINPROGRESS) { +#ifdef __linux__ + if (errno != EINVAL) + /* + * On some Linuxes, when bound to the loopback interface, sendto + * will fail and errno will be set to EINVAL. When that happens, + * don't throw an exception, just return false. + */ +#endif /*__linux__ */ NET_ThrowNew(env, errno, "Can't send ICMP packet"); + close(fd); return JNI_FALSE; } diff --git a/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c b/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c index 48d0d8ecfa8..cde085a9473 100644 --- a/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c +++ b/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c @@ -2255,7 +2255,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this, { struct in_addr in; struct in_addr *inP = ∈ - int len = sizeof(struct in_addr); + socklen_t len = sizeof(struct in_addr); #ifdef __linux__ struct ip_mreqn mreqn; diff --git a/jdk/src/solaris/native/java/nio/MappedByteBuffer.c b/jdk/src/solaris/native/java/nio/MappedByteBuffer.c index 15c4ec5f5de..49ab0e2e1c6 100644 --- a/jdk/src/solaris/native/java/nio/MappedByteBuffer.c +++ b/jdk/src/solaris/native/java/nio/MappedByteBuffer.c @@ -82,8 +82,8 @@ Java_java_nio_MappedByteBuffer_load0(JNIEnv *env, jobject obj, jlong address, JNIEXPORT void JNICALL -Java_java_nio_MappedByteBuffer_force0(JNIEnv *env, jobject obj, jlong address, - jlong len) +Java_java_nio_MappedByteBuffer_force0(JNIEnv *env, jobject obj, jobject fdo, + jlong address, jlong len) { void* a = (void *)jlong_to_ptr(address); int result = msync(a, (size_t)len, MS_SYNC); diff --git a/jdk/src/solaris/native/sun/awt/awt_InputMethod.c b/jdk/src/solaris/native/sun/awt/awt_InputMethod.c index fbaf35cfff3..549e51986f6 100644 --- a/jdk/src/solaris/native/sun/awt/awt_InputMethod.c +++ b/jdk/src/solaris/native/sun/awt/awt_InputMethod.c @@ -1473,6 +1473,10 @@ static void OpenXIMCallback(Display *display, XPointer client_data, XPointer cal static void DestroyXIMCallback(XIM im, XPointer client_data, XPointer call_data) { /* mark that XIM server was destroyed */ X11im = NULL; + JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + /* free the old pX11IMData and set it to null. this also avoids crashing + * the jvm if the XIM server reappears */ + X11InputMethodData *pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance); } /* diff --git a/jdk/src/solaris/native/sun/net/spi/DefaultProxySelector.c b/jdk/src/solaris/native/sun/net/spi/DefaultProxySelector.c index 12770fdf78c..6c22e231602 100644 --- a/jdk/src/solaris/native/sun/net/spi/DefaultProxySelector.c +++ b/jdk/src/solaris/native/sun/net/spi/DefaultProxySelector.c @@ -158,7 +158,7 @@ Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env, char *phost = NULL; char *mode = NULL; int pport = 0; - int use_proxy; + int use_proxy = 0; int use_same_proxy = 0; const char* urlhost; jobject isa = NULL; diff --git a/jdk/src/windows/bin/java_md.c b/jdk/src/windows/bin/java_md.c index 06824ce319c..cef7db8c115 100644 --- a/jdk/src/windows/bin/java_md.c +++ b/jdk/src/windows/bin/java_md.c @@ -208,7 +208,7 @@ EnsureJreInstallation(const char* jrepath) struct stat s; /* Make sure the jrepath contains something */ - if (jrepath[0] == NULL) { + if ((void*)jrepath[0] == NULL) { return; } /* 32 bit windows only please */ @@ -540,7 +540,7 @@ JLI_ReportErrorMessageSys(const char *fmt, ...) /* get the length of the string we need */ int len = mlen = _vscprintf(fmt, vl) + 1; if (freeit) { - mlen += JLI_StrLen(errtext); + mlen += (int)JLI_StrLen(errtext); } message = (char *)JLI_MemAlloc(mlen); @@ -997,7 +997,6 @@ ExecJRE(char *jre, char **argv) { exit(exitCode); } - } /* diff --git a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java index d697fd34047..5a3cd2ddd87 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java @@ -556,24 +556,26 @@ public abstract class WComponentPeer extends WObjectPeer Component target = (Component)getTarget(); Window window = SunToolkit.getContainingWindow(target); - if (window != null && !window.isOpaque()) { - // Non-opaque windows do not support heavyweight children. - // Redirect all painting to the Window's Graphics instead. - // The caller is responsible for calling the - // WindowPeer.updateWindow() after painting has finished. - int x = 0, y = 0; - for (Component c = target; c != window; c = c.getParent()) { - x += c.getX(); - y += c.getY(); - } - + if (window != null) { Graphics g = ((WWindowPeer)window.getPeer()).getTranslucentGraphics(); + // getTranslucentGraphics() returns non-null value for non-opaque windows only + if (g != null) { + // Non-opaque windows do not support heavyweight children. + // Redirect all painting to the Window's Graphics instead. + // The caller is responsible for calling the + // WindowPeer.updateWindow() after painting has finished. + int x = 0, y = 0; + for (Component c = target; c != window; c = c.getParent()) { + x += c.getX(); + y += c.getY(); + } - g.translate(x, y); - g.clipRect(0, 0, target.getWidth(), target.getHeight()); + g.translate(x, y); + g.clipRect(0, 0, target.getWidth(), target.getHeight()); - return g; + return g; + } } SurfaceData surfaceData = this.surfaceData; diff --git a/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java b/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java index 18489f91db4..908c1aac8e2 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java +++ b/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java @@ -191,9 +191,20 @@ public class WEmbeddedFrame extends EmbeddedFrame { public void activateEmbeddingTopLevel() { } - public void synthesizeWindowActivation(boolean doActivate) { - ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate); + public void synthesizeWindowActivation(final boolean doActivate) { + if (!doActivate || EventQueue.isDispatchThread()) { + ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate); + } else { + // To avoid focus concurrence b/w IE and EmbeddedFrame + // activation is postponed by means of posting it to EDT. + EventQueue.invokeLater(new Runnable() { + public void run() { + ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true); + } + }); + } } + public void registerAccelerator(AWTKeyStroke stroke) {} public void unregisterAccelerator(AWTKeyStroke stroke) {} diff --git a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java index c5c979e34ec..d3ccd4db4d9 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java @@ -594,16 +594,6 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, } } - @Override - public Graphics getGraphics() { - synchronized (getStateLock()) { - if (!isOpaque) { - return getTranslucentGraphics(); - } - } - return super.getGraphics(); - } - @Override public void setBackground(Color c) { super.setBackground(c); diff --git a/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java b/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java index e893a2afb07..2cdc8f8fe9f 100644 --- a/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java +++ b/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java @@ -26,10 +26,11 @@ package sun.nio.ch; import java.io.*; +import sun.misc.SharedSecrets; +import sun.misc.JavaIOFileDescriptorAccess; class FileDispatcherImpl extends FileDispatcher { - static { Util.load(); } @@ -94,6 +95,16 @@ class FileDispatcherImpl extends FileDispatcher close0(fd); } + FileDescriptor duplicateForMapping(FileDescriptor fd) throws IOException { + // on Windows we need to keep a handle to the file + JavaIOFileDescriptorAccess fdAccess = + SharedSecrets.getJavaIOFileDescriptorAccess(); + FileDescriptor result = new FileDescriptor(); + long handle = duplicateHandle(fdAccess.getHandle(fd)); + fdAccess.setHandle(result, handle); + return result; + } + //-- Native methods static native int read0(FileDescriptor fd, long address, int len) @@ -132,4 +143,5 @@ class FileDispatcherImpl extends FileDispatcher static native void closeByHandle(long fd) throws IOException; + static native long duplicateHandle(long fd) throws IOException; } diff --git a/jdk/src/windows/lib/tzmappings b/jdk/src/windows/lib/tzmappings index 05309c9aef8..bbc3ca09ce2 100644 --- a/jdk/src/windows/lib/tzmappings +++ b/jdk/src/windows/lib/tzmappings @@ -1,5 +1,4 @@ # -# # This file describes mapping information between Windows and Java # time zones. # Format: Each line should include a colon separated fields of Windows @@ -11,7 +10,7 @@ # NOTE # This table format is not a public interface of any Java # platforms. No applications should depend on this file in any form. -# +# # This table has been generated by a program and should not be edited # manually. # @@ -84,8 +83,8 @@ Ekaterinburg:10,11::Asia/Yekaterinburg: Ekaterinburg Standard Time:10,11::Asia/Yekaterinburg: West Asia:10,11:UZ:Asia/Tashkent: West Asia Standard Time:10,11:UZ:Asia/Tashkent: -Central Asia:12,13::Asia/Dhaka: -Central Asia Standard Time:12,13::Asia/Dhaka: +Central Asia:12,13::Asia/Almaty: +Central Asia Standard Time:12,13::Asia/Almaty: N. Central Asia Standard Time:12,13::Asia/Novosibirsk: Bangkok:14,15::Asia/Bangkok: Bangkok Standard Time:14,15::Asia/Bangkok: @@ -167,22 +166,27 @@ Greenwich:88,89::GMT: Greenwich Standard Time:88,89::GMT: Argentina Standard Time:900,900::America/Buenos_Aires: Azerbaijan Standard Time:901,901:AZ:Asia/Baku: -Central Brazilian Standard Time:902,902:BR:America/Manaus: -Central Standard Time (Mexico):903,903::America/Mexico_City: -Georgian Standard Time:904,904:GE:Asia/Tbilisi: -Jordan Standard Time:905,905:JO:Asia/Amman: -Mauritius Standard Time:906,906:MU:Indian/Mauritius: -Middle East Standard Time:907,907:LB:Asia/Beirut: -Montevideo Standard Time:908,908:UY:America/Montevideo: -Morocco Standard Time:909,909:MA:Africa/Casablanca: -Mountain Standard Time (Mexico):910,910:MX:America/Chihuahua: -Namibia Standard Time:911,911:NA:Africa/Windhoek: -Pacific Standard Time (Mexico):912,912:MX:America/Tijuana: -Pakistan Standard Time:913,913::Asia/Karachi: -UTC:914,914::UTC: -Venezuela Standard Time:915,915::America/Caracas: -Kamchatka Standard Time:916,916:RU:Asia/Kamchatka: -Paraguay Standard Time:917,917:PY:America/Asuncion: -Western Brazilian Standard Time:918,918:BR:America/Rio_Branco: -Ulaanbaatar Standard Time:919,919::Asia/Ulaanbaatar: -Armenian Standard Time:920,920:AM:Asia/Yerevan: +Bangladesh Standard Time:902,902::Asia/Dhaka: +Central Brazilian Standard Time:903,903:BR:America/Manaus: +Central Standard Time (Mexico):904,904::America/Mexico_City: +Georgian Standard Time:905,905:GE:Asia/Tbilisi: +Jordan Standard Time:906,906:JO:Asia/Amman: +Kamchatka Standard Time:907,907:RU:Asia/Kamchatka: +Mauritius Standard Time:908,908:MU:Indian/Mauritius: +Middle East Standard Time:909,909:LB:Asia/Beirut: +Montevideo Standard Time:910,910:UY:America/Montevideo: +Morocco Standard Time:911,911:MA:Africa/Casablanca: +Mountain Standard Time (Mexico):912,912:MX:America/Chihuahua: +Namibia Standard Time:913,913:NA:Africa/Windhoek: +Pacific Standard Time (Mexico):914,914:MX:America/Tijuana: +Pakistan Standard Time:915,915::Asia/Karachi: +Paraguay Standard Time:916,916:PY:America/Asuncion: +Syria Standard Time:917,917:SY:Asia/Damascus: +UTC:918,918::UTC: +UTC+12:919,919::GMT+1200: +UTC-02:920,920::GMT-0200: +UTC-11:921,921::GMT-1100: +Ulaanbaatar Standard Time:922,922::Asia/Ulaanbaatar: +Venezuela Standard Time:923,923::America/Caracas: +Western Brazilian Standard Time:924,924:BR:America/Rio_Branco: +Armenian Standard Time:925,925:AM:Asia/Yerevan: diff --git a/jdk/src/windows/native/java/io/WinNTFileSystem_md.c b/jdk/src/windows/native/java/io/WinNTFileSystem_md.c index d57047a64d1..633d20e578a 100644 --- a/jdk/src/windows/native/java/io/WinNTFileSystem_md.c +++ b/jdk/src/windows/native/java/io/WinNTFileSystem_md.c @@ -434,7 +434,9 @@ Java_java_io_WinNTFileSystem_setPermission(JNIEnv *env, jobject this, a = GetFileAttributesW(pathbuf); } } - if (a != INVALID_FILE_ATTRIBUTES) { + if ((a != INVALID_FILE_ATTRIBUTES) && + ((a & FILE_ATTRIBUTE_DIRECTORY) == 0)) + { if (enable) a = a & ~FILE_ATTRIBUTE_READONLY; else @@ -796,9 +798,10 @@ Java_java_io_WinNTFileSystem_setReadOnly(JNIEnv *env, jobject this, } } - if (a != INVALID_FILE_ATTRIBUTES) { + if ((a != INVALID_FILE_ATTRIBUTES) && + ((a & FILE_ATTRIBUTE_DIRECTORY) == 0)) { if (SetFileAttributesW(pathbuf, a | FILE_ATTRIBUTE_READONLY)) - rv = JNI_TRUE; + rv = JNI_TRUE; } free(pathbuf); return rv; @@ -812,7 +815,7 @@ Java_java_io_WinNTFileSystem_getDriveDirectory(JNIEnv *env, jobject this, jint drive) { jstring ret = NULL; - jchar *p = _wgetdcwd(drive, NULL, MAX_PATH); + jchar *p = currentDir(drive); jchar *pf = p; if (p == NULL) return NULL; if (iswalpha(*p) && (p[1] == L':')) p += 2; diff --git a/jdk/src/windows/native/java/io/io_util_md.c b/jdk/src/windows/native/java/io/io_util_md.c index f5b9723a743..722913f775a 100644 --- a/jdk/src/windows/native/java/io/io_util_md.c +++ b/jdk/src/windows/native/java/io/io_util_md.c @@ -66,6 +66,25 @@ fileToNTPath(JNIEnv *env, jobject file, jfieldID id) { return pathToNTPath(env, path, JNI_FALSE); } +/* Returns the working directory for the given drive, or NULL */ +WCHAR* +currentDir(int di) { + UINT dt; + WCHAR root[4]; + // verify drive is valid as _wgetdcwd in the VC++ 2010 runtime + // library does not handle invalid drives. + root[0] = L'A' + (WCHAR)(di - 1); + root[1] = L':'; + root[2] = L'\\'; + root[3] = L'\0'; + dt = GetDriveTypeW(root); + if (dt == DRIVE_UNKNOWN || dt == DRIVE_NO_ROOT_DIR) { + return NULL; + } else { + return _wgetdcwd(di, NULL, MAX_PATH); + } +} + /* We cache the length of current working dir here to avoid calling _wgetcwd() every time we need to resolve a relative path. This piece of code needs to be revisited if chdir @@ -83,7 +102,7 @@ currentDirLength(const WCHAR* ps, int pathlen) { if ((d >= L'a') && (d <= L'z')) di = d - L'a' + 1; else if ((d >= L'A') && (d <= L'Z')) di = d - L'A' + 1; else return 0; /* invalid drive name. */ - dir = _wgetdcwd(di, NULL, MAX_PATH); + dir = currentDir(di); if (dir != NULL){ dirlen = wcslen(dir); free(dir); diff --git a/jdk/src/windows/native/java/io/io_util_md.h b/jdk/src/windows/native/java/io/io_util_md.h index c937adfbfb8..6b6b89b6397 100644 --- a/jdk/src/windows/native/java/io/io_util_md.h +++ b/jdk/src/windows/native/java/io/io_util_md.h @@ -33,6 +33,7 @@ WCHAR* pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE); WCHAR* fileToNTPath(JNIEnv *env, jobject file, jfieldID id); WCHAR* getPrefixed(const WCHAR* path, int pathlen); +WCHAR* currentDir(int di); int currentDirLength(const WCHAR* path, int pathlen); void fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags); int handleAvailable(jlong fd, jlong *pbytes); diff --git a/jdk/src/windows/native/java/nio/MappedByteBuffer.c b/jdk/src/windows/native/java/nio/MappedByteBuffer.c index 5af3b99c73d..7ee6da52103 100644 --- a/jdk/src/windows/native/java/nio/MappedByteBuffer.c +++ b/jdk/src/windows/native/java/nio/MappedByteBuffer.c @@ -51,11 +51,11 @@ Java_java_nio_MappedByteBuffer_load0(JNIEnv *env, jobject obj, jlong address, } JNIEXPORT void JNICALL -Java_java_nio_MappedByteBuffer_force0(JNIEnv *env, jobject obj, jlong address, - jlong len) +Java_java_nio_MappedByteBuffer_force0(JNIEnv *env, jobject obj, jobject fdo, + jlong address, jlong len) { void *a = (void *) jlong_to_ptr(address); - int result; + BOOL result; int retry; /* @@ -71,6 +71,30 @@ Java_java_nio_MappedByteBuffer_force0(JNIEnv *env, jobject obj, jlong address, retry++; } while (retry < 3); + /** + * FlushViewOfFile only initiates the writing of dirty pages to disk + * so we have to call FlushFileBuffers to and ensure they are written. + */ + if (result != 0) { + // by right, the jfieldID initialization should be in a static + // initializer but we do it here instead to avoiding needing to + // load nio.dll during startup. + static jfieldID handle_fdID; + HANDLE h; + if (handle_fdID == NULL) { + jclass clazz = (*env)->FindClass(env, "java/io/FileDescriptor"); + if (clazz == NULL) + return; // exception thrown + handle_fdID = (*env)->GetFieldID(env, clazz, "handle", "J"); + } + h = jlong_to_ptr((*env)->GetLongField(env, fdo, handle_fdID)); + result = FlushFileBuffers(h); + if (result == 0 && GetLastError() == ERROR_ACCESS_DENIED) { + // read-only mapping + result = 1; + } + } + if (result == 0) { JNU_ThrowIOExceptionWithLastError(env, "Flush failed"); } diff --git a/jdk/src/windows/native/sun/nio/ch/FileDispatcherImpl.c b/jdk/src/windows/native/sun/nio/ch/FileDispatcherImpl.c index d31ef21ed83..f4d0b17d63b 100644 --- a/jdk/src/windows/native/sun/nio/ch/FileDispatcherImpl.c +++ b/jdk/src/windows/native/sun/nio/ch/FileDispatcherImpl.c @@ -32,6 +32,7 @@ #include #include "nio.h" #include "nio_util.h" +#include "jlong.h" /************************************************************** @@ -441,3 +442,15 @@ Java_sun_nio_ch_FileDispatcherImpl_closeByHandle(JNIEnv *env, jclass clazz, { closeFile(env, fd); } + +JNIEXPORT jlong JNICALL +Java_sun_nio_ch_FileDispatcherImpl_duplicateHandle(JNIEnv *env, jclass this, jlong hFile) +{ + HANDLE hProcess = GetCurrentProcess(); + HANDLE hResult; + BOOL res = DuplicateHandle(hProcess, hFile, hProcess, &hResult, 0, FALSE, + DUPLICATE_SAME_ACCESS); + if (res == 0) + JNU_ThrowIOExceptionWithLastError(env, "DuplicateHandle failed"); + return ptr_to_jlong(hResult); +} diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index 54bfbb47a16..71307cb9e58 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -2329,6 +2329,19 @@ MsgRouting AwtComponent::WmMouseDown(UINT flags, int x, int y, int button) MSG msg; InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); + AwtWindow *toplevel = GetContainer(); + if (toplevel && !toplevel->IsSimpleWindow()) { + /* + * The frame should be focused by click in case it is + * the active window but not the focused window. See 6886678. + */ + if (toplevel->GetHWnd() == ::GetActiveWindow() && + toplevel->GetHWnd() != AwtComponent::GetFocusedWindow()) + { + toplevel->AwtSetActiveWindow(); + } + } + SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, now, x, y, GetJavaModifiers(), clickCount, JNI_FALSE, GetButton(button), &msg); diff --git a/jdk/src/windows/native/sun/windows/awt_Desktop.cpp b/jdk/src/windows/native/sun/windows/awt_Desktop.cpp index 4121c8af9b5..67506f3bc1e 100644 --- a/jdk/src/windows/native/sun/windows/awt_Desktop.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Desktop.cpp @@ -59,15 +59,17 @@ JNIEXPORT jstring JNICALL Java_sun_awt_windows_WDesktopPeer_ShellExecute FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, - GetLastError(), + (int)retval, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&buffer, 0, NULL ); - jstring errmsg = JNU_NewStringPlatform(env, buffer, len); - LocalFree(buffer); - return errmsg; + if (buffer) { + jstring errmsg = JNU_NewStringPlatform(env, buffer); + LocalFree(buffer); + return errmsg; + } } return NULL; diff --git a/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp b/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp index a6ad4325481..50d305fd511 100644 --- a/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp +++ b/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp @@ -505,7 +505,8 @@ void AwtDesktopProperties::GetOtherParameters() { SetIntegerProperty(TEXT("win.drag.width"), cxdrag); SetIntegerProperty(TEXT("win.drag.height"), cydrag); SetIntegerProperty(TEXT("DnD.gestureMotionThreshold"), max(cxdrag, cydrag)/2); - SetIntegerProperty(TEXT("awt.mouse.numButtons"), GetSystemMetrics(SM_CMOUSEBUTTONS)); + SetIntegerProperty(TEXT("awt.mouse.numButtons"), AwtToolkit::GetNumberOfButtons()); + SetIntegerProperty(TEXT("awt.multiClickInterval"), GetDoubleClickTime()); // BEGIN cross-platform properties diff --git a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp index ff23a086612..2beb5191bd2 100644 --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp @@ -133,6 +133,8 @@ extern "C" JNIEXPORT jboolean JNICALL AWTIsHeadless() { static LPCTSTR szAwtToolkitClassName = TEXT("SunAwtToolkit"); +static const int MOUSE_BUTTONS_WINDOWS_SUPPORTED = 5; //three standard buttons + XBUTTON1 + XBUTTON2. + UINT AwtToolkit::GetMouseKeyState() { static BOOL mbSwapped = ::GetSystemMetrics(SM_SWAPBUTTON); @@ -2310,5 +2312,9 @@ void AwtToolkit::setExtraMouseButtonsEnabled(BOOL enable) { JNIEXPORT jint JNICALL Java_sun_awt_windows_WToolkit_getNumberOfButtonsImpl (JNIEnv *, jobject self) { - return GetSystemMetrics(SM_CMOUSEBUTTONS); + return AwtToolkit::GetNumberOfButtons(); +} + +UINT AwtToolkit::GetNumberOfButtons() { + return MOUSE_BUTTONS_WINDOWS_SUPPORTED; } diff --git a/jdk/src/windows/native/sun/windows/awt_Toolkit.h b/jdk/src/windows/native/sun/windows/awt_Toolkit.h index 054b607c42b..2a957719337 100644 --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.h +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.h @@ -185,6 +185,7 @@ public: BOOL IsDynamicLayoutActive(); BOOL areExtraMouseButtonsEnabled(); void setExtraMouseButtonsEnabled(BOOL enable); + static UINT GetNumberOfButtons(); INLINE BOOL localPump() { return m_localPump; } INLINE BOOL VerifyComponents() { return FALSE; } // TODO: Use new DebugHelper class to set this flag diff --git a/jdk/test/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream/BufferOverflowTest.java b/jdk/test/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream/BufferOverflowTest.java new file mode 100644 index 00000000000..ffb3c9e963d --- /dev/null +++ b/jdk/test/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream/BufferOverflowTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test %I% %E% + * @bug 6954275 + * @summary Check that UnsyncByteArrayOutputStream does not + * throw ArrayIndexOutOfBoundsException + * @compile -XDignore.symbol.file BufferOverflowTest.java + * @run main BufferOverflowTest + */ + +import com.sun.org.apache.xml.internal.security.utils.UnsyncByteArrayOutputStream; + +public class BufferOverflowTest { + + public static void main(String[] args) throws Exception { + try { + UnsyncByteArrayOutputStream out = new UnsyncByteArrayOutputStream(); + out.write(new byte[(8192) << 2 + 1]); + System.out.println("PASSED"); + } catch (ArrayIndexOutOfBoundsException e) { + System.err.println("FAILED, got ArrayIndexOutOfBoundsException"); + throw new Exception(e); + } + } +} diff --git a/jdk/test/demo/zipfs/Basic.java b/jdk/test/demo/zipfs/Basic.java new file mode 100644 index 00000000000..91f8af274ee --- /dev/null +++ b/jdk/test/demo/zipfs/Basic.java @@ -0,0 +1,159 @@ +/* + * 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.nio.file.spi.FileSystemProvider; +import java.util.*; +import java.net.URI; +import java.io.IOException; + +/** + * Basic test for zip provider + */ + +public class Basic { + public static void main(String[] args) throws Exception { + Path zipfile = Paths.get(args[0]); + + // Test: zip should should be returned in provider list + boolean found = false; + + for (FileSystemProvider provider: FileSystemProvider.installedProviders()) { + if (provider.getScheme().equalsIgnoreCase("zip")) { + found = true; + break; + } + } + if (!found) + throw new RuntimeException("'zip' provider not installed"); + + // Test: FileSystems#newFileSystem(FileRef) + Map env = new HashMap(); + FileSystems.newFileSystem(zipfile, env, null).close(); + + // Test: FileSystems#newFileSystem(URI) + URI uri = URI.create("zip" + zipfile.toUri().toString().substring(4)); + FileSystem fs = FileSystems.newFileSystem(uri, env, null); + + // Test: exercise toUri method + String expected = uri.toString() + "#/foo"; + String actual = fs.getPath("/foo").toUri().toString(); + if (!actual.equals(expected)) { + throw new RuntimeException("toUri returned '" + actual + + "', expected '" + expected + "'"); + } + + // Test: exercise directory iterator and retrieval of basic attributes + Files.walkFileTree(fs.getPath("/"), new FileTreePrinter()); + + // Test: DirectoryStream + found = false; + DirectoryStream stream = fs.getPath("/").newDirectoryStream(); + try { + for (Path entry: stream) { + found = entry.toString().equals("/META-INF/"); + if (found) break; + } + } finally { + stream.close(); + } + + if (!found) + throw new RuntimeException("Expected file not found"); + + // Test: copy file from zip file to current (scratch) directory + Path source = fs.getPath("/META-INF/services/java.nio.file.spi.FileSystemProvider"); + if (source.exists()) { + Path target = Paths.get(source.getName().toString()); + source.copyTo(target, StandardCopyOption.REPLACE_EXISTING); + try { + long s1 = Attributes.readBasicFileAttributes(source).size(); + long s2 = Attributes.readBasicFileAttributes(target).size(); + if (s2 != s1) + throw new RuntimeException("target size != source size"); + } finally { + target.delete(); + } + } + + // Test: FileStore + FileStore store = fs.getPath("/").getFileStore(); + if (!store.supportsFileAttributeView("basic")) + throw new RuntimeException("BasicFileAttributeView should be supported"); + + // Test: ClosedFileSystemException + fs.close(); + if (fs.isOpen()) + throw new RuntimeException("FileSystem should be closed"); + try { + fs.getPath("/missing").checkAccess(AccessMode.READ); + } catch (ClosedFileSystemException x) { } + } + + // FileVisitor that pretty prints a file tree + static class FileTreePrinter extends SimpleFileVisitor { + private int indent = 0; + + private void indent() { + StringBuilder sb = new StringBuilder(indent); + for (int i=0; i %s", s, path); + } catch (Exception x) { + exc = x; + out.format("%s -> %s", s, x); + } + out.println(); + } + + Path path() { + return path; + } + + void fail() { + throw new RuntimeException("PathOps failed"); + } + + void checkPath() { + if (path == null) { + throw new InternalError("path is null"); + } + } + + void check(Object result, String expected) { + out.format("\tExpected: %s\n", expected); + out.format("\tActual: %s\n", result); + if (result == null) { + if (expected == null) return; + } else { + // compare string representations + if (expected != null && result.toString().equals(expected.toString())) + return; + } + fail(); + } + + void check(Object result, boolean expected) { + check(result, Boolean.toString(expected)); + } + + PathOps root(String expected) { + out.println("check root"); + checkPath(); + check(path.getRoot(), expected); + return this; + } + + PathOps parent(String expected) { + out.println("check parent"); + checkPath(); + check(path.getParent(), expected); + return this; + } + + PathOps name(String expected) { + out.println("check name"); + checkPath(); + check(path.getName(), expected); + return this; + } + + PathOps element(int index, String expected) { + out.format("check element %d\n", index); + checkPath(); + check(path.getName(index), expected); + return this; + } + + PathOps subpath(int startIndex, int endIndex, String expected) { + out.format("test subpath(%d,%d)\n", startIndex, endIndex); + checkPath(); + check(path.subpath(startIndex, endIndex), expected); + return this; + } + + PathOps starts(String prefix) { + out.format("test startsWith with %s\n", prefix); + checkPath(); + Path s = fs.getPath(prefix); + check(path.startsWith(s), true); + return this; + } + + PathOps notStarts(String prefix) { + out.format("test not startsWith with %s\n", prefix); + checkPath(); + Path s = fs.getPath(prefix); + check(path.startsWith(s), false); + return this; + } + + PathOps ends(String suffix) { + out.format("test endsWith %s\n", suffix); + checkPath(); + Path s = fs.getPath(suffix); + check(path.endsWith(s), true); + return this; + } + + PathOps notEnds(String suffix) { + out.format("test not endsWith %s\n", suffix); + checkPath(); + Path s = fs.getPath(suffix); + check(path.endsWith(s), false); + return this; + } + + PathOps absolute() { + out.println("check path is absolute"); + checkPath(); + check(path.isAbsolute(), true); + return this; + } + + PathOps notAbsolute() { + out.println("check path is not absolute"); + checkPath(); + check(path.isAbsolute(), false); + return this; + } + + PathOps resolve(String other, String expected) { + out.format("test resolve %s\n", other); + checkPath(); + check(path.resolve(other), expected); + return this; + } + + PathOps relativize(String other, String expected) { + out.format("test relativize %s\n", other); + checkPath(); + Path that = fs.getPath(other); + check(path.relativize(that), expected); + return this; + } + + PathOps normalize(String expected) { + out.println("check normalized path"); + checkPath(); + check(path.normalize(), expected); + return this; + } + + PathOps string(String expected) { + out.println("check string representation"); + checkPath(); + check(path, expected); + return this; + } + + PathOps invalid() { + if (!(exc instanceof InvalidPathException)) { + out.println("InvalidPathException not thrown as expected"); + fail(); + } + return this; + } + + static PathOps test(String s) { + return new PathOps(s); + } + + // -- PathOpss -- + + static void header(String s) { + out.println(); + out.println(); + out.println("-- " + s + " --"); + } + + static void doPathOpTests() { + header("Path operations"); + + // all components + test("/a/b/c") + .root("/") + .parent("/a/b") + .name("c"); + + // root component only + test("/") + .root("/") + .parent(null) + .name(null); + + // no root component + test("a/b") + .root(null) + .parent("a") + .name("b"); + + // name component only + test("foo") + .root(null) + .parent(null) + .name("foo"); + + // startsWith + test("/") + .starts("/") + .notStarts("/foo"); + test("/foo") + .starts("/") + .starts("/foo") + .notStarts("/f"); + test("/foo/bar") + .starts("/") + .starts("/foo") + .starts("/foo/bar") + .notStarts("/f") + .notStarts("foo") + .notStarts("foo/bar"); + test("foo") + .starts("foo") + .notStarts("f"); + test("foo/bar") + .starts("foo") + .starts("foo/bar") + .notStarts("f") + .notStarts("/foo") + .notStarts("/foo/bar"); + + // endsWith + test("/") + .ends("/") + .notEnds("foo") + .notEnds("/foo"); + test("/foo") + .ends("foo") + .ends("/foo") + .notEnds("/"); + test("/foo/bar") + .ends("bar") + .ends("foo/bar") + .ends("/foo/bar") + .notEnds("/bar"); + test("foo") + .ends("foo"); + test("foo/bar") + .ends("bar") + .ends("foo/bar"); + + // elements + test("a/b/c") + .element(0,"a") + .element(1,"b") + .element(2,"c"); + + // isAbsolute + test("/") + .absolute(); + test("/tmp") + .absolute(); + test("tmp") + .notAbsolute(); + + // resolve + test("/tmp") + .resolve("foo", "/tmp/foo") + .resolve("/foo", "/foo"); + test("tmp") + .resolve("foo", "tmp/foo") + .resolve("/foo", "/foo"); + + // relativize + test("/a/b/c") + .relativize("/a/b/c", null) + .relativize("/a/b/c/d/e", "d/e") + .relativize("/a/x", "../../x"); + + // normalize + test("/") + .normalize("/"); + test("foo") + .normalize("foo"); + test("/foo") + .normalize("/foo"); + test(".") + .normalize(null); + test("..") + .normalize(".."); + test("/..") + .normalize("/"); + test("/../..") + .normalize("/"); + test("foo/.") + .normalize("foo"); + test("./foo") + .normalize("foo"); + test("foo/..") + .normalize(null); + test("../foo") + .normalize("../foo"); + test("../../foo") + .normalize("../../foo"); + test("foo/bar/..") + .normalize("foo"); + test("foo/bar/gus/../..") + .normalize("foo"); + test("/foo/bar/gus/../..") + .normalize("/foo"); + + // invalid + test("foo\u0000bar") + .invalid(); + test("\u0000foo") + .invalid(); + test("bar\u0000") + .invalid(); + test("//foo\u0000bar") + .invalid(); + test("//\u0000foo") + .invalid(); + test("//bar\u0000") + .invalid(); + + // normalization + test("//foo//bar") + .string("/foo/bar") + .root("/") + .parent("/foo") + .name("bar"); + } + + static void npes() { + header("NullPointerException"); + + Path path = fs.getPath("foo"); + + try { + path.resolve((String)null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.relativize(null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.compareTo(null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.startsWith(null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.endsWith(null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + } + + public static void main(String[] args) throws Throwable { + + Path zipfile = Paths.get(args[0]); + Map env = new HashMap(); + fs = FileSystems.newFileSystem(zipfile, env, null); + npes(); + doPathOpTests(); + fs.close(); + } +} diff --git a/jdk/test/demo/zipfs/ZipFSTester.java b/jdk/test/demo/zipfs/ZipFSTester.java new file mode 100644 index 00000000000..54b9274db13 --- /dev/null +++ b/jdk/test/demo/zipfs/ZipFSTester.java @@ -0,0 +1,633 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.*; +import java.nio.*; +import java.nio.channels.*; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.net.*; +import java.util.*; + +import static java.nio.file.StandardOpenOption.*; +import static java.nio.file.StandardCopyOption.*; + +/* + * Tests various zipfs operations. + */ + +public class ZipFSTester { + + public static void main(String[] args) throws Throwable { + FileSystem fs = null; + try { + fs = newZipFileSystem(Paths.get(args[0]), new HashMap()); + test(fs); + test2(fs); // more tests + } finally { + if (fs != null) + fs.close(); + } + } + + static void test(FileSystem fs) + throws Exception + { + Random rdm = new Random(); + + // clone a fs and test on it + Path tmpfsPath = getTempPath(); + Map env = new HashMap(); + env.put("createNew", true); + FileSystem fs0 = newZipFileSystem(tmpfsPath, env); + z2zcopy(fs, fs0, "/", 0); + fs0.close(); // sync to file + + fs = newZipFileSystem(tmpfsPath, new HashMap()); + + try { + // prepare a src + Path src = getTempPath(); + String tmpName = src.toString(); + OutputStream os = src.newOutputStream(); + byte[] bits = new byte[12345]; + rdm.nextBytes(bits); + os.write(bits); + os.close(); + + // copyin + Path dst = getPathWithParents(fs, tmpName); + src.copyTo(dst); + checkEqual(src, dst); + + // copy + Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) + + "/efg" + rdm.nextInt(100) + "/foo.class"); + dst.copyTo(dst2); + //dst.moveTo(dst2); + checkEqual(src, dst2); + + // delete + dst.delete(); + if (dst.exists()) + throw new RuntimeException("Failed!"); + + // moveout + Path dst3 = Paths.get(tmpName + "_Tmp"); + dst2.moveTo(dst3); + checkEqual(src, dst3); + + // delete + if (dst2.exists()) + throw new RuntimeException("Failed!"); + dst3.delete(); + if (dst3.exists()) + throw new RuntimeException("Failed!"); + + // newInputStream on dir + Path parent = dst2.getParent(); + try { + parent.newInputStream(); + throw new RuntimeException("Failed"); + } catch (FileSystemException e) { + e.printStackTrace(); // expected fse + } + + // rmdirs + try { + rmdirs(parent); + } catch (IOException x) { + x.printStackTrace(); + } + + // newFileChannel() copy in, out and verify via fch + fchCopy(src, dst); // in + checkEqual(src, dst); + Path tmp = Paths.get(tmpName + "_Tmp"); + fchCopy(dst, tmp); // out + checkEqual(src, tmp); + tmp.delete(); + + // test channels + channel(fs, dst); + dst.delete(); + src.delete(); + } finally { + if (fs != null) + fs.close(); + if (tmpfsPath.exists()) + tmpfsPath.delete(); + } + } + + static void test2(FileSystem fs) throws Exception { + + Path fs1Path = getTempPath(); + Path fs2Path = getTempPath(); + Path fs3Path = getTempPath(); + + if (fs1Path.exists()) + fs1Path.delete(); + if (fs2Path.exists()) + fs2Path.delete(); + if (fs3Path.exists()) + fs3Path.delete(); + + // create a new filesystem, copy everything from fs + Map env = new HashMap(); + env.put("createNew", true); + FileSystem fs0 = newZipFileSystem(fs1Path, env); + + final FileSystem fs2 = newZipFileSystem(fs2Path, env); + final FileSystem fs3 = newZipFileSystem(fs3Path, env); + + System.out.println("copy src: fs -> fs0..."); + z2zcopy(fs, fs0, "/", 0); // copy fs -> fs1 + fs0.close(); // dump to file + + System.out.println("open fs0 as fs1"); + env = new HashMap(); + final FileSystem fs1 = newZipFileSystem(fs1Path, env); + + System.out.println("listing..."); + final ArrayList files = new ArrayList<>(); + final ArrayList dirs = new ArrayList<>(); + list(fs1.getPath("/"), files, dirs); + + Thread t0 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(dirs); + Collections.shuffle(list); + for (String path : list) { + try { + z2zcopy(fs1, fs2, path, 0); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + + }); + + Thread t1 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(dirs); + Collections.shuffle(list); + for (String path : list) { + try { + z2zcopy(fs1, fs2, path, 1); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + + }); + + Thread t2 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(dirs); + Collections.shuffle(list); + for (String path : list) { + try { + z2zcopy(fs1, fs2, path, 2); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + + }); + + Thread t3 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(files); + Collections.shuffle(list); + while (!list.isEmpty()) { + Iterator itr = list.iterator(); + while (itr.hasNext()) { + String path = itr.next(); + try { + if (fs2.getPath(path).exists()) { + z2zmove(fs2, fs3, path); + itr.remove(); + } + } catch (FileAlreadyExistsException x){ + itr.remove(); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + } + + }); + + System.out.println("copying/removing..."); + t0.start(); t1.start(); t2.start(); t3.start(); + t0.join(); t1.join(); t2.join(); t3.join(); + + System.out.println("closing: fs1, fs2"); + fs1.close(); + fs2.close(); + + int failed = 0; + System.out.println("checkEqual: fs vs fs3"); + for (String path : files) { + try { + checkEqual(fs.getPath(path), fs3.getPath(path)); + } catch (IOException x) { + //x.printStackTrace(); + failed++; + } + } + System.out.println("closing: fs3"); + fs3.close(); + + System.out.println("opening: fs3 as fs4"); + FileSystem fs4 = newZipFileSystem(fs3Path, env); + + + ArrayList files2 = new ArrayList<>(); + ArrayList dirs2 = new ArrayList<>(); + list(fs4.getPath("/"), files2, dirs2); + + System.out.println("checkEqual: fs vs fs4"); + for (String path : files2) { + checkEqual(fs.getPath(path), fs4.getPath(path)); + } + System.out.println("walking: fs4"); + walk(fs4.getPath("/")); + System.out.println("closing: fs4"); + fs4.close(); + + System.out.printf("failed=%d%n", failed); + + fs1Path.delete(); + fs2Path.delete(); + fs3Path.delete(); + } + + private static FileSystem newZipFileSystem(Path path, Map env) + throws IOException + { + return FileSystems.newFileSystem( + URI.create("zip" + + path.toUri().toString().substring(4)), + env, + null); + } + + private static Path getTempPath() throws IOException + { + File tmp = File.createTempFile("testzipfs_", "zip"); + tmp.delete(); // we need a clean path, no file + return tmp.toPath(); + } + + private static void list(Path path, List files, List dirs ) + throws IOException + { + if (Attributes.readBasicFileAttributes(path).isDirectory()) { + DirectoryStream ds = path.newDirectoryStream(); + for (Path child : ds) + list(child, files, dirs); + ds.close(); + dirs.add(path.toString()); + } else { + files.add(path.toString()); + } + } + + private static void z2zcopy(FileSystem src, FileSystem dst, String path, + int method) + throws IOException + { + Path srcPath = src.getPath(path); + Path dstPath = dst.getPath(path); + + if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) { + if (!dstPath.exists()) { + try { + mkdirs(dstPath); + } catch (FileAlreadyExistsException x) {} + } + DirectoryStream ds = srcPath.newDirectoryStream(); + for (Path child : ds) { + z2zcopy(src, dst, + path + (path.endsWith("/")?"":"/") + child.getName(), + method); + } + ds.close(); + } else { + try { + if (dstPath.exists()) + return; + switch (method) { + case 0: + srcPath.copyTo(dstPath); + break; + case 1: + chCopy(srcPath, dstPath); + break; + case 2: + //fchCopy(srcPath, dstPath); + streamCopy(srcPath, dstPath); + break; + } + } catch (FileAlreadyExistsException x) {} + } + } + + private static void z2zmove(FileSystem src, FileSystem dst, String path) + throws IOException + { + Path srcPath = src.getPath(path); + Path dstPath = dst.getPath(path); + + if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) { + if (!dstPath.exists()) + mkdirs(dstPath); + DirectoryStream ds = srcPath.newDirectoryStream(); + for (Path child : ds) { + z2zmove(src, dst, + path + (path.endsWith("/")?"":"/") + child.getName()); + } + ds.close(); + } else { + //System.out.println("moving..." + path); + Path parent = dstPath.getParent(); + if (parent != null && parent.notExists()) + mkdirs(parent); + srcPath.moveTo(dstPath); + } + } + + private static void walk(Path path) throws IOException + { + Files.walkFileTree( + path, + new SimpleFileVisitor() { + private int indent = 0; + private void indent() { + int n = 0; + while (n++ < indent) + System.out.printf(" "); + } + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) + { + indent(); + System.out.printf("%s%n", file.getName().toString()); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) + { + indent(); + System.out.printf("[%s]%n", dir.toString()); + indent += 2; + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, + IOException ioe) + throws IOException + { + indent -= 2; + return FileVisitResult.CONTINUE; + } + }); + } + + private static void mkdirs(Path path) throws IOException { + path = path.toAbsolutePath(); + Path parent = path.getParent(); + if (parent != null) { + if (parent.notExists()) + mkdirs(parent); + } + path.createDirectory(); + } + + private static void rmdirs(Path path) throws IOException { + while (path != null && path.getNameCount() != 0) { + path.delete(); + path = path.getParent(); + } + } + + // check the content of two paths are equal + private static void checkEqual(Path src, Path dst) throws IOException + { + //System.out.printf("checking <%s> vs <%s>...%n", + // src.toString(), dst.toString()); + + //streams + InputStream isSrc = src.newInputStream(); + InputStream isDst = dst.newInputStream(); + byte[] bufSrc = new byte[8192]; + byte[] bufDst = new byte[8192]; + + try { + int nSrc = 0; + while ((nSrc = isSrc.read(bufSrc)) != -1) { + int nDst = 0; + while (nDst < nSrc) { + int n = isDst.read(bufDst, nDst, nSrc - nDst); + if (n == -1) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nDst += n; + } + while (--nSrc >= 0) { + if (bufSrc[nSrc] != bufDst[nSrc]) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nSrc--; + } + } + } finally { + isSrc.close(); + isDst.close(); + } + + // channels + SeekableByteChannel chSrc = src.newByteChannel(); + SeekableByteChannel chDst = dst.newByteChannel(); + if (chSrc.size() != chDst.size()) { + System.out.printf("src[%s].size=%d, dst[%s].size=%d%n", + chSrc.toString(), chSrc.size(), + chDst.toString(), chDst.size()); + throw new RuntimeException("CHECK FAILED!"); + } + ByteBuffer bbSrc = ByteBuffer.allocate(8192); + ByteBuffer bbDst = ByteBuffer.allocate(8192); + + try { + int nSrc = 0; + while ((nSrc = chSrc.read(bbSrc)) != -1) { + int nDst = chDst.read(bbDst); + if (nSrc != nDst) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + while (--nSrc >= 0) { + if (bbSrc.get(nSrc) != bbDst.get(nSrc)) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nSrc--; + } + bbSrc.flip(); + bbDst.flip(); + } + } catch (IOException x) { + x.printStackTrace(); + } finally { + chSrc.close(); + chDst.close(); + } + } + + private static void fchCopy(Path src, Path dst) throws IOException + { + Set read = new HashSet<>(); + read.add(READ); + Set openwrite = new HashSet<>(); + openwrite.add(CREATE_NEW); + openwrite.add(WRITE); + + FileChannel srcFc = src.getFileSystem() + .provider() + .newFileChannel(src, read); + FileChannel dstFc = dst.getFileSystem() + .provider() + .newFileChannel(dst, openwrite); + + try { + ByteBuffer bb = ByteBuffer.allocate(8192); + while (srcFc.read(bb) >= 0) { + bb.flip(); + dstFc.write(bb); + bb.clear(); + } + } finally { + srcFc.close(); + dstFc.close(); + } + } + + private static void chCopy(Path src, Path dst) throws IOException + { + Set read = new HashSet<>(); + read.add(READ); + Set openwrite = new HashSet<>(); + openwrite.add(CREATE_NEW); + openwrite.add(WRITE); + + SeekableByteChannel srcCh = src.newByteChannel(read); + SeekableByteChannel dstCh = dst.newByteChannel(openwrite); + + try { + ByteBuffer bb = ByteBuffer.allocate(8192); + while (srcCh.read(bb) >= 0) { + bb.flip(); + dstCh.write(bb); + bb.clear(); + } + } finally { + srcCh.close(); + dstCh.close(); + } + } + + private static void streamCopy(Path src, Path dst) throws IOException + { + InputStream isSrc = src.newInputStream(); + OutputStream osDst = dst.newOutputStream(); + byte[] buf = new byte[8192]; + try { + int n = 0; + while ((n = isSrc.read(buf)) != -1) { + osDst.write(buf, 0, n); + } + } finally { + isSrc.close(); + osDst.close(); + } + } + + static void channel(FileSystem fs, Path path) + throws Exception + { + System.out.println("test ByteChannel..."); + SeekableByteChannel sbc = path.newByteChannel(); + Set read = new HashSet<>(); + read.add(READ); + System.out.printf(" sbc[0]: pos=%d, size=%d%n", sbc.position(), sbc.size()); + ByteBuffer bb = ByteBuffer.allocate((int)sbc.size()); + int n = sbc.read(bb); + System.out.printf(" sbc[1]: read=%d, pos=%d, size=%d%n", + n, sbc.position(), sbc.size()); + ByteBuffer bb2 = ByteBuffer.allocate((int)sbc.size()); + int N = 120; + sbc.close(); + + // sbc.position(pos) is not supported in current version + // try the FileChannel + sbc = fs.provider().newFileChannel(path, read); + sbc.position(N); + System.out.printf(" sbc[2]: pos=%d, size=%d%n", + sbc.position(), sbc.size()); + bb2.limit(100); + n = sbc.read(bb2); + System.out.printf(" sbc[3]: read=%d, pos=%d, size=%d%n", + n, sbc.position(), sbc.size()); + System.out.printf(" sbc[4]: bb[%d]=%d, bb1[0]=%d%n", + N, bb.get(N) & 0xff, bb2.get(0) & 0xff); + sbc.close(); + } + + // create parents if does not exist + static Path getPathWithParents(FileSystem fs, String name) + throws Exception + { + Path path = fs.getPath(name); + Path parent = path.getParent(); + if (parent != null && parent.notExists()) + mkdirs(parent); + return path; + } +} diff --git a/jdk/test/demo/zipfs/basic.sh b/jdk/test/demo/zipfs/basic.sh new file mode 100644 index 00000000000..c6cfb77caf3 --- /dev/null +++ b/jdk/test/demo/zipfs/basic.sh @@ -0,0 +1,73 @@ +# +# 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. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# @test +# @bug 6990846 +# @summary Test ZipFileSystem demo +# @build Basic PathOps ZipFSTester +# @run shell basic.sh + +if [ -z "${TESTJAVA}" ]; then + echo "Test must be run with jtreg" + exit 0 +fi + +ZIPFS="${TESTJAVA}/demo/nio/zipfs/zipfs.jar" +if [ ! -r "${ZIPFS}" ]; then + echo "${ZIPFS} not found" + exit 0 +fi + +OS=`uname -s` +case "$OS" in + Windows_* ) + CLASSPATH="${TESTCLASSES};${ZIPFS}" + ;; + * ) + CLASSPATH="${TESTCLASSES}:${ZIPFS}" + ;; +esac +export CLASSPATH + +failures=0 + +go() { + echo "" + ${TESTJAVA}/bin/java $1 $2 $3 2>&1 + if [ $? != 0 ]; then failures=`expr $failures + 1`; fi +} + +# Run the tests + +go Basic "${ZIPFS}" +go PathOps "${ZIPFS}" +go ZipFSTester "${ZIPFS}" + +# +# Results +# + +if [ $failures -gt 0 ]; +then echo "$failures tests failed"; +else echo "All tests passed"; +fi +exit $failures diff --git a/jdk/test/java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java b/jdk/test/java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java new file mode 100644 index 00000000000..6c13b37aa0d --- /dev/null +++ b/jdk/test/java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1995, 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. + */ + +/* + @test FocusOwnerFrameOnClick.java %W% %E% + @bug 6886678 + @summary Tests that clicking an owner frame switches focus from its owned window. + @author Anton Tarasov: area=awt.focus + @library ../../regtesthelpers + @build Util + @run main FocusOwnerFrameOnClick +*/ + +import java.awt.*; +import java.awt.event.*; +import java.applet.Applet; +import java.util.concurrent.atomic.AtomicBoolean; +import java.lang.reflect.InvocationTargetException; +import test.java.awt.regtesthelpers.Util; + +public class FocusOwnerFrameOnClick extends Applet { + Robot robot; + Frame frame = new Frame("Frame"); + Window window = new Window(frame); + Button fButton = new Button("fButton"); + Button wButton = new Button("wButton"); + + AtomicBoolean focused = new AtomicBoolean(false); + + public static void main(String[] args) { + FocusOwnerFrameOnClick app = new FocusOwnerFrameOnClick(); + app.init(); + app.start(); + } + + public void init() { + robot = Util.createRobot(); + + frame.setLayout(new FlowLayout()); + frame.setSize(200, 200); + frame.add(fButton); + + window.setLocation(300, 0); + window.add(wButton); + window.pack(); + } + + public void start() { + frame.setVisible(true); + Util.waitForIdle(robot); + + window.setVisible(true); + Util.waitForIdle(robot); + + if (!wButton.hasFocus()) { + if (!Util.trackFocusGained(wButton, new Runnable() { + public void run() { + Util.clickOnComp(wButton, robot); + } + }, 2000, false)) + { + throw new TestErrorException("wButton didn't gain focus on showing"); + } + } + + Runnable clickAction = new Runnable() { + public void run() { + Point loc = fButton.getLocationOnScreen(); + Dimension dim = fButton.getSize(); + + robot.mouseMove(loc.x, loc.y + dim.height + 20); + robot.delay(50); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.delay(50); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + } + }; + + if (!Util.trackWindowGainedFocus(frame, clickAction, 2000, true)) { + throw new TestFailedException("The frame wasn't focused on click"); + } + + System.out.println("Test passed."); + } +} + +/** + * Thrown when the behavior being verified is found wrong. + */ +class TestFailedException extends RuntimeException { + TestFailedException(String msg) { + super("Test failed: " + msg); + } +} + +/** + * Thrown when an error not related to the behavior being verified is encountered. + */ +class TestErrorException extends RuntimeException { + TestErrorException(String msg) { + super("Unexpected error: " + msg); + } +} diff --git a/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java b/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java index f70b8dd691b..0571820837d 100644 --- a/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java +++ b/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java @@ -21,16 +21,15 @@ public class MouseModifiersUnitTest_Extra extends Frame { static final int SHIFT = 1; static final int CTRL = 2; static final int ALT = 3; - static CheckingModifierAdapter adapterTest1; - static CheckingModifierAdapter adapterTest2; - static CheckingModifierAdapter adapterTest3; - static CheckingModifierAdapter adapterTest4; + static CheckingModifierAdapterExtra adapterTest1; + static CheckingModifierAdapterExtra adapterTest2; + static CheckingModifierAdapterExtra adapterTest3; + static CheckingModifierAdapterExtra adapterTest4; static boolean debug = true; //dump all errors (debug) or throw first(under jtreg) exception static boolean autorun = false; //use robot or manual run static int testModifier = NONE; - static int [] mouseButtons; static int [] mouseButtonDownMasks; //an arrays representing a modifiersEx of extra mouse buttons while using ALT/CTRL/SHIFT or none of them @@ -39,7 +38,6 @@ public class MouseModifiersUnitTest_Extra extends Frame { static int [] modifiersExStandardCTRL; static int [] modifiersExStandardALT; - // final static int [] mouseButtons = new int [] {MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON3_MASK}; // BUTTON1, 2, 3 press-release. final static int modifiersStandard = 0; //InputEvent.BUTTON_DOWN_MASK; @@ -56,7 +54,7 @@ public class MouseModifiersUnitTest_Extra extends Frame { if (modifiersEx != curStandardExModifiers[index]){ // System.out.println(">>>>>>>>>>>>>>> Pressed. modifiersEx "+modifiersEx +" : "+!= curStandardExModifiers"); - MessageLogger.reportError("Test failed : Pressed. modifiersEx != curStandardExModifiers"); + MessageLogger.reportError("Test failed : Pressed. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]); } //check event.paramString() output @@ -168,7 +166,7 @@ public class MouseModifiersUnitTest_Extra extends Frame { } if (modifiersEx != curStandardExModifiers[index]){ - MessageLogger.reportError("Test failed : Released. modifiersEx != curStandardExModifiers"); + MessageLogger.reportError("Test failed : Released. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]); } //check event.paramString() output @@ -191,7 +189,7 @@ public class MouseModifiersUnitTest_Extra extends Frame { } if (modifiersEx != curStandardExModifiers[index]){ - MessageLogger.reportError("Test failed : Clicked. modifiersEx != curStandardExModifiers"); + MessageLogger.reportError("Test failed : Clicked. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]); } //check event.paramString() output @@ -275,11 +273,11 @@ public class MouseModifiersUnitTest_Extra extends Frame { this.addMouseListener(adapterTest1); robot.delay(1000); robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); - for (int i = 3; i< mouseButtons.length; i++){ - System.out.println("testNONE() => " +mouseButtons[i] ); - robot.mousePress(mouseButtons[i]); + for (int i = 3; i< mouseButtonDownMasks.length; i++){ + System.out.println("testNONE() => " +mouseButtonDownMasks[i] ); + robot.mousePress(mouseButtonDownMasks[i]); robot.delay(100); - robot.mouseRelease(mouseButtons[i]); + robot.mouseRelease(mouseButtonDownMasks[i]); } robot.delay(1000); this.removeMouseListener(adapterTest1); @@ -289,12 +287,12 @@ public class MouseModifiersUnitTest_Extra extends Frame { this.addMouseListener(adapterTest2); robot.delay(1000); robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); - for (int i = 3; i< mouseButtons.length; i++){ + for (int i = 3; i< mouseButtonDownMasks.length; i++){ robot.keyPress(KeyEvent.VK_SHIFT); - System.out.println("testSHIFT() => " +mouseButtons[i] ); - robot.mousePress(mouseButtons[i]); + System.out.println("testSHIFT() => " +mouseButtonDownMasks[i] ); + robot.mousePress(mouseButtonDownMasks[i]); robot.delay(100); - robot.mouseRelease(mouseButtons[i]); + robot.mouseRelease(mouseButtonDownMasks[i]); robot.keyRelease(KeyEvent.VK_SHIFT); } robot.delay(1000); @@ -305,12 +303,12 @@ public class MouseModifiersUnitTest_Extra extends Frame { this.addMouseListener(adapterTest3); robot.delay(1000); robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); - for (int i = 3; i< mouseButtons.length; i++){ + for (int i = 3; i< mouseButtonDownMasks.length; i++){ robot.keyPress(KeyEvent.VK_CONTROL); - System.out.println("testCTRL() => " +mouseButtons[i] ); - robot.mousePress(mouseButtons[i]); + System.out.println("testCTRL() => " +mouseButtonDownMasks[i] ); + robot.mousePress(mouseButtonDownMasks[i]); robot.delay(100); - robot.mouseRelease(mouseButtons[i]); + robot.mouseRelease(mouseButtonDownMasks[i]); robot.keyRelease(KeyEvent.VK_CONTROL); } robot.delay(1000); @@ -321,12 +319,12 @@ public class MouseModifiersUnitTest_Extra extends Frame { this.addMouseListener(adapterTest4); robot.delay(1000); robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); - for (int i = 3; i< mouseButtons.length; i++){ + for (int i = 3; i< mouseButtonDownMasks.length; i++){ robot.keyPress(KeyEvent.VK_ALT); - System.out.println("testALT() => " +mouseButtons[i] ); - robot.mousePress(mouseButtons[i]); + System.out.println("testALT() => " +mouseButtonDownMasks[i] ); + robot.mousePress(mouseButtonDownMasks[i]); robot.delay(100); - robot.mouseRelease(mouseButtons[i]); + robot.mouseRelease(mouseButtonDownMasks[i]); robot.keyRelease(KeyEvent.VK_ALT); } robot.delay(1000); @@ -368,52 +366,52 @@ public class MouseModifiersUnitTest_Extra extends Frame { } public static void initAdapters(){ - adapterTest1 = new CheckingModifierAdapter(NONE); - adapterTest2 = new CheckingModifierAdapter(SHIFT); - adapterTest3 = new CheckingModifierAdapter(CTRL); - adapterTest4 = new CheckingModifierAdapter(ALT); + adapterTest1 = new CheckingModifierAdapterExtra(NONE); + adapterTest2 = new CheckingModifierAdapterExtra(SHIFT); + adapterTest3 = new CheckingModifierAdapterExtra(CTRL); + adapterTest4 = new CheckingModifierAdapterExtra(ALT); } public static void initVars(){ - int [] tmp = new int [MouseInfo.getNumberOfButtons()]; - for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){ - tmp[i] = InputEvent.getMaskForButton(i+1); - // System.out.println("TEST: "+tmp[i]); + //Init the array of the mouse button masks. It will be used for generating mouse events. + mouseButtonDownMasks = new int [MouseInfo.getNumberOfButtons()]; + for (int i = 0; i < mouseButtonDownMasks.length; i++){ + mouseButtonDownMasks[i] = InputEvent.getMaskForButton(i+1); + System.out.println("MouseArray [i] == "+mouseButtonDownMasks[i]); } - mouseButtons = Arrays.copyOf(tmp, tmp.length); - - for (int i = 0; i < mouseButtons.length; i++){ - System.out.println("MouseArray [i] == "+mouseButtons[i]); - } - - mouseButtonDownMasks = Arrays.copyOf(tmp, tmp.length); - // So we need to get the number of extra buttons on the mouse: "MouseInfo.getNumberOfButtons() - 3" // and multyply on 3 because each button will generate three events : PRESS, RELEASE and CLICK. - tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3]; - Arrays.fill(tmp, 0); + int [] tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3]; + //Fill array of expected results for the case when mouse buttons are only used (no-modifier keys) + Arrays.fill(tmp, 0); for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ tmp[i] = mouseButtonDownMasks[j]; } modifiersExStandard = Arrays.copyOf(tmp, tmp.length); + //Fill array of expected results for the case when mouse buttons are only used with SHIFT modifier key Arrays.fill(tmp, InputEvent.SHIFT_DOWN_MASK); - for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){ - tmp[i] = tmp[j] | mouseButtonDownMasks[j]; + for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ + System.out.println("modifiersExStandardSHIFT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]); + tmp[i] = tmp[i] | mouseButtonDownMasks[j]; } modifiersExStandardSHIFT = Arrays.copyOf(tmp, tmp.length); + //Fill array of expected results for the case when mouse buttons are only used with CTRL modifier key Arrays.fill(tmp, InputEvent.CTRL_DOWN_MASK); - for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){ - tmp[i] = tmp[j] | mouseButtonDownMasks[j]; + for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ + System.out.println("modifiersExStandardCTRL FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]); + tmp[i] = tmp[i] | mouseButtonDownMasks[j]; } modifiersExStandardCTRL = Arrays.copyOf(tmp, tmp.length); + //Fill array of expected results for the case when mouse buttons are only used with ALT modifier key Arrays.fill(tmp, InputEvent.ALT_DOWN_MASK); - for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){ - tmp[i] = tmp[j] | mouseButtonDownMasks[j]; + for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ + System.out.println("modifiersExStandardALT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]); + tmp[i] = tmp[i] | mouseButtonDownMasks[j]; } modifiersExStandardALT = Arrays.copyOf(tmp, tmp.length); } @@ -436,9 +434,9 @@ public class MouseModifiersUnitTest_Extra extends Frame { /* A class that invoke appropriate verification * routine with current modifier. */ -class CheckingModifierAdapter extends MouseAdapter{ +class CheckingModifierAdapterExtra extends MouseAdapter{ int modifier; - public CheckingModifierAdapter(int modifier){ + public CheckingModifierAdapterExtra(int modifier){ this.modifier = modifier; } diff --git a/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java index fa6a41771aa..e6c19830306 100644 --- a/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java +++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java @@ -90,7 +90,7 @@ public class ToolkitPropertyTest_Enable extends Frame { int [] buttonMasks = new int[MouseInfo.getNumberOfButtons()]; // = InputEvent.getButtonDownMasks(); for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){ buttonMasks[i] = InputEvent.getMaskForButton(i+1); - System.out.println("TEST: "+buttonMasks[i]); + System.out.println("TEST: buttonMasks["+ i +"] = " + buttonMasks[i]); } for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){ diff --git a/jdk/test/java/awt/image/GetSamplesTest.java b/jdk/test/java/awt/image/GetSamplesTest.java new file mode 100644 index 00000000000..86780c5cf9f --- /dev/null +++ b/jdk/test/java/awt/image/GetSamplesTest.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6735275 + * @summary Test verifies that SampleModel.getSamples() throws an appropriate + * exception if coordinates are not in bounds. + * + * @run main GetSamplesTest + */ + +import java.awt.image.BandedSampleModel; +import java.awt.image.ComponentSampleModel; +import java.awt.image.DataBuffer; +import java.awt.image.MultiPixelPackedSampleModel; +import java.awt.image.PixelInterleavedSampleModel; +import java.awt.image.SampleModel; +import java.awt.image.SinglePixelPackedSampleModel; +import java.util.Vector; + +public class GetSamplesTest { + + public static int width = 100; + public static int height = 100; + public static int dataType = DataBuffer.TYPE_BYTE; + public static int numBands = 4; + + public static void main(String[] args) { + Vector> classes = new Vector>(); + + classes.add(ComponentSampleModel.class); + classes.add(MultiPixelPackedSampleModel.class); + classes.add(SinglePixelPackedSampleModel.class); + classes.add(BandedSampleModel.class); + classes.add(PixelInterleavedSampleModel.class); + + for (Class c : classes) { + doTest(c); + } + } + private static void doTest(Class c) { + System.out.println("Test for: " + c.getName()); + SampleModel sm = createSampleModel(c); + + DataBuffer db = sm.createDataBuffer(); + + int[] iArray = new int[ width * height + numBands]; + float[] fArray = new float[ width * height + numBands]; + double[] dArray = new double[ width * height + numBands]; + + boolean iOk = false; + boolean fOk = false; + boolean dOk = false; + + try { + sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, iArray, db); + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println(e.getMessage()); + iOk = true; + } + + try { + sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, fArray, db); + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println(e.getMessage()); + fOk = true; + } + + try { + sm.getSamples(0, Integer.MAX_VALUE, 1, 1, 0, dArray, db); + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println(e.getMessage()); + dOk = true; + } + if (!iOk || !fOk || !dOk) { + throw new RuntimeException("Test for " + c.getSimpleName() + + " failed: iOk=" + iOk + "; fOk=" + fOk + "; dOk=" + dOk); + } + } + + private static SampleModel createSampleModel(Class cls) { + SampleModel res = null; + + if (cls == ComponentSampleModel.class) { + res = new ComponentSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 } ); + } else if (cls == MultiPixelPackedSampleModel.class) { + res = new MultiPixelPackedSampleModel(dataType, width, height, 4); + } else if (cls == SinglePixelPackedSampleModel.class) { + res = new SinglePixelPackedSampleModel(dataType, width, height, + new int[]{ 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff }); + } else if (cls == BandedSampleModel.class) { + res = new BandedSampleModel(dataType, width, height, numBands); + } else if (cls == PixelInterleavedSampleModel.class) { + res = new PixelInterleavedSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 }); + } else { + throw new RuntimeException("Unknown class " + cls); + } + return res; + } +} diff --git a/jdk/test/java/beans/Introspector/6976577/Test6976577.java b/jdk/test/java/beans/Introspector/6976577/Test6976577.java new file mode 100644 index 00000000000..61e1771231f --- /dev/null +++ b/jdk/test/java/beans/Introspector/6976577/Test6976577.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6976577 + * @summary Tests public methods in non-public beans + * @author Sergey Malenkov + */ + +import test.Accessor; + +import java.beans.EventSetDescriptor; +import java.beans.IndexedPropertyDescriptor; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; + +public class Test6976577 { + + public static void main(String[] args) throws Exception { + Class bt = Accessor.getBeanType(); + Class lt = Accessor.getListenerType(); + + // test PropertyDescriptor + PropertyDescriptor pd = new PropertyDescriptor("boolean", bt); + test(pd.getReadMethod()); + test(pd.getWriteMethod()); + + // test IndexedPropertyDescriptor + IndexedPropertyDescriptor ipd = new IndexedPropertyDescriptor("indexed", bt); + test(ipd.getReadMethod()); + test(ipd.getWriteMethod()); + test(ipd.getIndexedReadMethod()); + test(ipd.getIndexedWriteMethod()); + + // test EventSetDescriptor + EventSetDescriptor esd = new EventSetDescriptor(bt, "test", lt, "process"); + test(esd.getAddListenerMethod()); + test(esd.getRemoveListenerMethod()); + test(esd.getGetListenerMethod()); + test(esd.getListenerMethods()); + } + + private static void test(Method... methods) { + for (Method method : methods) { + if (method == null) { + throw new Error("public method is not found"); + } + } + } +} diff --git a/jdk/test/java/beans/Introspector/6976577/test/Accessor.java b/jdk/test/java/beans/Introspector/6976577/test/Accessor.java new file mode 100644 index 00000000000..a7a7090bc11 --- /dev/null +++ b/jdk/test/java/beans/Introspector/6976577/test/Accessor.java @@ -0,0 +1,81 @@ +package test; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.EventListener; +import java.util.TooManyListenersException; + +public class Accessor { + + public static Class getBeanType() { + return Bean.class; + } + + public static Class getListenerType() { + return TestListener.class; + } +} + +interface TestEvent { +} + +interface TestListener extends EventListener { + void process(TestEvent event); +} + +class Bean { + + private boolean b; + private int[] indexed; + private TestListener listener; + private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); + + public void addPropertyChangeListener(PropertyChangeListener listener) { + this.pcs.addPropertyChangeListener(listener); + } + + public void addTestListener(TestListener listener) throws TooManyListenersException { + if (listener != null) { + if (this.listener != null) { + throw new TooManyListenersException(); + } + this.listener = listener; + } + } + + public void removeTestListener(TestListener listener) { + if (this.listener == listener) { + this.listener = null; + } + } + + public TestListener[] getTestListeners() { + return (this.listener != null) + ? new TestListener[] { this.listener } + : new TestListener[0]; + } + + public boolean isBoolean() { + return this.b; + } + + public void setBoolean(boolean b) { + this.b = b; + } + + public int[] getIndexed() { + return this.indexed; + } + + public void setIndexed(int[] values) { + this.indexed = values; + } + + public int getIndexed(int index) { + return this.indexed[index]; + } + + public void setIndexed(int index, int value) { + this.indexed[index] = value; + } +} diff --git a/jdk/test/java/io/File/SetAccess.java b/jdk/test/java/io/File/SetAccess.java index 0b6c1724a5a..355740934b8 100644 --- a/jdk/test/java/io/File/SetAccess.java +++ b/jdk/test/java/io/File/SetAccess.java @@ -22,11 +22,12 @@ */ /* @test - @bug 4167472 5097703 6216563 6284003 + @bug 4167472 5097703 6216563 6284003 6728842 6464744 @summary Basic test for setWritable/Readable/Executable methods */ import java.io.*; +import java.nio.file.attribute.*; public class SetAccess { public static void main(String[] args) throws Exception { @@ -49,8 +50,9 @@ public class SetAccess { } public static void doTest(File f) throws Exception { - f.setReadOnly(); if (!System.getProperty("os.name").startsWith("Windows")) { + if (!f.setReadOnly()) + throw new Exception(f + ": setReadOnly Failed"); if (!f.setWritable(true, true) || !f.canWrite() || permission(f).charAt(2) != 'w') @@ -119,40 +121,44 @@ public class SetAccess { throw new Exception(f + ": setReadable(false, true) Failed"); } else { //Windows platform - if (!f.setWritable(true, true) || !f.canWrite()) - throw new Exception(f + ": setWritable(true, ture) Failed"); - if (!f.setWritable(true, false) || !f.canWrite()) - throw new Exception(f + ": setWritable(true, false) Failed"); - if (!f.setWritable(true) || !f.canWrite()) - throw new Exception(f + ": setWritable(true, ture) Failed"); - if (!f.setExecutable(true, true) || !f.canExecute()) - throw new Exception(f + ": setExecutable(true, true) Failed"); - if (!f.setExecutable(true, false) || !f.canExecute()) - throw new Exception(f + ": setExecutable(true, false) Failed"); - if (!f.setExecutable(true) || !f.canExecute()) - throw new Exception(f + ": setExecutable(true, true) Failed"); - if (!f.setReadable(true, true) || !f.canRead()) - throw new Exception(f + ": setReadable(true, true) Failed"); - if (!f.setReadable(true, false) || !f.canRead()) - throw new Exception(f + ": setReadable(true, false) Failed"); - if (!f.setReadable(true) || !f.canRead()) - throw new Exception(f + ": setReadable(true, true) Failed"); + if (f.isFile()) { + if (!f.setReadOnly()) + throw new Exception(f + ": setReadOnly Failed"); + if (!f.setWritable(true, true) || !f.canWrite()) + throw new Exception(f + ": setWritable(true, ture) Failed"); + if (!f.setWritable(true, false) || !f.canWrite()) + throw new Exception(f + ": setWritable(true, false) Failed"); + if (!f.setWritable(true) || !f.canWrite()) + throw new Exception(f + ": setWritable(true, ture) Failed"); + if (!f.setExecutable(true, true) || !f.canExecute()) + throw new Exception(f + ": setExecutable(true, true) Failed"); + if (!f.setExecutable(true, false) || !f.canExecute()) + throw new Exception(f + ": setExecutable(true, false) Failed"); + if (!f.setExecutable(true) || !f.canExecute()) + throw new Exception(f + ": setExecutable(true, true) Failed"); + if (!f.setReadable(true, true) || !f.canRead()) + throw new Exception(f + ": setReadable(true, true) Failed"); + if (!f.setReadable(true, false) || !f.canRead()) + throw new Exception(f + ": setReadable(true, false) Failed"); + if (!f.setReadable(true) || !f.canRead()) + throw new Exception(f + ": setReadable(true, true) Failed"); + } if (f.isDirectory()) { - //All directories on Windows always have read&write access perm, - //setting a directory to "unwritable" actually means "not deletable" - if (!f.setWritable(false, true) || !f.canWrite()) - throw new Exception(f + ": setWritable(false, true) Failed"); - if (!f.setWritable(false, false) || !f.canWrite()) - throw new Exception(f + ": setWritable(false, true) Failed"); - if (!f.setWritable(false) || !f.canWrite()) - throw new Exception(f + ": setWritable(false, true) Failed"); + // setWritable should fail on directories because the DOS readonly + // attribute prevents a directory from being deleted. + if (f.setWritable(false, true)) + throw new Exception(f + ": setWritable(false, true) Succeeded"); + if (f.setWritable(false, false)) + throw new Exception(f + ": setWritable(false, false) Succeeded"); + if (f.setWritable(false)) + throw new Exception(f + ": setWritable(false) Succeeded"); } else { if (!f.setWritable(false, true) || f.canWrite()) throw new Exception(f + ": setWritable(false, true) Failed"); if (!f.setWritable(false, false) || f.canWrite()) - throw new Exception(f + ": setWritable(false, true) Failed"); + throw new Exception(f + ": setWritable(false, false) Failed"); if (!f.setWritable(false) || f.canWrite()) - throw new Exception(f + ": setWritable(false, true) Failed"); + throw new Exception(f + ": setWritable(false) Failed"); } if (f.setExecutable(false, true)) throw new Exception(f + ": setExecutable(false, true) Failed"); @@ -172,14 +178,8 @@ public class SetAccess { } private static String permission(File f) throws Exception { - byte[] bb = new byte[1024]; - String command = f.isDirectory()?"ls -dl ":"ls -l "; - int len = Runtime.getRuntime() - .exec(command + f.getPath()) - .getInputStream() - .read(bb, 0, 1024); - if (len > 0) - return new String(bb, 0, len).substring(0, 10); - return ""; + PosixFileAttributes attrs = Attributes.readPosixFileAttributes(f.toPath()); + String type = attrs.isDirectory() ? "d" : " "; + return type + PosixFilePermissions.toString(attrs.permissions()); } } diff --git a/jdk/test/java/io/File/SetReadOnly.java b/jdk/test/java/io/File/SetReadOnly.java index 2d348edf7a5..1c1301bf7b5 100644 --- a/jdk/test/java/io/File/SetReadOnly.java +++ b/jdk/test/java/io/File/SetReadOnly.java @@ -22,7 +22,7 @@ */ /* @test - @bug 4091757 4939819 + @bug 4091757 4939819 6728842 @summary Basic test for setReadOnly method */ @@ -57,17 +57,8 @@ public class SetReadOnly { } if (!f.mkdir()) throw new Exception(f + ": Cannot create directory"); - if (!f.setReadOnly()) - throw new Exception(f + ": Failed on directory"); - // The readonly attribute on Windows does not make a folder read-only - if (System.getProperty("os.name").startsWith("Windows")) { - if (!f.canWrite()) - throw new Exception(f + ": Directory is not writeable"); - } else { - if (f.canWrite()) - throw new Exception(f + ": Directory is writeable"); - } - + if (f.setReadOnly() && f.canWrite()) + throw new Exception(f + ": Directory is writeable"); if (!f.delete()) throw new Exception(f + ": Cannot delete directory"); diff --git a/jdk/test/java/io/Serializable/6559775/README b/jdk/test/java/io/Serializable/6559775/README deleted file mode 100644 index c7a4a9ffe25..00000000000 --- a/jdk/test/java/io/Serializable/6559775/README +++ /dev/null @@ -1,29 +0,0 @@ -The testcase works well on dual core machines. -The below output indicates a successful fix: - -Exception in thread "Thread-0" java.lang.NullPointerException - at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:476) - at SerialRace$1.run(SerialRace.java:33) - at java.lang.Thread.run(Thread.java:595) - - -When the vulnerability exists, the output of the tescase is something like this: -Available processors: 2 -Iteration 1 -java.io.NotActiveException: not in readObject invocation or fields already read - at java.io.ObjectInputStream$CallbackContext.checkAndSetUsed(ObjectInputStream.java:3437) - at java.io.ObjectInputStream$CallbackContext.getObj(ObjectInputStream.java:3427) - at java.io.ObjectInputStream.readFields(ObjectInputStream.java:514) - at SerialVictim.readObject(SerialVictim.java:19) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) - at java.lang.reflect.Method.invoke(Method.java:585) - at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:946) - at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1809) - at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719) - at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305) - at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348) - at SerialRace.main(SerialRace.java:65) -Victim: ? -Victim: $ diff --git a/jdk/test/java/io/Serializable/6559775/SerialRace.java b/jdk/test/java/io/Serializable/6559775/SerialRace.java deleted file mode 100644 index 2d4df6a0218..00000000000 --- a/jdk/test/java/io/Serializable/6559775/SerialRace.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * @test %W% %E% - * @bug 6559775 - * @summary Race allows defaultReadObject to be invoked instead of readFields during deserialization - * @run shell Test6559775.sh -*/ - -import java.io.*; - -public class SerialRace { - public static void main(String[] args) throws Exception { - System.err.println( - "Available processors: "+ - Runtime.getRuntime().availableProcessors() - ); - - final int perStream = 10000; - - // Construct attack data. - ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); - { - ObjectOutputStream out = new ObjectOutputStream(byteOut); - char[] value = new char[] { '?' }; - out.writeObject(value); - for (int i=0; i test.out 2>&1 - -cat test.out - -STATUS=0 - -egrep "java.io.NotActiveException|not in readObject invocation or fields already read|^Victim" test.out - -if [ $? = 0 ] -then - STATUS=1 -else - grep "java.lang.NullPointerException" test.out - - if [ $? != 0 ]; then - STATUS=1 - fi -fi - -exit $STATUS diff --git a/jdk/test/java/io/Serializable/6966692/Attack.java b/jdk/test/java/io/Serializable/6966692/Attack.java deleted file mode 100644 index 9a408b20d4e..00000000000 --- a/jdk/test/java/io/Serializable/6966692/Attack.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * @test - * @bug 6966692 - * @summary defaultReadObject can set a field multiple times - * @run shell Test6966692.sh -*/ - -import java.io.*; - -public class Attack { - public static void main(String[] args) throws Exception { - attack(setup()); - } - /** Returned data has Victim with two aaaa fields. */ - private static byte[] setup() throws Exception { - Victim victim = new Victim(); - ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(byteOut); - out.writeObject(victim); - out.close(); - byte[] data = byteOut.toByteArray(); - String str = new String(data, 0); // hibyte is 0 - str = str.replaceAll("bbbb", "aaaa"); - str.getBytes(0, data.length, data, 0); // ignore hibyte - return data; - } - private static void attack(byte[] data) throws Exception { - ObjectInputStream in = new ObjectInputStream( - new ByteArrayInputStream(data) - ); - Victim victim = (Victim)in.readObject(); - System.out.println(victim+" "+victim.aaaa); - } -} diff --git a/jdk/test/java/io/Serializable/6966692/README b/jdk/test/java/io/Serializable/6966692/README deleted file mode 100644 index f4448688391..00000000000 --- a/jdk/test/java/io/Serializable/6966692/README +++ /dev/null @@ -1,23 +0,0 @@ -Testcase shows default deserialisation of the Victim having two values for the same field. - -Probably requires dual core to run successfully. - -Reading thread is warmed up so that it can easily win the race for the demonstration, but this means we need to make the field volatile. - -Typical output: - -Victim@1551f60 BBBB -Victim@1551f60 AAAA - -The output when its fixed is, -Victim@1975b59 AAAA -Victim@1975b59 AAAA - The value is retained - -and when it is not fixed, it shows something like -Victim@173a10f AAAA -Victim@173a10f BBBB - the value of the object gets set again and hence is different. This is a bug - -Look at the -AAAA AAAA -and -AAAA BBBB diff --git a/jdk/test/java/io/Serializable/6966692/Test6966692.sh b/jdk/test/java/io/Serializable/6966692/Test6966692.sh deleted file mode 100644 index 326f24684ed..00000000000 --- a/jdk/test/java/io/Serializable/6966692/Test6966692.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh - -if [ "${TESTSRC}" = "" ] -then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] -then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - echo "TESTJAVA not set, selecting " ${TESTJAVA} - echo "If this is incorrect, try setting the variable manually." -fi - -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - -BIT_FLAG="" - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - SunOS | Linux ) - NULL=/dev/null - PS=":" - FS="/" - ## for solaris, linux it's HOME - FILE_LOCATION=$HOME - if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" ] - then - BIT_FLAG=`cat ${FILE_LOCATION}${FS}JDK64BIT | grep -v '^#'` - fi - ;; - Windows_* ) - NULL=NUL - PS=";" - FS="\\" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -JEMMYPATH=${CPAPPEND} -CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH - -THIS_DIR=`pwd` - -${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -version - -cp ${TESTSRC}${FS}*.java . -chmod 777 *.java - -${TESTJAVA}${FS}bin${FS}javac *.java - -${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} Attack > test.out 2>&1 - -cat test.out - -STATUS=0 - -egrep "^Victim.*BBBB.*AAAA|^Victim.*AAAA.*BBBB" test.out - -if [ $? = 0 ] -then - STATUS=1 -else - egrep "^Victim.*BBBB.*BBBB|^Victim.*AAAA.*AAAA" test.out - - if [ $? != 0 ]; then - STATUS=1 - fi -fi - -exit $STATUS diff --git a/jdk/test/java/io/Serializable/6966692/Victim.java b/jdk/test/java/io/Serializable/6966692/Victim.java deleted file mode 100644 index f26276e3a66..00000000000 --- a/jdk/test/java/io/Serializable/6966692/Victim.java +++ /dev/null @@ -1,35 +0,0 @@ -import java.io.*; - -public class Victim implements Serializable { - public volatile Object aaaa = "AAAA"; // must be volatile... - private final Object aabb = new Show(this); - public Object bbbb = "BBBB"; -} -class Show implements Serializable { - private final Victim victim; - public Show(Victim victim) { - this.victim = victim; - } - private void readObject(java.io.ObjectInputStream in) - throws IOException, ClassNotFoundException - { - in.defaultReadObject(); - Thread thread = new Thread(new Runnable() { public void run() { - for (;;) { - Object a = victim.aaaa; - if (a != null) { - System.err.println(victim+" "+a); - break; - } - } - }}); - thread.start(); - - // Make sure we are running compiled whilst serialisation is done interpreted. - try { - Thread.sleep(1000); - } catch (java.lang.InterruptedException exc) { - Thread.currentThread().interrupt(); - } - } -} diff --git a/jdk/test/java/io/pathNames/GeneralWin32.java b/jdk/test/java/io/pathNames/GeneralWin32.java index a43a8cd42f1..90802eee49f 100644 --- a/jdk/test/java/io/pathNames/GeneralWin32.java +++ b/jdk/test/java/io/pathNames/GeneralWin32.java @@ -22,7 +22,7 @@ */ /* @test - @bug 4032066 4039597 4046914 4054511 4065189 4109131 4875229 + @bug 4032066 4039597 4046914 4054511 4065189 4109131 4875229 6983520 @summary General exhaustive test of win32 pathname handling @author Mark Reinhold diff --git a/jdk/test/java/lang/ClassLoader/deadlock/GetResource.java b/jdk/test/java/lang/ClassLoader/deadlock/GetResource.java new file mode 100644 index 00000000000..a1a1b4e1730 --- /dev/null +++ b/jdk/test/java/lang/ClassLoader/deadlock/GetResource.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.Properties; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.BrokenBarrierException; +import java.io.IOException; +import java.net.URL; + +/* @test + * @bug 6977738 + * @summary Test ClassLoader.getResource() that should not deadlock + # if another thread is holding the system properties object + * + * @build GetResource + * @run main GetResource + */ + +public class GetResource { + CyclicBarrier go = new CyclicBarrier(2); + CyclicBarrier done = new CyclicBarrier(2); + Thread t1, t2; + public GetResource() { + t1 = new Thread() { + public void run() { + Properties prop = System.getProperties(); + synchronized (prop) { + System.out.println("Thread 1 ready"); + try { + go.await(); + prop.put("property", "value"); + prop.store(System.out, ""); + done.await(); // keep holding the lock until t2 finishes + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (BrokenBarrierException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + System.out.println("Thread 1 exits"); + } + }; + + t2 = new Thread() { + public void run() { + System.out.println("Thread 2 ready"); + try { + go.await(); // wait until t1 holds the lock of the system properties + + URL u1 = Thread.currentThread().getContextClassLoader().getResource("unknownresource"); + URL u2 = Thread.currentThread().getContextClassLoader().getResource("sun/util/resources/CalendarData.class"); + if (u2 == null) { + throw new RuntimeException("Test failed: resource not found"); + } + done.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (BrokenBarrierException e) { + throw new RuntimeException(e); + } + System.out.println("Thread 2 exits"); + } + }; + } + + public void run() throws Exception { + t1.start(); + t2.start(); + try { + t1.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw e; + } + try { + t2.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw e; + } + } + + public static void main(String[] args) throws Exception { + new GetResource().run(); + } +} diff --git a/jdk/test/java/lang/StringBuilder/EnsureCapacity.java b/jdk/test/java/lang/StringBuilder/EnsureCapacity.java new file mode 100644 index 00000000000..f1ef16ee8d3 --- /dev/null +++ b/jdk/test/java/lang/StringBuilder/EnsureCapacity.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 6955504 6992121 + * @summary Test the StringBuilder.ensureCapacity() with negative minimumCapacity + * and append() method with negative length input argument. + * Also, test the StringBuffer class. + */ + +import java.util.ArrayList; +import java.util.Vector; + +public class EnsureCapacity { + public static void main(String[] args) { + testStringBuilder(); + testStringBuffer(); + } + + private static void checkCapacity(int before, int after) { + if (before != after) { + throw new RuntimeException("capacity is expected to be unchanged: " + + "before=" + before + " after=" + after); + } + } + + private static void testStringBuilder() { + StringBuilder sb = new StringBuilder("abc"); + int cap = sb.capacity(); + + // test if negative minimumCapacity + sb.ensureCapacity(Integer.MIN_VALUE); + checkCapacity(cap, sb.capacity()); + + try { + char[] str = {'a', 'b', 'c', 'd'}; + // test if negative length + sb.append(str, 0, Integer.MIN_VALUE + 10); + throw new RuntimeException("IndexOutOfBoundsException not thrown"); + } catch (IndexOutOfBoundsException ex) { + } + } + + private static void testStringBuffer() { + StringBuffer sb = new StringBuffer("abc"); + int cap = sb.capacity(); + + // test if negative minimumCapacity + sb.ensureCapacity(Integer.MIN_VALUE); + checkCapacity(cap, sb.capacity()); + + try { + char[] str = {'a', 'b', 'c', 'd'}; + // test if negative length + sb.append(str, 0, Integer.MIN_VALUE + 10); + throw new RuntimeException("IndexOutOfBoundsException not thrown"); + } catch (IndexOutOfBoundsException ex) { + } + } +} diff --git a/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java b/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java index b7a04e0307d..22e1dc16572 100644 --- a/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java +++ b/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4959889 + * @bug 4959889 6992968 * @summary Basic unit test of memory management testing: * 1) setCollectionUsageThreshold() and getCollectionUsageThreshold() * 2) test notification emitted for two different memory pools. @@ -34,8 +34,10 @@ * @run main/timeout=300 CollectionUsageThreshold */ +import java.lang.Thread.*; import java.lang.management.*; import java.util.*; +import java.util.concurrent.*; import javax.management.*; import javax.management.openmbean.CompositeData; @@ -52,6 +54,12 @@ public class CollectionUsageThreshold { private static Checker checker; private static int numGCs = 0; + // semaphore to signal the arrival of a low memory notification + private static Semaphore signals = new Semaphore(0); + // barrier for the main thread to wait until the checker thread + // finishes checking the low memory notification result + private static CyclicBarrier barrier = new CyclicBarrier(2); + static class PoolRecord { private MemoryPoolMXBean pool; private int listenerInvoked = 0; @@ -98,10 +106,9 @@ public class CollectionUsageThreshold { } pr.addNotification(minfo); synchronized (this) { + System.out.println("notifying the checker thread to check result"); numNotifs++; - if (numNotifs > 0 && (numNotifs % EXPECTED_NUM_POOLS) == 0) { - checker.goCheckResult(); - } + signals.release(); } } } @@ -134,6 +141,9 @@ public class CollectionUsageThreshold { } try { + // This test creates a checker thread responsible for checking + // the low memory notifications. It blocks until a permit + // from the signals semaphore is available. checker = new Checker("Checker thread"); checker.setDaemon(true); checker.start(); @@ -148,9 +158,18 @@ public class CollectionUsageThreshold { NotificationEmitter emitter = (NotificationEmitter) mm; emitter.addNotificationListener(listener, null, null); + // The main thread invokes GC to trigger the VM to perform + // low memory detection and then waits until the checker thread + // finishes its work to check for a low-memory notification. + // + // At GC time, VM will issue low-memory notification and invoke + // the listener which will release a permit to the signals semaphore. + // When the checker thread acquires the permit and finishes + // checking the low-memory notification, it will also call + // barrier.await() to signal the main thread to resume its work. for (int i = 0; i < NUM_GCS; i++) { invokeGC(); - checker.waitForCheckResult(); + barrier.await(); } } finally { // restore the default @@ -166,6 +185,7 @@ public class CollectionUsageThreshold { } + private static void invokeGC() { System.out.println("Calling System.gc()"); numGCs++; @@ -180,8 +200,6 @@ public class CollectionUsageThreshold { } static class Checker extends Thread { - private Object lock = new Object(); - private Object go = new Object(); private boolean checkerReady = false; private int waiters = 0; private boolean readyToCheck = false; @@ -190,83 +208,48 @@ public class CollectionUsageThreshold { }; public void run() { while (true) { - synchronized (lock) { - checkerReady = true; - try { - lock.wait(); - } catch (InterruptedException e) { - // ignore - } + try { + signals.acquire(EXPECTED_NUM_POOLS); checkResult(); - checkerReady = false; + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (BrokenBarrierException e) { + throw new RuntimeException(e); } } } - private void checkResult() { + private void checkResult() throws InterruptedException, BrokenBarrierException { for (PoolRecord pr : result.values()) { if (pr.getListenerInvokedCount() != numGCs) { - throw new RuntimeException("Listeners invoked count = " + + fail("Listeners invoked count = " + pr.getListenerInvokedCount() + " expected to be " + numGCs); } if (pr.getNotifCount() != numGCs) { - throw new RuntimeException("Notif Count = " + + fail("Notif Count = " + pr.getNotifCount() + " expected to be " + numGCs); } long count = pr.getPool().getCollectionUsageThresholdCount(); if (count != numGCs) { - throw new RuntimeException("CollectionUsageThresholdCount = " + + fail("CollectionUsageThresholdCount = " + count + " expected to be " + numGCs); } if (!pr.getPool().isCollectionUsageThresholdExceeded()) { - throw new RuntimeException("isCollectionUsageThresholdExceeded" + + fail("isCollectionUsageThresholdExceeded" + " expected to be true"); } } - synchronized (go) { - // wait until the main thread is waiting for notification - while (waiters == 0) { - try { - go.wait(50); - } catch (InterruptedException e) { - // ignore - } - } - - System.out.println(Thread.currentThread().getName() + - " notifying main thread to continue - result checking finished"); - go.notify(); - } - } - public void goCheckResult() { - System.out.println(Thread.currentThread().getName() + - " notifying to check result"); - synchronized (lock) { - while (!checkerReady) { - try { - lock.wait(50); - } catch (InterruptedException e) { - // ignore - } - } - lock.notify(); - } + // wait until the main thread is waiting for notification + barrier.await(); + System.out.println("notifying main thread to continue - result checking finished"); } - public void waitForCheckResult() { - System.out.println(Thread.currentThread().getName() + - " waiting for result checking finishes"); - synchronized (go) { - waiters++; - try { - go.wait(); - } catch (InterruptedException e) { - // ignore - } - waiters--; - } + private void fail(String msg) { + // reset the barrier to cause BrokenBarrierException to avoid hanging + barrier.reset(); + throw new RuntimeException(msg); } } } diff --git a/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThresholdConcMarkSweepGC.sh b/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThresholdConcMarkSweepGC.sh index 3dac6c5d5af..6e005a0257f 100644 --- a/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThresholdConcMarkSweepGC.sh +++ b/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThresholdConcMarkSweepGC.sh @@ -27,6 +27,7 @@ # @summary Test CollectionUsageThreshold with concurrent marksweep collector # @author Mandy Chung # +# @ignore 6982965 # @run build CollectionUsageThreshold # @run shell/timeout=300 CollectionUsageThresholdConcMarkSweepGC.sh # diff --git a/jdk/test/java/nio/Buffer/LimitDirectMemory.java b/jdk/test/java/nio/Buffer/LimitDirectMemory.java new file mode 100644 index 00000000000..597e4d9c093 --- /dev/null +++ b/jdk/test/java/nio/Buffer/LimitDirectMemory.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2002, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.ByteBuffer; +import java.util.Properties; + +public class LimitDirectMemory { + private static int K = 1024; + + public static void main(String [] args) throws Exception { + if (args.length < 2) + throw new RuntimeException(); + boolean throwp = parseThrow(args[0]); + int size = parseSize(args[1]); + int incr = (args.length > 2 ? parseSize(args[2]) : size); + + Properties p = System.getProperties(); + if (p.getProperty("sun.nio.MaxDirectMemorySize") != null) + throw new RuntimeException("sun.nio.MaxDirectMemorySize defined"); + + ByteBuffer [] b = new ByteBuffer[K]; + + // Fill up most/all of the direct memory + int i = 0; + while (size >= incr) { + b[i++] = ByteBuffer.allocateDirect(incr); + size -= incr; + } + + if (throwp) { + try { + b[i] = ByteBuffer.allocateDirect(incr); + throw new RuntimeException("OutOfMemoryError not thrown: " + + incr); + } catch (OutOfMemoryError e) { + e.printStackTrace(System.out); + System.out.println("OK - Error thrown as expected "); + } + } else { + b[i] = ByteBuffer.allocateDirect(incr); + System.out.println("OK - Error not thrown"); + } + } + + private static boolean parseThrow(String s) { + if (s.equals("true")) return true; + if (s.equals("false")) return false; + throw new RuntimeException("Unrecognized expectation: " + s); + } + + private static int parseSize(String size) throws Exception { + + if (size.equals("DEFAULT")) + return (int)Runtime.getRuntime().maxMemory(); + if (size.equals("DEFAULT+1")) + return (int)Runtime.getRuntime().maxMemory() + 1; + if (size.equals("DEFAULT+1M")) + return (int)Runtime.getRuntime().maxMemory() + (1 << 20); + if (size.equals("DEFAULT-1")) + return (int)Runtime.getRuntime().maxMemory() - 1; + if (size.equals("DEFAULT/2")) + return (int)Runtime.getRuntime().maxMemory() / 2; + + int idx = 0, len = size.length(); + + int result = 1; + for (int i = 0; i < len; i++) { + if (Character.isDigit(size.charAt(i))) idx++; + else break; + } + + if (idx == 0) + throw new RuntimeException("No digits detected: " + size); + + result = Integer.parseInt(size.substring(0, idx)); + + if (idx < len) { + for (int i = idx; i < len; i++) { + switch(size.charAt(i)) { + case 'T': case 't': result *= K; // fall through + case 'G': case 'g': result *= K; // fall through + case 'M': case 'm': result *= K; // fall through + case 'K': case 'k': result *= K; + break; + default: + throw new RuntimeException("Unrecognized size: " + size); + } + } + } + return result; + } +} diff --git a/jdk/test/java/nio/Buffer/LimitDirectMemory.sh b/jdk/test/java/nio/Buffer/LimitDirectMemory.sh new file mode 100644 index 00000000000..38e8c0c05fa --- /dev/null +++ b/jdk/test/java/nio/Buffer/LimitDirectMemory.sh @@ -0,0 +1,91 @@ +#!/bin/sh + +# +# Copyright (c) 2002, 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. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# @test +# @bug 4627316 6743526 +# @summary Test option to limit direct memory allocation +# +# @build LimitDirectMemory +# @run shell LimitDirectMemory.sh + +TMP1=tmp_$$ + +runTest() { + echo "Testing: $*" + ${TESTJAVA}/bin/java $* + if [ $? -eq 0 ] + then echo "--- passed as expected" + else + echo "--- failed" + exit 1 + fi +} + +launchFail() { + echo "Testing: -XX:MaxDirectMemorySize=$* -cp ${TESTCLASSES} \ + LimitDirectMemory true DEFAULT DEFAULT+1M" + ${TESTJAVA}/bin/java -XX:MaxDirectMemorySize=$* -cp ${TESTCLASSES} \ + LimitDirectMemory true DEFAULT DEFAULT+1M > ${TMP1} 2>&1 + cat ${TMP1} + cat ${TMP1} | grep -s "Unrecognized VM option: \'MaxDirectMemorySize=" + if [ $? -ne 0 ] + then echo "--- failed as expected" + else + echo "--- failed" + exit 1 + fi +} + +# $java LimitDirectMemory throwp fill_direct_memory size_per_buffer + +# Memory is properly limited using multiple buffers. +runTest -XX:MaxDirectMemorySize=10 -cp ${TESTCLASSES} LimitDirectMemory true 10 1 +runTest -XX:MaxDirectMemorySize=1k -cp ${TESTCLASSES} LimitDirectMemory true 1k 100 +runTest -XX:MaxDirectMemorySize=10m -cp ${TESTCLASSES} LimitDirectMemory true 10m 10m + +# We can increase the amount of available memory. +runTest -XX:MaxDirectMemorySize=65M -cp ${TESTCLASSES} \ + LimitDirectMemory false 64M 65M + +# Exactly the default amount of memory is available. +runTest -cp ${TESTCLASSES} LimitDirectMemory false 10 1 +runTest -Xmx64m -cp ${TESTCLASSES} LimitDirectMemory false 0 DEFAULT +runTest -Xmx64m -cp ${TESTCLASSES} LimitDirectMemory true 0 DEFAULT+1 + +# We should be able to eliminate direct memory allocation entirely. +runTest -XX:MaxDirectMemorySize=0 -cp ${TESTCLASSES} LimitDirectMemory true 0 1 + +# Setting the system property should not work so we should be able to allocate +# the default amount. +runTest -Dsun.nio.MaxDirectMemorySize=1K -Xmx64m -cp ${TESTCLASSES} \ + LimitDirectMemory false DEFAULT-1 DEFAULT/2 + +# Various bad values fail to launch the VM. +launchFail foo +launchFail 10kmt +launchFail -1 + +# Clean-up +rm ${TMP1} diff --git a/jdk/test/java/nio/MappedByteBuffer/Basic.java b/jdk/test/java/nio/MappedByteBuffer/Basic.java index 3b068b76983..07ecbf227ab 100644 --- a/jdk/test/java/nio/MappedByteBuffer/Basic.java +++ b/jdk/test/java/nio/MappedByteBuffer/Basic.java @@ -24,7 +24,6 @@ /* @test * @bug 4462336 6799037 * @summary Simple MappedByteBuffer tests - * @run main/othervm Basic */ import java.io.*; @@ -76,5 +75,10 @@ public class Basic { throw new RuntimeException("Incorrect isReadOnly"); fc.close(); raf.close(); + + // clean-up + mbb = null; + System.gc(); + Thread.sleep(500); } } diff --git a/jdk/test/java/nio/channels/Selector/TemporarySelector.java b/jdk/test/java/nio/channels/Selector/TemporarySelector.java new file mode 100644 index 00000000000..c131c327fa7 --- /dev/null +++ b/jdk/test/java/nio/channels/Selector/TemporarySelector.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 6645197 + * @run main/othervm -Xmx5m TemporarySelector + * @summary Timed read with socket adaptor throws ClosedSelectorException if temporary selector GC'ed. + */ +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; + +public class TemporarySelector { + + static volatile boolean done = false; + + public static void main(String[] args) throws Exception { + + Runnable r = new Runnable() { + public void run() { + while (!done) { + System.gc(); + try { + Thread.sleep(1000); + } catch (Exception e) { + } + } + } + }; + + try { + // Create a server socket that will open and accept on loopback connection + ServerSocketChannel ssc = ServerSocketChannel.open(); + final ServerSocket ss = ssc.socket(); + ss.bind(new InetSocketAddress(0)); + int localPort = ss.getLocalPort(); + + // Create a client socket that will connect and read + System.out.println("Connecting to server socket"); + System.out.flush(); + SocketChannel channel = SocketChannel.open(new InetSocketAddress("localhost", localPort)); + System.out.println("Connected to server socket"); + System.out.flush(); + + // Create a thread to try and cause the GC to run + Thread t = new Thread(r); + t.start(); + byte[] buffer = new byte[500]; + System.out.println("Reading from socket input stream"); + System.out.flush(); + Socket socket = channel.socket(); + socket.setSoTimeout(10000); // The timeout must be set + // to trigger this bug + try { + socket.getInputStream().read(buffer); + } catch (java.net.SocketTimeoutException ste) { + // no java.nio.channels.ClosedSelectorException + } + } finally { + done = true; + } + } +} diff --git a/jdk/test/java/nio/file/Path/InterruptCopy.java b/jdk/test/java/nio/file/Path/InterruptCopy.java index c03ebb312d8..7be5578985c 100644 --- a/jdk/test/java/nio/file/Path/InterruptCopy.java +++ b/jdk/test/java/nio/file/Path/InterruptCopy.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313887 + * @bug 4313887 6993267 * @summary Unit test for Sun-specific ExtendedCopyOption.INTERRUPTIBLE option * @library .. * @run main/othervm -XX:-UseVMInterruptibleIO InterruptCopy @@ -36,8 +36,9 @@ import com.sun.nio.file.ExtendedCopyOption; public class InterruptCopy { - private static final long FILE_SIZE_TO_COPY = 512 * 1024 * 1024; + private static final long FILE_SIZE_TO_COPY = 512L * 1024L * 1024L; private static final int DELAY_IN_MS = 500; + private static final int DURATION_MAX_IN_MS = 5000; public static void main(String[] args) throws Exception { Path dir = TestUtil.createTemporaryDirectory(); @@ -81,20 +82,27 @@ public class InterruptCopy { try { // copy source to target in main thread, interrupting it after a delay final Thread me = Thread.currentThread(); - pool.schedule(new Runnable() { + Future wakeup = pool.schedule(new Runnable() { public void run() { me.interrupt(); }}, DELAY_IN_MS, TimeUnit.MILLISECONDS); System.out.println("Copying file..."); try { + long start = System.currentTimeMillis(); source.copyTo(target, ExtendedCopyOption.INTERRUPTIBLE); - throw new RuntimeException("Copy completed (this is not expected)"); + long duration = System.currentTimeMillis() - start; + if (duration > DURATION_MAX_IN_MS) + throw new RuntimeException("Copy was not interrupted"); } catch (IOException e) { boolean interrupted = Thread.interrupted(); if (!interrupted) throw new RuntimeException("Interrupt status was not set"); System.out.println("Copy failed (this is expected)"); } + try { + wakeup.get(); + } catch (InterruptedException ignore) { } + Thread.interrupted(); // copy source to target via task in thread pool, interrupting it after // a delay using cancel(true) @@ -113,7 +121,6 @@ public class InterruptCopy { System.out.println("Copy cancelled."); } finally { pool.shutdown(); - pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS); } } } diff --git a/jdk/test/java/util/ArrayList/EnsureCapacity.java b/jdk/test/java/util/ArrayList/EnsureCapacity.java new file mode 100644 index 00000000000..a8e5f42ac6b --- /dev/null +++ b/jdk/test/java/util/ArrayList/EnsureCapacity.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 6992121 + * @summary Test the ArrayList.ensureCapacity() and Vector.ensureCapacity + * method with negative minimumCapacity input argument. + */ + +import java.util.ArrayList; +import java.util.Vector; + +public class EnsureCapacity { + public static void main(String[] args) { + testArrayList(); + testVector(); + } + + private static void checkCapacity(int before, int after) { + if (before != after) { + throw new RuntimeException("capacity is expected to be unchanged: " + + "before=" + before + " after=" + after); + } + } + + private static void testArrayList() { + ArrayList al = new ArrayList(); + al.add("abc"); + al.ensureCapacity(Integer.MIN_VALUE); + + // there is no method to query the capacity of ArrayList + // so before and after capacity are not checked + } + + private static void testVector() { + Vector vector = new Vector(); + vector.add("abc"); + + int cap = vector.capacity(); + vector.ensureCapacity(Integer.MIN_VALUE); + checkCapacity(cap, vector.capacity()); + } +} diff --git a/jdk/test/java/util/Arrays/Sorting.java b/jdk/test/java/util/Arrays/Sorting.java index cee7f53301f..a2c4ed98e04 100644 --- a/jdk/test/java/util/Arrays/Sorting.java +++ b/jdk/test/java/util/Arrays/Sorting.java @@ -23,7 +23,7 @@ /* * @test - * @bug 6880672 6896573 6899694 + * @bug 6880672 6896573 6899694 6976036 * @summary Exercise Arrays.sort * @build Sorting * @run main Sorting -shortrun @@ -50,10 +50,10 @@ public class Sorting { 1, 2, 3, 21, 55, 1000, 10000 }; // Random initial values used in a long run (default) - private static final long[] LONG_RUN_RANDOMS = {666, 0xC0FFEE, 999}; + private static final long[] LONG_RUN_RANDOMS = { 666, 0xC0FFEE, 999 }; // Random initial values used in a short run - private static final long[] SHORT_RUN_RANDOMS = {666}; + private static final long[] SHORT_RUN_RANDOMS = { 666 }; public static void main(String[] args) { boolean shortRun = args.length > 0 && args[0].equals("-shortrun"); @@ -81,6 +81,11 @@ public class Sorting { for (long random : randoms) { reset(random); + for (int length : lengths) { + testAndCheckWithInsertionSort(length, random); + } + reset(random); + for (int length : lengths) { testAndCheckWithCheckSum(length, random); } @@ -268,9 +273,7 @@ public class Sorting { " length = " + length + ", m = " + m); Object convertedGolden = converter.convert(golden); Object convertedTest = converter.convert(test); - // outArray(test); sortSubArray(convertedTest, fromIndex, toIndex); - // outArray(test); checkSubArray(convertedTest, fromIndex, toIndex, m); } } @@ -311,7 +314,7 @@ public class Sorting { private static void checkSorted(Pair[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i].getKey() > a[i + 1].getKey()) { - failed(i, "" + a[i].getKey(), "" + a[i + 1].getKey()); + failedSort(i, "" + a[i].getKey(), "" + a[i + 1].getKey()); } } } @@ -328,7 +331,7 @@ public class Sorting { int value4 = a[i++].getValue(); if (!(key1 == key2 && key2 == key3 && key3 == key4)) { - failed("On position " + i + " must keys are different " + + failed("On position " + i + " keys are different " + key1 + ", " + key2 + ", " + key3 + ", " + key4); } if (!(value1 < value2 && value2 < value3 && value3 < value4)) { @@ -385,6 +388,35 @@ public class Sorting { private int myValue; } + + private static void testAndCheckWithInsertionSort(int length, long random) { + if (length > 1000) { + return; + } + ourDescription = "Check sorting with insertion sort"; + int[] golden = new int[length]; + + for (int m = 1; m < 2 * length; m *= 2) { + for (UnsortedBuilder builder : UnsortedBuilder.values()) { + builder.build(golden, m); + int[] test = golden.clone(); + + for (TypeConverter converter : TypeConverter.values()) { + out.println("Test 'insertion sort': " + converter + " " + + builder + "random = " + random + ", length = " + + length + ", m = " + m); + Object convertedGolden = converter.convert(golden); + Object convertedTest1 = converter.convert(test); + Object convertedTest2 = converter.convert(test); + sort(convertedTest1); + sortByInsertionSort(convertedTest2); + compare(convertedTest1, convertedTest2); + } + } + } + out.println(); + } + private static void testAndCheckWithCheckSum(int length, long random) { ourDescription = "Check sorting with check sum"; int[] golden = new int[length]; @@ -460,9 +492,7 @@ public class Sorting { builder.build(golden, a, g, z, n, p); float[] test = golden.clone(); scramble(test); - // outArray(test); sort(test); - // outArray(test); compare(test, golden, a, n, g); } newLine = true; @@ -500,9 +530,7 @@ public class Sorting { builder.build(golden, a, g, z, n, p); double[] test = golden.clone(); scramble(test); - // outArray(test); sort(test); - // outArray(test); compare(test, golden, a, n, g); } newLine = true; @@ -721,12 +749,12 @@ public class Sorting { for (int i = numNeg; i < numNeg + numNegZero; i++) { if (NEGATIVE_ZERO != Float.floatToIntBits(a[i])) { - failed("On position " + i + " must be -0.0f instead of " + a[i]); + failed("On position " + i + " must be -0.0 instead of " + a[i]); } } for (int i = 0; i < a.length - numNaN; i++) { if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); + failedCompare(i, "" + a[i], "" + b[i]); } } } @@ -747,12 +775,12 @@ public class Sorting { for (int i = numNeg; i < numNeg + numNegZero; i++) { if (NEGATIVE_ZERO != Double.doubleToLongBits(a[i])) { - failed("On position " + i + " must be -0.0d instead of " + a[i]); + failed("On position " + i + " must be -0.0 instead of " + a[i]); } } for (int i = 0; i < a.length - numNaN; i++) { if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); + failedCompare(i, "" + a[i], "" + b[i]); } } } @@ -841,8 +869,8 @@ public class Sorting { int incCount = 1; int decCount = a.length; int i = 0; - int period = m; - m--; + int period = m--; + while (true) { for (int k = 1; k <= period; k++) { if (i >= a.length) { @@ -922,6 +950,25 @@ public class Sorting { } } + private static void checkWithCheckSum(Object test, Object golden) { + checkSorted(test); + checkCheckSum(test, golden); + } + + private static void failed(String message) { + err.format("\n*** TEST FAILED - %s.\n\n%s.\n\n", ourDescription, message); + throw new RuntimeException("Test failed - see log file for details"); + } + + private static void failedSort(int index, String value1, String value2) { + failed("Array is not sorted at " + index + "-th position: " + + value1 + " and " + value2); + } + + private static void failedCompare(int index, String value1, String value2) { + failed("On position " + index + " must be " + value2 + " instead of " + value1); + } + private static void compare(Object test, Object golden) { if (test instanceof int[]) { compare((int[]) test, (int[]) golden); @@ -945,19 +992,68 @@ public class Sorting { } } - private static void checkWithCheckSum(Object test, Object golden) { - checkSorted(test); - checkCheckSum(test, golden); + private static void compare(int[] a, int[] b) { + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + failedCompare(i, "" + a[i], "" + b[i]); + } + } } - private static void failed(String message) { - err.format("\n*** TEST FAILED - %s\n\n%s\n\n", ourDescription, message); - throw new RuntimeException("Test failed - see log file for details"); + private static void compare(long[] a, long[] b) { + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + failedCompare(i, "" + a[i], "" + b[i]); + } + } } - private static void failed(int index, String value1, String value2) { - failed("Array is not sorted at " + index + "-th position: " + - value1 + " and " + value2); + private static void compare(short[] a, short[] b) { + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + failedCompare(i, "" + a[i], "" + b[i]); + } + } + } + + private static void compare(byte[] a, byte[] b) { + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + failedCompare(i, "" + a[i], "" + b[i]); + } + } + } + + private static void compare(char[] a, char[] b) { + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + failedCompare(i, "" + a[i], "" + b[i]); + } + } + } + + private static void compare(float[] a, float[] b) { + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + failedCompare(i, "" + a[i], "" + b[i]); + } + } + } + + private static void compare(double[] a, double[] b) { + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + failedCompare(i, "" + a[i], "" + b[i]); + } + } + } + + private static void compare(Integer[] a, Integer[] b) { + for (int i = 0; i < a.length; i++) { + if (a[i].compareTo(b[i]) != 0) { + failedCompare(i, "" + a[i], "" + b[i]); + } + } } private static void checkSorted(Object object) { @@ -983,82 +1079,10 @@ public class Sorting { } } - private static void compare(Integer[] a, Integer[] b) { - for (int i = 0; i < a.length; i++) { - if (a[i].intValue() != b[i].intValue()) { - failed(i, "" + a[i], "" + b[i]); - } - } - } - - private static void compare(int[] a, int[] b) { - for (int i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); - } - } - } - - private static void compare(long[] a, long[] b) { - for (int i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); - } - } - } - - private static void compare(short[] a, short[] b) { - for (int i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); - } - } - } - - private static void compare(byte[] a, byte[] b) { - for (int i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); - } - } - } - - private static void compare(char[] a, char[] b) { - for (int i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); - } - } - } - - private static void compare(float[] a, float[] b) { - for (int i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); - } - } - } - - private static void compare(double[] a, double[] b) { - for (int i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); - } - } - } - - private static void checkSorted(Integer[] a) { - for (int i = 0; i < a.length - 1; i++) { - if (a[i].intValue() > a[i + 1].intValue()) { - failed(i, "" + a[i], "" + a[i + 1]); - } - } - } - private static void checkSorted(int[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } } @@ -1066,7 +1090,7 @@ public class Sorting { private static void checkSorted(long[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } } @@ -1074,7 +1098,7 @@ public class Sorting { private static void checkSorted(short[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } } @@ -1082,7 +1106,7 @@ public class Sorting { private static void checkSorted(byte[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } } @@ -1090,7 +1114,7 @@ public class Sorting { private static void checkSorted(char[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } } @@ -1098,7 +1122,7 @@ public class Sorting { private static void checkSorted(float[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } } @@ -1106,34 +1130,45 @@ public class Sorting { private static void checkSorted(double[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); + } + } + } + + private static void checkSorted(Integer[] a) { + for (int i = 0; i < a.length - 1; i++) { + if (a[i].intValue() > a[i + 1].intValue()) { + failedSort(i, "" + a[i], "" + a[i + 1]); } } } private static void checkCheckSum(Object test, Object golden) { - if (checkSum(test) != checkSum(golden)) { - failed("It seems that original and sorted arrays are not identical"); + if (checkSumXor(test) != checkSumXor(golden)) { + failed("Original and sorted arrays are not identical [xor]"); + } + if (checkSumPlus(test) != checkSumPlus(golden)) { + failed("Original and sorted arrays are not identical [plus]"); } } - private static int checkSum(Object object) { + private static int checkSumXor(Object object) { if (object instanceof int[]) { - return checkSum((int[]) object); + return checkSumXor((int[]) object); } else if (object instanceof long[]) { - return checkSum((long[]) object); + return checkSumXor((long[]) object); } else if (object instanceof short[]) { - return checkSum((short[]) object); + return checkSumXor((short[]) object); } else if (object instanceof byte[]) { - return checkSum((byte[]) object); + return checkSumXor((byte[]) object); } else if (object instanceof char[]) { - return checkSum((char[]) object); + return checkSumXor((char[]) object); } else if (object instanceof float[]) { - return checkSum((float[]) object); + return checkSumXor((float[]) object); } else if (object instanceof double[]) { - return checkSum((double[]) object); + return checkSumXor((double[]) object); } else if (object instanceof Integer[]) { - return checkSum((Integer[]) object); + return checkSumXor((Integer[]) object); } else { failed("Unknow type of array: " + object + " of class " + object.getClass().getName()); @@ -1141,76 +1176,275 @@ public class Sorting { } } - private static int checkSum(Integer[] a) { - int checkXorSum = 0; + private static int checkSumXor(Integer[] a) { + int checkSum = 0; for (Integer e : a) { - checkXorSum ^= e.intValue(); + checkSum ^= e.intValue(); } - return checkXorSum; + return checkSum; } - private static int checkSum(int[] a) { - int checkXorSum = 0; + private static int checkSumXor(int[] a) { + int checkSum = 0; for (int e : a) { - checkXorSum ^= e; + checkSum ^= e; } - return checkXorSum; + return checkSum; } - private static int checkSum(long[] a) { - long checkXorSum = 0; + private static int checkSumXor(long[] a) { + long checkSum = 0; for (long e : a) { - checkXorSum ^= e; + checkSum ^= e; } - return (int) checkXorSum; + return (int) checkSum; } - private static int checkSum(short[] a) { - short checkXorSum = 0; + private static int checkSumXor(short[] a) { + short checkSum = 0; for (short e : a) { - checkXorSum ^= e; + checkSum ^= e; } - return (int) checkXorSum; + return (int) checkSum; } - private static int checkSum(byte[] a) { - byte checkXorSum = 0; + private static int checkSumXor(byte[] a) { + byte checkSum = 0; for (byte e : a) { - checkXorSum ^= e; + checkSum ^= e; } - return (int) checkXorSum; + return (int) checkSum; } - private static int checkSum(char[] a) { - char checkXorSum = 0; + private static int checkSumXor(char[] a) { + char checkSum = 0; for (char e : a) { - checkXorSum ^= e; + checkSum ^= e; } - return (int) checkXorSum; + return (int) checkSum; } - private static int checkSum(float[] a) { - int checkXorSum = 0; + private static int checkSumXor(float[] a) { + int checkSum = 0; for (float e : a) { - checkXorSum ^= (int) e; + checkSum ^= (int) e; } - return checkXorSum; + return checkSum; } - private static int checkSum(double[] a) { - int checkXorSum = 0; + private static int checkSumXor(double[] a) { + int checkSum = 0; for (double e : a) { - checkXorSum ^= (int) e; + checkSum ^= (int) e; + } + return checkSum; + } + + private static int checkSumPlus(Object object) { + if (object instanceof int[]) { + return checkSumPlus((int[]) object); + } else if (object instanceof long[]) { + return checkSumPlus((long[]) object); + } else if (object instanceof short[]) { + return checkSumPlus((short[]) object); + } else if (object instanceof byte[]) { + return checkSumPlus((byte[]) object); + } else if (object instanceof char[]) { + return checkSumPlus((char[]) object); + } else if (object instanceof float[]) { + return checkSumPlus((float[]) object); + } else if (object instanceof double[]) { + return checkSumPlus((double[]) object); + } else if (object instanceof Integer[]) { + return checkSumPlus((Integer[]) object); + } else { + failed("Unknow type of array: " + object + " of class " + + object.getClass().getName()); + return -1; + } + } + + private static int checkSumPlus(int[] a) { + int checkSum = 0; + + for (int e : a) { + checkSum += e; + } + return checkSum; + } + + private static int checkSumPlus(long[] a) { + long checkSum = 0; + + for (long e : a) { + checkSum += e; + } + return (int) checkSum; + } + + private static int checkSumPlus(short[] a) { + short checkSum = 0; + + for (short e : a) { + checkSum += e; + } + return (int) checkSum; + } + + private static int checkSumPlus(byte[] a) { + byte checkSum = 0; + + for (byte e : a) { + checkSum += e; + } + return (int) checkSum; + } + + private static int checkSumPlus(char[] a) { + char checkSum = 0; + + for (char e : a) { + checkSum += e; + } + return (int) checkSum; + } + + private static int checkSumPlus(float[] a) { + int checkSum = 0; + + for (float e : a) { + checkSum += (int) e; + } + return checkSum; + } + + private static int checkSumPlus(double[] a) { + int checkSum = 0; + + for (double e : a) { + checkSum += (int) e; + } + return checkSum; + } + + private static int checkSumPlus(Integer[] a) { + int checkSum = 0; + + for (Integer e : a) { + checkSum += e.intValue(); + } + return checkSum; + } + + private static void sortByInsertionSort(Object object) { + if (object instanceof int[]) { + sortByInsertionSort((int[]) object); + } else if (object instanceof long[]) { + sortByInsertionSort((long[]) object); + } else if (object instanceof short[]) { + sortByInsertionSort((short[]) object); + } else if (object instanceof byte[]) { + sortByInsertionSort((byte[]) object); + } else if (object instanceof char[]) { + sortByInsertionSort((char[]) object); + } else if (object instanceof float[]) { + sortByInsertionSort((float[]) object); + } else if (object instanceof double[]) { + sortByInsertionSort((double[]) object); + } else if (object instanceof Integer[]) { + sortByInsertionSort((Integer[]) object); + } else { + failed("Unknow type of array: " + object + " of class " + + object.getClass().getName()); + } + } + + private static void sortByInsertionSort(int[] a) { + for (int j, i = 1; i < a.length; i++) { + int ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; + } + } + + private static void sortByInsertionSort(long[] a) { + for (int j, i = 1; i < a.length; i++) { + long ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; + } + } + + private static void sortByInsertionSort(short[] a) { + for (int j, i = 1; i < a.length; i++) { + short ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; + } + } + + private static void sortByInsertionSort(byte[] a) { + for (int j, i = 1; i < a.length; i++) { + byte ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; + } + } + + private static void sortByInsertionSort(char[] a) { + for (int j, i = 1; i < a.length; i++) { + char ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; + } + } + + private static void sortByInsertionSort(float[] a) { + for (int j, i = 1; i < a.length; i++) { + float ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; + } + } + + private static void sortByInsertionSort(double[] a) { + for (int j, i = 1; i < a.length; i++) { + double ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; + } + } + + private static void sortByInsertionSort(Integer[] a) { + for (int j, i = 1; i < a.length; i++) { + Integer ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; } - return checkXorSum; } private static void sort(Object object) { @@ -1292,7 +1526,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i].intValue() > a[i + 1].intValue()) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } @@ -1314,7 +1548,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } @@ -1336,7 +1570,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } @@ -1358,7 +1592,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } @@ -1380,7 +1614,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } @@ -1402,7 +1636,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } @@ -1424,7 +1658,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } @@ -1446,7 +1680,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } diff --git a/jdk/test/javax/swing/JComboBox/6632953/bug6632953.java b/jdk/test/javax/swing/JComboBox/6632953/bug6632953.java new file mode 100644 index 00000000000..90352765eb7 --- /dev/null +++ b/jdk/test/javax/swing/JComboBox/6632953/bug6632953.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 6632953 + * @summary MetalComboBoxUI.getBaseline(JComponent, int, int) throws IAE for valid width/height + * @author Alexander Potochkin + */ + +import javax.swing.JComboBox; +import javax.swing.plaf.metal.MetalComboBoxUI; + +public class bug6632953 { + + public static void main(String... args) throws Exception { + MetalComboBoxUI ui = new MetalComboBoxUI(); + ui.installUI(new JComboBox()); + ui.getBaseline(new JComboBox(), 0, 0); + ui.getBaseline(new JComboBox(), 1, 1); + ui.getBaseline(new JComboBox(), 2, 2); + ui.getBaseline(new JComboBox(), 3, 3); + ui.getBaseline(new JComboBox(), 4, 4); + } +} diff --git a/jdk/test/javax/swing/JScrollBar/6542335/bug6542335.java b/jdk/test/javax/swing/JScrollBar/6542335/bug6542335.java new file mode 100644 index 00000000000..33e95d8ecac --- /dev/null +++ b/jdk/test/javax/swing/JScrollBar/6542335/bug6542335.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 6542335 + @summary different behavior on knob of scroll bar between 1.4.2 and 5.0 + @author Alexander Potochkin + @run main bug6542335 +*/ + +import sun.awt.SunToolkit; + +import javax.swing.*; +import javax.swing.plaf.basic.BasicScrollBarUI; +import java.awt.*; +import java.awt.event.InputEvent; + +public class bug6542335 { + private static JScrollBar sb; + private static MyScrollBarUI ui; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(10); + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + final JFrame frame = new JFrame("bug6542335"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + sb = new JScrollBar(0, 0, 1, 0, 1); + + ui = new MyScrollBarUI(); + sb.setUI(ui); + + sb.setPreferredSize(new Dimension(200, 17)); + DefaultBoundedRangeModel rangeModel = new DefaultBoundedRangeModel(); + rangeModel.setMaximum(100); + rangeModel.setMinimum(0); + rangeModel.setExtent(50); + rangeModel.setValue(50); + + sb.setModel(rangeModel); + frame.add(sb); + + frame.setSize(200, 100); + frame.setVisible(true); + } + }); + + Rectangle thumbBounds = new Rectangle(ui.getThumbBounds()); + + toolkit.realSync(); + Point l = sb.getLocationOnScreen(); + robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight()/2); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + + if (!thumbBounds.equals(ui.getThumbBounds())) { + throw new RuntimeException("Test failed"); + } + } + + static class MyScrollBarUI extends BasicScrollBarUI { + public Rectangle getThumbBounds() { + return super.getThumbBounds(); + } + } +} diff --git a/jdk/test/javax/swing/JTable/Test6888156.java b/jdk/test/javax/swing/JTable/Test6888156.java index 79809e582a1..f82d8026be4 100644 --- a/jdk/test/javax/swing/JTable/Test6888156.java +++ b/jdk/test/javax/swing/JTable/Test6888156.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -71,14 +71,14 @@ public class Test6888156 { table = new JTable(model); } - public void test(final LookAndFeel laf) throws Exception { + public void test(final String laf) throws Exception { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { try { + System.out.println(laf); UIManager.setLookAndFeel(laf); - } catch (UnsupportedLookAndFeelException e) { - System.err.println(laf.getDescription() + - " is unsupported; continuing"); + } catch (Exception e) { + System.err.println(laf + " is unsupported; continuing"); return; } SwingUtilities.updateComponentTreeUI(table); @@ -92,8 +92,10 @@ public class Test6888156 { public static void main(String[] args) throws Exception { Test6888156 t = new Test6888156(); - t.test(new javax.swing.plaf.nimbus.NimbusLookAndFeel()); - t.test(new com.sun.java.swing.plaf.gtk.GTKLookAndFeel()); + t.test("javax.swing.plaf.nimbus.NimbusLookAndFeel"); + t.test("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); + for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { + t.test(laf.getClassName()); + } } } - diff --git a/jdk/test/javax/swing/JTextArea/6940863/bug6940863.java b/jdk/test/javax/swing/JTextArea/6940863/bug6940863.java index ffcd2d44aa5..b868d41adfc 100644 --- a/jdk/test/javax/swing/JTextArea/6940863/bug6940863.java +++ b/jdk/test/javax/swing/JTextArea/6940863/bug6940863.java @@ -56,6 +56,7 @@ public class bug6940863 { public static void main(String[] args) throws Exception { if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) { System.out.println("The test is suitable only for Windows OS. Skipped"); + return; } UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); diff --git a/jdk/test/sun/misc/BootClassLoaderHook/TestHook.java b/jdk/test/sun/misc/BootClassLoaderHook/TestHook.java index 7dca5e87dc0..5a620b1a6f5 100644 --- a/jdk/test/sun/misc/BootClassLoaderHook/TestHook.java +++ b/jdk/test/sun/misc/BootClassLoaderHook/TestHook.java @@ -24,7 +24,10 @@ import java.io.File; import java.util.TreeSet; import java.util.Set; +import java.net.URLStreamHandlerFactory; import sun.misc.BootClassLoaderHook; +import sun.misc.URLClassPath; + /* @test * @bug 6888802 @@ -68,10 +71,6 @@ public class TestHook extends BootClassLoaderHook { for (String s : copy) { System.out.println(" Loaded " + s); } - - if (BootClassLoaderHook.getBootstrapPaths().length > 0) { - throw new RuntimeException("Unexpected returned value from getBootstrapPaths()"); - } } private static void testHook() throws Exception { @@ -98,8 +97,9 @@ public class TestHook extends BootClassLoaderHook { return false; } - public File[] getAdditionalBootstrapPaths() { - return new File[0]; + public URLClassPath getBootstrapClassPath(URLClassPath bcp, + URLStreamHandlerFactory factory) { + return bcp; } public boolean isCurrentThreadPrefetching() { diff --git a/jdk/test/sun/net/www/http/HttpClient/B6726695.java b/jdk/test/sun/net/www/http/HttpClient/B6726695.java index 9e69e8e3d46..01840850cb0 100644 --- a/jdk/test/sun/net/www/http/HttpClient/B6726695.java +++ b/jdk/test/sun/net/www/http/HttpClient/B6726695.java @@ -23,7 +23,7 @@ /* * @test - * @bug 6726695 + * @bug 6726695 6993490 * @summary HttpURLConnection shoul support 'Expect: 100-contimue' headers for PUT */ @@ -184,7 +184,15 @@ public class B6726695 extends Thread { out.flush(); // Then read the body char[] cbuf = new char[512]; - int l = in.read(cbuf); + in.read(cbuf); + + /* Force the server to not respond for more that the expect 100-Continue + * timeout set by the HTTP handler (5000 millis). This ensures the + * timeout is correctly resets the default read timeout, infinity. + * See 6993490. */ + System.out.println("server sleeping..."); + try {Thread.sleep(6000); } catch (InterruptedException e) {} + // finally send the 200 OK out.print("HTTP/1.1 200 OK"); out.print("Server: Sun-Java-System-Web-Server/7.0\r\n"); diff --git a/jdk/test/sun/net/www/http/KeepAliveCache/B5045306.java b/jdk/test/sun/net/www/http/KeepAliveCache/B5045306.java index ac9d4e568f3..08b3079b5cf 100644 --- a/jdk/test/sun/net/www/http/KeepAliveCache/B5045306.java +++ b/jdk/test/sun/net/www/http/KeepAliveCache/B5045306.java @@ -23,7 +23,7 @@ /* * @test - * @bug 5045306 6356004 + * @bug 5045306 6356004 6993490 * @library ../../httptest/ * @build HttpCallback HttpServer HttpTransaction * @run main/othervm B5045306 @@ -32,7 +32,6 @@ import java.net.*; import java.io.*; -import java.nio.channels.*; import java.lang.management.*; /* Part 1: @@ -164,6 +163,14 @@ class SimpleHttpTransaction implements HttpCallback failed = true; trans.setResponseHeader ("Content-length", Integer.toString(0)); + + /* Force the server to not respond for more that the timeout + * set by the keepalive cleaner (5000 millis). This ensures the + * timeout is correctly resets the default read timeout, + * infinity. See 6993490. */ + System.out.println("server sleeping..."); + try {Thread.sleep(6000); } catch (InterruptedException e) {} + trans.sendResponse(200, "OK"); } else if(path.equals("/part2")) { System.out.println("Call to /part2"); diff --git a/jdk/test/sun/net/www/protocol/http/ChunkedErrorStream.java b/jdk/test/sun/net/www/protocol/http/ChunkedErrorStream.java index ee5368a59cc..d5e72f44889 100644 --- a/jdk/test/sun/net/www/protocol/http/ChunkedErrorStream.java +++ b/jdk/test/sun/net/www/protocol/http/ChunkedErrorStream.java @@ -23,7 +23,7 @@ /* * @test - * @bug 6488669 6595324 + * @bug 6488669 6595324 6993490 * @run main/othervm ChunkedErrorStream * @summary Chunked ErrorStream tests */ @@ -48,6 +48,18 @@ import com.sun.net.httpserver.*; * 2) Client sends request to server and tries to * getErrorStream(). 4K + 10 bytes must be read from * the errorStream. + * + * Part 3: 6993490 + * Reuse persistent connection from part 2, the error stream + * buffering will have set a reduced timeout on the socket and + * tried to reset it to the default, infinity. Client must not + * throw a timeout exception. If it does, it indicates that the + * default timeout was not reset correctly. + * If no timeout exception is thrown, it does not guarantee that + * the timeout was reset correctly, as there is a potential race + * between the sleeping server and the client thread. Typically, + * 1000 millis has been enought to reliable reproduce this problem + * since the error stream buffering sets the timeout to 60 millis. */ public class ChunkedErrorStream @@ -75,19 +87,18 @@ public class ChunkedErrorStream } finally { httpServer.stop(1); } - } void doClient() { - for (int times=0; times<2; times++) { + for (int times=0; times<3; times++) { HttpURLConnection uc = null; try { InetSocketAddress address = httpServer.getAddress(); String URLStr = "http://localhost:" + address.getPort() + "/test/"; if (times == 0) { - URLStr += 6488669; + URLStr += "first"; } else { - URLStr += 6595324; + URLStr += "second"; } System.out.println("Trying " + URLStr); @@ -97,6 +108,11 @@ public class ChunkedErrorStream throw new RuntimeException("Failed: getInputStream should throw and IOException"); } catch (IOException e) { + if (e instanceof SocketTimeoutException) { + e.printStackTrace(); + throw new RuntimeException("Failed: SocketTimeoutException should not happen"); + } + // This is what we expect to happen. InputStream es = uc.getErrorStream(); byte[] ba = new byte[1024]; @@ -112,7 +128,7 @@ public class ChunkedErrorStream if (count == 0) throw new RuntimeException("Failed: ErrorStream returning 0 bytes"); - if (times == 1 && count != (4096+10)) + if (times >= 1 && count != (4096+10)) throw new RuntimeException("Failed: ErrorStream returning " + count + " bytes. Expecting " + (4096+10)); @@ -128,13 +144,13 @@ public class ChunkedErrorStream httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0); // create HttpServer context - HttpContext ctx1 = httpServer.createContext("/test/6488669", new Handler6488669()); - HttpContext ctx2 = httpServer.createContext("/test/6595324", new Handler6595324()); + httpServer.createContext("/test/first", new FirstHandler()); + httpServer.createContext("/test/second", new SecondHandler()); httpServer.start(); } - class Handler6488669 implements HttpHandler { + class FirstHandler implements HttpHandler { public void handle(HttpExchange t) throws IOException { InputStream is = t.getRequestBody(); byte[] ba = new byte[1024]; @@ -156,13 +172,22 @@ public class ChunkedErrorStream } } - class Handler6595324 implements HttpHandler { + static class SecondHandler implements HttpHandler { + /* count greater than 0, slow response */ + static int count = 0; + public void handle(HttpExchange t) throws IOException { InputStream is = t.getRequestBody(); byte[] ba = new byte[1024]; while (is.read(ba) != -1); is.close(); + if (count > 0) { + System.out.println("server sleeping..."); + try { Thread.sleep(1000); } catch(InterruptedException e) {} + } + count++; + t.sendResponseHeaders(404, 0); OutputStream os = t.getResponseBody(); diff --git a/jdk/test/sun/util/logging/PlatformLoggerTest.java b/jdk/test/sun/util/logging/PlatformLoggerTest.java index 5f7f923fee3..a2f6540d124 100644 --- a/jdk/test/sun/util/logging/PlatformLoggerTest.java +++ b/jdk/test/sun/util/logging/PlatformLoggerTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 6882376 + * @bug 6882376 6985460 * @summary Test if java.util.logging.Logger is created before and after * logging is enabled. Also validate some basic PlatformLogger * operations. @@ -43,6 +43,8 @@ public class PlatformLoggerTest { final String GOO_PLATFORM_LOGGER = "test.platformlogger.goo"; final String BAR_LOGGER = "test.logger.bar"; PlatformLogger goo = PlatformLogger.getLogger(GOO_PLATFORM_LOGGER); + // test the PlatformLogger methods + testLogMethods(goo); // Create a platform logger using the default PlatformLogger foo = PlatformLogger.getLogger(FOO_PLATFORM_LOGGER); @@ -56,6 +58,10 @@ public class PlatformLoggerTest { PlatformLogger bar = PlatformLogger.getLogger(BAR_PLATFORM_LOGGER); checkPlatformLogger(bar, BAR_PLATFORM_LOGGER); + // test the PlatformLogger methods + testLogMethods(goo); + testLogMethods(bar); + checkLogger(FOO_PLATFORM_LOGGER, Level.FINER); checkLogger(BAR_PLATFORM_LOGGER, Level.FINER); @@ -64,6 +70,7 @@ public class PlatformLoggerTest { foo.setLevel(PlatformLogger.SEVERE); checkLogger(FOO_PLATFORM_LOGGER, Level.SEVERE); + } private static void checkPlatformLogger(PlatformLogger logger, String name) { @@ -108,4 +115,33 @@ public class PlatformLoggerTest { logger.getName() + " " + logger.getLevel()); } } + + private static void testLogMethods(PlatformLogger logger) { + logger.severe("Test severe(String, Object...) {0} {1}", new Long(1), "string"); + // test Object[] + logger.severe("Test severe(String, Object...) {0}", (Object[]) getPoints()); + logger.warning("Test warning(String, Throwable)", new Throwable("Testing")); + logger.info("Test info(String)"); + } + + static Point[] getPoints() { + Point[] res = new Point[3]; + res[0] = new Point(0,0); + res[1] = new Point(1,1); + res[2] = new Point(2,2); + return res; + } + + static class Point { + final int x; + final int y; + public Point(int x, int y) { + this.x = x; + this.y = y; + } + public String toString() { + return "{x="+x + ", y=" + y + "}"; + } + } + } diff --git a/jdk/test/sun/util/logging/SourceClassName.java b/jdk/test/sun/util/logging/SourceClassName.java new file mode 100644 index 00000000000..e662166ab46 --- /dev/null +++ b/jdk/test/sun/util/logging/SourceClassName.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6985460 + * @summary Test the source class name and method output by the platform + * logger. + * + * @compile -XDignore.symbol.file SourceClassName.java + * @run main/othervm SourceClassName + */ + +import java.util.logging.*; +import java.io.*; +import sun.util.logging.PlatformLogger; + +public class SourceClassName { + public static void main(String[] args) throws Exception { + File dir = new File(System.getProperty("user.dir", ".")); + File log = new File(dir, "testlog.txt"); + PrintStream logps = new PrintStream(log); + writeLogRecords(logps); + checkLogRecords(log); + } + + private static void writeLogRecords(PrintStream logps) throws Exception { + PrintStream err = System.err; + try { + System.setErr(logps); + + Object[] params = new Object[] { new Long(1), "string"}; + PlatformLogger plog = PlatformLogger.getLogger("test.log.foo"); + plog.severe("Log message {0} {1}", (Object[]) params); + + // create a java.util.logging.Logger + // now java.util.logging.Logger should be created for each platform logger + Logger logger = Logger.getLogger("test.log.bar"); + logger.log(Level.SEVERE, "Log message {0} {1}", params); + + plog.severe("Log message {0} {1}", (Object[]) params); + } finally { + logps.flush(); + logps.close(); + System.setErr(err); + } + } + + private static void checkLogRecords(File log) throws Exception { + System.out.println("Checking log records in file: " + log); + FileInputStream in = new FileInputStream(log); + String EXPECTED_LOG = "SEVERE: Log message 1 string"; + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + String line; + String[] record = new String[2]; + int count = 0; + int i = 0; + while ((line = reader.readLine()) != null) { + line = line.trim(); + System.out.println(line); + record[i++] = line; + if (i == 2) { + i = 0; + count++; + // check source class name and method + String[] ss = record[0].split("\\s+"); + int len = ss.length; + if (!ss[len-2].equals("SourceClassName") || + !ss[len-1].equals("writeLogRecords")) { + throw new RuntimeException("Unexpected source: " + + ss[len-2] + " " + ss[len-1]); + } + + // check log message + if (!record[1].equals(EXPECTED_LOG)) { + throw new RuntimeException("Unexpected log: " + record[1]); + } + } + } + if (count != 3) { + throw new RuntimeException("Unexpected number of records: " + count); + } + } finally { + in.close(); + } + } +} diff --git a/jdk/test/tools/jar/UpdateManifest.java b/jdk/test/tools/jar/UpdateManifest.java index 2bcd25081ea..64897183b57 100644 --- a/jdk/test/tools/jar/UpdateManifest.java +++ b/jdk/test/tools/jar/UpdateManifest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -23,7 +23,7 @@ /** * @test - * @bug 6434207 6442687 + * @bug 6434207 6442687 6984046 * @summary Ensure that jar ufm actually updates the * existing jar file's manifest with contents of the * manifest file. @@ -87,7 +87,7 @@ public class UpdateManifest { if (!debug) manifestOrig.deleteOnExit(); PrintWriter pw = new PrintWriter(manifestOrig); pw.println("Manifest-Version: 1.0"); - pw.println("Created-By: 1.6.0-internal (Sun Microsystems Inc.)"); + pw.println("Created-By: 1.7.0-internal (Oracle Corporation)"); pw.println(""); pw.println(animal); pw.println(specTitle); @@ -109,7 +109,7 @@ public class UpdateManifest { if (!debug) manifestUpdate.deleteOnExit(); pw = new PrintWriter(manifestUpdate); final String createdBy = - "Created-By: 1.5.0-special (Sun Microsystems Inc.)"; + "Created-By: 1.7.0-special (Oracle Corporation)"; final String specVersion = "Specification-Version: 1.0.0.0"; pw.println(createdBy); // replaces line in the original diff --git a/jdk/test/tools/launcher/Arrrghs.java b/jdk/test/tools/launcher/Arrrghs.java index f5730ba3532..de3dbe20112 100644 --- a/jdk/test/tools/launcher/Arrrghs.java +++ b/jdk/test/tools/launcher/Arrrghs.java @@ -24,6 +24,7 @@ /** * @test * @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881 6753938 + * 6894719 * @summary Argument parsing validation. * @compile -XDignore.symbol.file Arrrghs.java TestHelper.java * @run main Arrrghs @@ -326,20 +327,36 @@ public class Arrrghs { System.out.println(tr); } + static void test6894719() { + // test both arguments to ensure they exist + TestHelper.TestResult tr = null; + tr = TestHelper.doExec(TestHelper.javaCmd, + "-no-jre-restrict-search", "-version"); + tr.checkPositive(); + System.out.println(tr); + + tr = TestHelper.doExec(TestHelper.javaCmd, + "-jre-restrict-search", "-version"); + tr.checkPositive(); + System.out.println(tr); + } /** * @param args the command line arguments * @throws java.io.FileNotFoundException */ public static void main(String[] args) throws FileNotFoundException { - if (TestHelper.debug) System.out.println("Starting Arrrghs tests"); - quoteParsingTests(); - runBasicErrorMessageTests(); - runMainMethodTests(); - if (TestHelper.testExitValue > 0) { - System.out.println("Total of " + TestHelper.testExitValue + " failed"); - System.exit(1); - } else { - System.out.println("All tests pass"); - } + if (TestHelper.debug) { + System.out.println("Starting Arrrghs tests"); + } + quoteParsingTests(); + runBasicErrorMessageTests(); + runMainMethodTests(); + test6894719(); + if (TestHelper.testExitValue > 0) { + System.out.println("Total of " + TestHelper.testExitValue + " failed"); + System.exit(1); + } else { + System.out.println("All tests pass"); } } +} diff --git a/jdk/test/tools/pack200/AttributeTests.java b/jdk/test/tools/pack200/AttributeTests.java new file mode 100644 index 00000000000..e7107996cc8 --- /dev/null +++ b/jdk/test/tools/pack200/AttributeTests.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +/* + * @test + * @bug 6982312 + * @summary tests various classfile format and attribute handling by pack200 + * @compile -XDignore.symbol.file Utils.java AttributeTests.java + * @run main AttributeTests + * @author ksrini + */ +public class AttributeTests { + + public static void main(String... args) throws Exception { + test6982312(); + test6746111(); + } + /* + * This is an interim test, which ensures pack200 handles JSR-292 related + * classfile changes seamlessly, until all the classfile changes in jdk7 + * and jdk8 are fully supported. At that time this test should be jettisoned, + * along with the associated jar file. + * + * The jar file contains sources and classes noting the classes were + * derived by using the javac from the lambda project, + * see http://openjdk.java.net/projects/lambda/. + * Therefore the classes contained in the jar cannot be compiled, using + * the standard jdk7's javac compiler. + */ + static void test6982312() throws IOException { + String pack200Cmd = Utils.getPack200Cmd(); + File dynJar = new File(".", "dyn.jar"); + Utils.copyFile(new File(Utils.TEST_SRC_DIR, "dyn.jar"), dynJar); + File testJar = new File(".", "test.jar"); + List cmds = new ArrayList(); + cmds.add(pack200Cmd); + cmds.add("--repack"); + cmds.add(testJar.getAbsolutePath()); + cmds.add(dynJar.getAbsolutePath()); + Utils.runExec(cmds); + /* + * compare the repacked jar bit-wise, as all the files + * should be transmitted "as-is". + */ + Utils.doCompareBitWise(dynJar.getAbsoluteFile(), testJar.getAbsoluteFile()); + testJar.delete(); + dynJar.delete(); + } + + /* + * this test checks to see if we get the expected strings for output + */ + static void test6746111() throws Exception { + String pack200Cmd = Utils.getPack200Cmd(); + File badAttrJar = new File(".", "badattr.jar"); + Utils.copyFile(new File(Utils.TEST_SRC_DIR, "badattr.jar"), badAttrJar); + File testJar = new File(".", "test.jar"); + List cmds = new ArrayList(); + cmds.add(pack200Cmd); + cmds.add("--repack"); + cmds.add("-v"); + cmds.add(testJar.getAbsolutePath()); + cmds.add(badAttrJar.getAbsolutePath()); + List output = Utils.runExec(cmds); + /* + * compare the repacked jar bit-wise, as all the files + * should be transmitted "as-is". + */ + Utils.doCompareBitWise(badAttrJar.getAbsoluteFile(), testJar.getAbsoluteFile()); + String[] expectedStrings = { + "WARNING: Passing class file uncompressed due to unrecognized" + + " attribute: Foo.class", + "INFO: com.sun.java.util.jar.pack.Attribute$FormatException: " + + "class attribute \"XourceFile\": is unknown attribute " + + "in class Foo", + "INFO: com.sun.java.util.jar.pack.ClassReader$ClassFormatException: " + + "AnnotationDefault: attribute length cannot be zero, in Test.message()", + "WARNING: Passing class file uncompressed due to unknown class format: Test.class" + }; + List notfoundList = new ArrayList(); + notfoundList.addAll(Arrays.asList(expectedStrings)); + // make sure the expected messages are emitted + for (String x : output) { + findString(x, notfoundList, expectedStrings); + } + if (!notfoundList.isEmpty()) { + System.out.println("Not found:"); + for (String x : notfoundList) { + System.out.println(x); + } + throw new Exception("Test fails: " + notfoundList.size() + + " expected strings not found"); + } + testJar.delete(); + badAttrJar.delete(); + } + + private static void findString(String outputStr, List notfoundList, + String[] expectedStrings) { + for (String y : expectedStrings) { + if (outputStr.contains(y)) { + notfoundList.remove(y); + return; + } + } + } +} diff --git a/jdk/test/tools/pack200/PackageVersionTest.java b/jdk/test/tools/pack200/PackageVersionTest.java index 344aadd6b61..538b92ecafc 100644 --- a/jdk/test/tools/pack200/PackageVersionTest.java +++ b/jdk/test/tools/pack200/PackageVersionTest.java @@ -24,7 +24,7 @@ /* * @test - * @bug 6712743 + * @bug 6712743 6991164 * @summary verify package versions * @compile -XDignore.symbol.file Utils.java PackageVersionTest.java * @run main PackageVersionTest @@ -40,6 +40,7 @@ import java.io.PrintStream; import java.util.jar.JarFile; import java.util.jar.Pack200; import java.util.jar.Pack200.Packer; +import java.util.jar.Pack200.Unpacker; public class PackageVersionTest { private static final File javaHome = new File(System.getProperty("java.home")); @@ -60,6 +61,7 @@ public class PackageVersionTest { createClassFile("Test6"); createClassFile("Test7"); + verify6991164(); verifyPack("Test5.class", JAVA5_PACKAGE_MAJOR_VERSION, JAVA5_PACKAGE_MINOR_VERSION); @@ -75,6 +77,18 @@ public class PackageVersionTest { JAVA5_PACKAGE_MINOR_VERSION); } + static void verify6991164() { + Unpacker unpacker = Pack200.newUnpacker(); + String versionStr = unpacker.toString(); + String expected = "Pack200, Vendor: " + + System.getProperty("java.vendor") + ", Version: " + + JAVA6_PACKAGE_MAJOR_VERSION + "." + JAVA6_PACKAGE_MINOR_VERSION; + if (!versionStr.equals(expected)) { + System.out.println("Expected: " + expected); + System.out.println("Obtained: " + versionStr); + throw new RuntimeException("did not get expected string " + expected); + } + } static void createClassFile(String name) { createJavaFile(name); diff --git a/jdk/test/tools/pack200/badattr.jar b/jdk/test/tools/pack200/badattr.jar new file mode 100644 index 00000000000..330be6147c1 Binary files /dev/null and b/jdk/test/tools/pack200/badattr.jar differ diff --git a/jdk/test/tools/pack200/dyn.jar b/jdk/test/tools/pack200/dyn.jar new file mode 100644 index 00000000000..b04c2a9e825 Binary files /dev/null and b/jdk/test/tools/pack200/dyn.jar differ diff --git a/langtools/.hgtags b/langtools/.hgtags index d7bb666b3b3..0d6cdae403a 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -86,3 +86,5 @@ a408ebb8b3d427dbb3d8ce153dfaeb060564a0a4 jdk7-b108 4826378eaade4c6676c452efe954be4ee113cc11 jdk7-b109 32da0f38d2fe96c558492b8707b40da24643d41e jdk7-b110 8bec624274ef8535720cff553374347c2f4f5fb2 jdk7-b111 +fd2579b80b83bf5d4289426016c7d29174ba5dd9 jdk7-b112 +6dbd2d869b0573fa5b799a23cccff47d20c12696 jdk7-b113 diff --git a/langtools/make/netbeans/langtools/build.xml b/langtools/make/netbeans/langtools/build.xml index cbdb1a1e0f1..9202ed597ca 100644 --- a/langtools/make/netbeans/langtools/build.xml +++ b/langtools/make/netbeans/langtools/build.xml @@ -31,44 +31,44 @@ --> - - - - - - + + - - - + - + - + - + Must set property 'includes' - - - - - + - + Must set property 'run.classname' - + - - - + @@ -118,7 +118,7 @@ - + @@ -127,36 +127,36 @@ - + Some tests failed; see report for details. - + - + - + Must set property 'debug.classname' - + Must set property 'jtreg.tests' - + - + Must set property 'class' @@ -169,16 +169,16 @@ - + - - - + @@ -187,7 +187,7 @@ - + @@ -196,26 +196,26 @@ - + - + - + - - + - @@ -236,7 +236,7 @@ - + @@ -251,28 +251,29 @@ - - + - + diff --git a/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java index 8d949541ca5..023712e4c3b 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -99,9 +99,6 @@ public class JavaCompiler extends com.sun.tools.javac.main.JavaCompiler { private static Context preRegister(Context context) { Bark.preRegister(context); - // force the use of the scanner that captures Javadoc comments - DocCommentScanner.Factory.preRegister(context); - if (context.get(JavaFileManager.class) == null) JavacFileManager.preRegister(context); diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java index 1e98ec9ce27..07e39a8c3bd 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java @@ -1,5 +1,5 @@ /* - * 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. * * This code is free software; you can redistribute it and/or modify it @@ -96,9 +96,6 @@ public class JavacTaskImpl extends JavacTask { args.getClass(); context.getClass(); fileObjects.getClass(); - - // force the use of the scanner that captures Javadoc comments - com.sun.tools.javac.parser.DocCommentScanner.Factory.preRegister(context); } JavacTaskImpl(JavacTool tool, @@ -337,9 +334,13 @@ public class JavacTaskImpl extends JavacTask { ListBuffer elements = new ListBuffer(); for (JCCompilationUnit unit : units) { - for (JCTree node : unit.defs) - if (node.getTag() == JCTree.CLASSDEF) - elements.append(((JCTree.JCClassDecl) node).sym); + for (JCTree node : unit.defs) { + if (node.getTag() == JCTree.CLASSDEF) { + JCClassDecl cdef = (JCClassDecl) node; + if (cdef.sym != null) // maybe null if errors in anno processing + elements.append(cdef.sym); + } + } } return elements.toList(); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java index 889beb95c2a..e1c6053b27b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java @@ -1,5 +1,5 @@ /* - * 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. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,6 @@ import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.comp.MemberEnter; import com.sun.tools.javac.comp.Resolve; import com.sun.tools.javac.model.JavacElements; -import com.sun.tools.javac.processing.JavacMessager; import com.sun.tools.javac.processing.JavacProcessingEnvironment; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree; @@ -81,14 +80,15 @@ import com.sun.tools.javac.util.Pair; */ public class JavacTrees extends Trees { - private final Resolve resolve; - private final Enter enter; - private final Log log; - private final MemberEnter memberEnter; - private final Attr attr; - private final TreeMaker treeMaker; - private final JavacElements elements; - private final JavacTaskImpl javacTaskImpl; + // in a world of a single context per compilation, these would all be final + private Resolve resolve; + private Enter enter; + private Log log; + private MemberEnter memberEnter; + private Attr attr; + private TreeMaker treeMaker; + private JavacElements elements; + private JavacTaskImpl javacTaskImpl; public static JavacTrees instance(JavaCompiler.CompilationTask task) { if (!(task instanceof JavacTaskImpl)) @@ -111,6 +111,14 @@ public class JavacTrees extends Trees { private JavacTrees(Context context) { context.put(JavacTrees.class, this); + init(context); + } + + public void updateContext(Context context) { + init(context); + } + + private void init(Context context) { attr = Attr.instance(context); enter = Enter.instance(context); elements = JavacElements.instance(context); @@ -337,6 +345,7 @@ public class JavacTrees extends Trees { super(M); } + @Override public T copy(T t, JCTree leaf) { T t2 = super.copy(t, leaf); if (t == leaf) diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java b/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java index ce4270ecbe6..8bbc73d84d8 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java @@ -70,6 +70,45 @@ public class Scope { */ public int nelems = 0; + /** A timestamp - useful to quickly check whether a scope has changed or not + */ + public ScopeCounter scopeCounter; + + static ScopeCounter dummyCounter = new ScopeCounter() { + @Override + public void inc() { + //do nothing + } + }; + + public static class ScopeCounter { + protected static final Context.Key scopeCounterKey = + new Context.Key(); + + public static ScopeCounter instance(Context context) { + ScopeCounter instance = context.get(scopeCounterKey); + if (instance == null) + instance = new ScopeCounter(context); + return instance; + } + + protected ScopeCounter(Context context) { + context.put(scopeCounterKey, this); + } + + private ScopeCounter() {}; + + private long val = 0; + + public void inc() { + val++; + } + + public long val() { + return val; + } + } + /** Every hash bucket is a list of Entry's which ends in sentinel. */ private static final Entry sentinel = new Entry(null, null, null, null); @@ -80,12 +119,12 @@ public class Scope { /** A value for the empty scope. */ - public static final Scope emptyScope = new Scope(null, null, new Entry[]{}); + public static final Scope emptyScope = new Scope(null, null, new Entry[]{}, dummyCounter); /** Construct a new scope, within scope next, with given owner, using * given table. The table's length must be an exponent of 2. */ - Scope(Scope next, Symbol owner, Entry[] table) { + private Scope(Scope next, Symbol owner, Entry[] table, ScopeCounter scopeCounter) { this.next = next; assert emptyScope == null || owner != null; this.owner = owner; @@ -94,13 +133,18 @@ public class Scope { this.elems = null; this.nelems = 0; this.shared = 0; + this.scopeCounter = scopeCounter; } /** Construct a new scope, within scope next, with given owner, * using a fresh table of length INITIAL_SIZE. */ public Scope(Symbol owner) { - this(null, owner, new Entry[INITIAL_SIZE]); + this(owner, dummyCounter); + } + + protected Scope(Symbol owner, ScopeCounter scopeCounter) { + this(null, owner, new Entry[INITIAL_SIZE], scopeCounter); for (int i = 0; i < INITIAL_SIZE; i++) table[i] = sentinel; } @@ -110,7 +154,7 @@ public class Scope { * of fresh tables. */ public Scope dup() { - Scope result = new Scope(this, this.owner, this.table); + Scope result = new Scope(this, this.owner, this.table, scopeCounter); shared++; // System.out.println("====> duping scope " + this.hashCode() + " owned by " + this.owner + " to " + result.hashCode()); // new Error().printStackTrace(System.out); @@ -123,7 +167,7 @@ public class Scope { * of fresh tables. */ public Scope dup(Symbol newOwner) { - Scope result = new Scope(this, newOwner, this.table); + Scope result = new Scope(this, newOwner, this.table, scopeCounter); shared++; // System.out.println("====> duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode()); // new Error().printStackTrace(System.out); @@ -135,7 +179,7 @@ public class Scope { * the table of its outer scope. */ public Scope dupUnshared() { - return new Scope(this, this.owner, this.table.clone()); + return new Scope(this, this.owner, this.table.clone(), scopeCounter); } /** Remove all entries of this scope from its table, if shared @@ -211,6 +255,7 @@ public class Scope { table[hash] = e; elems = e; nelems++; + scopeCounter.inc(); } Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) { @@ -226,6 +271,8 @@ public class Scope { while (e.scope == this && e.sym != sym) e = e.next(); if (e.scope == null) return; + scopeCounter.inc(); + // remove e from table and shadowed list; Entry te = table[sym.name.hashCode() & hashMask]; if (te == e) @@ -472,7 +519,7 @@ public class Scope { public static final Entry[] emptyTable = new Entry[0]; public DelegatedScope(Scope outer) { - super(outer, outer.owner, emptyTable); + super(outer, outer.owner, emptyTable, outer.scopeCounter); delegatee = outer; } public Scope dup() { @@ -498,10 +545,22 @@ public class Scope { } } + /** A class scope, for which a scope counter should be provided */ + public static class ClassScope extends Scope { + + ClassScope(Scope next, Symbol owner, Entry[] table, ScopeCounter scopeCounter) { + super(next, owner, table, scopeCounter); + } + + public ClassScope(Symbol owner, ScopeCounter scopeCounter) { + super(owner, scopeCounter); + } + } + /** An error scope, for which the owner should be an error symbol. */ public static class ErrorScope extends Scope { ErrorScope(Scope next, Symbol errSymbol, Entry[] table) { - super(next, /*owner=*/errSymbol, table); + super(next, /*owner=*/errSymbol, table, dummyCounter); } public ErrorScope(Symbol errSymbol) { super(errSymbol); diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java index 58fa9a7694a..3a21ce72135 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java @@ -25,11 +25,14 @@ package com.sun.tools.javac.code; -import com.sun.tools.javac.util.*; -import com.sun.tools.javac.jvm.Target; +import java.util.*; import javax.lang.model.SourceVersion; import static javax.lang.model.SourceVersion.*; -import java.util.*; + +import com.sun.tools.javac.util.*; +import com.sun.tools.javac.jvm.Target; + +import static com.sun.tools.javac.main.OptionName.*; /** The source language version accepted. * @@ -71,7 +74,7 @@ public enum Source { Source instance = context.get(sourceKey); if (instance == null) { Options options = Options.instance(context); - String sourceString = options.get("-source"); + String sourceString = options.get(SOURCE); if (sourceString != null) instance = lookup(sourceString); if (instance == null) instance = DEFAULT; context.put(sourceKey, instance); diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java index 5e0838fb63d..afce2e30723 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -960,6 +960,8 @@ public abstract class Symbol implements Element { return ElementKind.ENUM_CONSTANT; } else if (owner.kind == TYP || owner.kind == ERR) { return ElementKind.FIELD; + } else if (isResourceVariable()) { + return ElementKind.RESOURCE_VARIABLE; } else { return ElementKind.LOCAL_VARIABLE; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java index 0093deef593..3927c4c233f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java @@ -74,6 +74,7 @@ public class Symtab { public final JCNoType voidType = new JCNoType(TypeTags.VOID); private final Names names; + private final Scope.ScopeCounter scopeCounter; private final ClassReader reader; private final Target target; @@ -340,6 +341,7 @@ public class Symtab { context.put(symtabKey, this); names = Names.instance(context); + scopeCounter = Scope.ScopeCounter.instance(context); target = Target.instance(context); // Create the unknown type @@ -386,7 +388,7 @@ public class Symtab { // Create class to hold all predefined constants and operations. predefClass = new ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage); - Scope scope = new Scope(predefClass); + Scope scope = new Scope.ClassScope(predefClass, scopeCounter); predefClass.members_field = scope; // Enter symbols for basic types. @@ -476,7 +478,7 @@ public class Symtab { proprietarySymbol.completer = null; proprietarySymbol.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE; proprietarySymbol.erasure_field = proprietaryType; - proprietarySymbol.members_field = new Scope(proprietarySymbol); + proprietarySymbol.members_field = new Scope.ClassScope(proprietarySymbol, scopeCounter); proprietaryType.typarams_field = List.nil(); proprietaryType.allparams_field = List.nil(); proprietaryType.supertype_field = annotationType; @@ -488,7 +490,7 @@ public class Symtab { ClassType arrayClassType = (ClassType)arrayClass.type; arrayClassType.supertype_field = objectType; arrayClassType.interfaces_field = List.of(cloneableType, serializableType); - arrayClass.members_field = new Scope(arrayClass); + arrayClass.members_field = new Scope.ClassScope(arrayClass, scopeCounter); lengthVar = new VarSymbol( PUBLIC | FINAL, names.length, diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 0b8b27b5c86..f6fd8fd721e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -69,6 +69,7 @@ public class Types { new Context.Key(); final Symtab syms; + final Scope.ScopeCounter scopeCounter; final JavacMessages messages; final Names names; final boolean allowBoxing; @@ -89,6 +90,7 @@ public class Types { protected Types(Context context) { context.put(typesKey, this); syms = Symtab.instance(context); + scopeCounter = Scope.ScopeCounter.instance(context); names = Names.instance(context); allowBoxing = Source.instance(context).allowBoxing(); reader = ClassReader.instance(context); @@ -1984,22 +1986,26 @@ public class Types { final MethodSymbol cachedImpl; final Filter implFilter; final boolean checkResult; + final Scope.ScopeCounter scopeCounter; public Entry(MethodSymbol cachedImpl, Filter scopeFilter, - boolean checkResult) { + boolean checkResult, + Scope.ScopeCounter scopeCounter) { this.cachedImpl = cachedImpl; this.implFilter = scopeFilter; this.checkResult = checkResult; + this.scopeCounter = scopeCounter; } - boolean matches(Filter scopeFilter, boolean checkResult) { + boolean matches(Filter scopeFilter, boolean checkResult, Scope.ScopeCounter scopeCounter) { return this.implFilter == scopeFilter && - this.checkResult == checkResult; + this.checkResult == checkResult && + this.scopeCounter.val() >= scopeCounter.val(); } } - MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter implFilter) { + MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter implFilter, Scope.ScopeCounter scopeCounter) { SoftReference> ref_cache = _map.get(ms); Map cache = ref_cache != null ? ref_cache.get() : null; if (cache == null) { @@ -2008,9 +2014,9 @@ public class Types { } Entry e = cache.get(origin); if (e == null || - !e.matches(implFilter, checkResult)) { + !e.matches(implFilter, checkResult, scopeCounter)) { MethodSymbol impl = implementationInternal(ms, origin, Types.this, checkResult, implFilter); - cache.put(origin, new Entry(impl, implFilter, checkResult)); + cache.put(origin, new Entry(impl, implFilter, checkResult, scopeCounter)); return impl; } else { @@ -2038,7 +2044,7 @@ public class Types { private ImplementationCache implCache = new ImplementationCache(); public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult, Filter implFilter) { - return implCache.get(ms, origin, checkResult, implFilter); + return implCache.get(ms, origin, checkResult, implFilter, scopeCounter); } // diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 69f7934537b..7e80d2693cb 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -119,10 +119,10 @@ public class Attr extends JCTree.Visitor { allowAnonOuterThis = source.allowAnonOuterThis(); allowStringsInSwitch = source.allowStringsInSwitch(); sourceName = source.name; - relax = (options.get("-retrofit") != null || - options.get("-relax") != null); - useBeforeDeclarationWarning = options.get("useBeforeDeclarationWarning") != null; - enableSunApiLintControl = options.get("enableSunApiLintControl") != null; + relax = (options.isSet("-retrofit") || + options.isSet("-relax")); + useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning"); + enableSunApiLintControl = options.isSet("enableSunApiLintControl"); } /** Switch: relax some constraints for retrofit mode. @@ -1422,7 +1422,8 @@ public class Attr extends JCTree.Visitor { // Compute the result type. Type restype = mtype.getReturnType(); - assert restype.tag != WILDCARD : mtype; + if (restype.tag == WILDCARD) + throw new AssertionError(mtype); // as a special case, array.clone() has a result that is // the same as static type of the array being cloned diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 9f46e32b648..07d95cc5c1e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -25,7 +25,6 @@ package com.sun.tools.javac.comp; -import com.sun.source.tree.AssignmentTree; import java.util.*; import java.util.Set; @@ -46,6 +45,8 @@ import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTags.*; +import static com.sun.tools.javac.main.OptionName.*; + /** Type checking helper class for the attribution phase. * *

This is NOT part of any supported API. @@ -60,6 +61,7 @@ public class Check { private final Names names; private final Log log; private final Symtab syms; + private final Enter enter; private final Infer infer; private final Types types; private final JCDiagnostic.Factory diags; @@ -86,6 +88,7 @@ public class Check { names = Names.instance(context); log = Log.instance(context); syms = Symtab.instance(context); + enter = Enter.instance(context); infer = Infer.instance(context); this.types = Types.instance(context); diags = JCDiagnostic.Factory.instance(context); @@ -97,10 +100,10 @@ public class Check { allowGenerics = source.allowGenerics(); allowAnnotations = source.allowAnnotations(); allowCovariantReturns = source.allowCovariantReturns(); - complexInference = options.get("-complexinference") != null; - skipAnnotations = options.get("skipAnnotations") != null; - warnOnSyntheticConflicts = options.get("warnOnSyntheticConflicts") != null; - suppressAbortOnBadClassFile = options.get("suppressAbortOnBadClassFile") != null; + complexInference = options.isSet(COMPLEXINFERENCE); + skipAnnotations = options.isSet("skipAnnotations"); + warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts"); + suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile"); Target target = Target.instance(context); syntheticNameChar = target.syntheticNameChar(); @@ -1727,6 +1730,113 @@ public class Check { return undef; } + void checkNonCyclicDecl(JCClassDecl tree) { + CycleChecker cc = new CycleChecker(); + cc.scan(tree); + if (!cc.errorFound && !cc.partialCheck) { + tree.sym.flags_field |= ACYCLIC; + } + } + + class CycleChecker extends TreeScanner { + + List seenClasses = List.nil(); + boolean errorFound = false; + boolean partialCheck = false; + + private void checkSymbol(DiagnosticPosition pos, Symbol sym) { + if (sym != null && sym.kind == TYP) { + Env classEnv = enter.getEnv((TypeSymbol)sym); + if (classEnv != null) { + DiagnosticSource prevSource = log.currentSource(); + try { + log.useSource(classEnv.toplevel.sourcefile); + scan(classEnv.tree); + } + finally { + log.useSource(prevSource.getFile()); + } + } else if (sym.kind == TYP) { + checkClass(pos, sym, List.nil()); + } + } else { + //not completed yet + partialCheck = true; + } + } + + @Override + public void visitSelect(JCFieldAccess tree) { + super.visitSelect(tree); + checkSymbol(tree.pos(), tree.sym); + } + + @Override + public void visitIdent(JCIdent tree) { + checkSymbol(tree.pos(), tree.sym); + } + + @Override + public void visitTypeApply(JCTypeApply tree) { + scan(tree.clazz); + } + + @Override + public void visitTypeArray(JCArrayTypeTree tree) { + scan(tree.elemtype); + } + + @Override + public void visitClassDef(JCClassDecl tree) { + List supertypes = List.nil(); + if (tree.getExtendsClause() != null) { + supertypes = supertypes.prepend(tree.getExtendsClause()); + } + if (tree.getImplementsClause() != null) { + for (JCTree intf : tree.getImplementsClause()) { + supertypes = supertypes.prepend(intf); + } + } + checkClass(tree.pos(), tree.sym, supertypes); + } + + void checkClass(DiagnosticPosition pos, Symbol c, List supertypes) { + if ((c.flags_field & ACYCLIC) != 0) + return; + if (seenClasses.contains(c)) { + errorFound = true; + noteCyclic(pos, (ClassSymbol)c); + } else if (!c.type.isErroneous()) { + try { + seenClasses = seenClasses.prepend(c); + if (c.type.tag == CLASS) { + if (supertypes.nonEmpty()) { + scan(supertypes); + } + else { + ClassType ct = (ClassType)c.type; + if (ct.supertype_field == null || + ct.interfaces_field == null) { + //not completed yet + partialCheck = true; + return; + } + checkSymbol(pos, ct.supertype_field.tsym); + for (Type intf : ct.interfaces_field) { + checkSymbol(pos, intf.tsym); + } + } + if (c.owner.kind == TYP) { + checkSymbol(pos, c.owner); + } + } + } finally { + seenClasses = seenClasses.tail; + } + } + } + } + /** Check for cyclic references. Issue an error if the * symbol of the type referred to has a LOCKED flag set. * diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java index e8f26e6ae15..b29e0dcc673 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java @@ -94,6 +94,7 @@ public class Enter extends JCTree.Visitor { Log log; Symtab syms; + Scope.ScopeCounter scopeCounter; Check chk; TreeMaker make; ClassReader reader; @@ -121,6 +122,7 @@ public class Enter extends JCTree.Visitor { reader = ClassReader.instance(context); make = TreeMaker.instance(context); syms = Symtab.instance(context); + scopeCounter = Scope.ScopeCounter.instance(context); chk = Check.instance(context); memberEnter = MemberEnter.instance(context); types = Types.instance(context); @@ -189,7 +191,7 @@ public class Enter extends JCTree.Visitor { */ public Env classEnv(JCClassDecl tree, Env env) { Env localEnv = - env.dup(tree, env.info.dup(new Scope(tree.sym))); + env.dup(tree, env.info.dup(new Scope.ClassScope(tree.sym, scopeCounter))); localEnv.enclClass = tree; localEnv.outer = env; localEnv.info.isSelfCall = false; @@ -325,7 +327,7 @@ public class Enter extends JCTree.Visitor { c.flatname = names.fromString(tree.packge + "." + name); c.sourcefile = tree.sourcefile; c.completer = null; - c.members_field = new Scope(c); + c.members_field = new Scope.ClassScope(c, scopeCounter); tree.packge.package_info = c; } classEnter(tree.defs, topEnv); @@ -393,7 +395,7 @@ public class Enter extends JCTree.Visitor { c.completer = memberEnter; c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree); c.sourcefile = env.toplevel.sourcefile; - c.members_field = new Scope(c); + c.members_field = new Scope.ClassScope(c, scopeCounter); ClassType ct = (ClassType)c.type; if (owner.kind != PCK && (c.flags_field & STATIC) == 0) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java index 8eb0c46606a..b7d28fdaa6f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -80,25 +80,12 @@ public class Infer { } - public static class InferenceException extends RuntimeException { + public static class InferenceException extends Resolve.InapplicableMethodException { private static final long serialVersionUID = 0; - JCDiagnostic diagnostic; - JCDiagnostic.Factory diags; - InferenceException(JCDiagnostic.Factory diags) { - this.diagnostic = null; - this.diags = diags; + super(diags); } - - InferenceException setMessage(String key, Object... args) { - this.diagnostic = diags.fragment(key, args); - return this; - } - - public JCDiagnostic getDiagnostic() { - return diagnostic; - } } public static class NoInstanceException extends InferenceException { @@ -320,7 +307,7 @@ public class Infer { Type qtype1 = types.subst(that.qtype, that.tvars, undetvars); if (!types.isSubtype(qtype1, to)) { throw unambiguousNoInstanceException - .setMessage("no.conforming.instance.exists", + .setMessage("infer.no.conforming.instance.exists", that.tvars, that.qtype, to); } for (List l = undetvars; l.nonEmpty(); l = l.tail) @@ -378,6 +365,11 @@ public class Infer { // instantiate all polymorphic argument types and // set up lower bounds constraints for undetvars Type varargsFormal = useVarargs ? formals.last() : null; + if (varargsFormal == null && + actuals.size() != formals.size()) { + throw unambiguousNoInstanceException + .setMessage("infer.arg.length.mismatch"); + } while (actuals.nonEmpty() && formals.head != varargsFormal) { Type formal = formals.head; Type actual = actuals.head.baseType(); @@ -390,19 +382,16 @@ public class Infer { : types.isSubtypeUnchecked(actual, undetFormal, warn); if (!works) { throw unambiguousNoInstanceException - .setMessage("no.conforming.assignment.exists", + .setMessage("infer.no.conforming.assignment.exists", tvars, actualNoCapture, formal); } formals = formals.tail; actuals = actuals.tail; actualsNoCapture = actualsNoCapture.tail; } - if (formals.head != varargsFormal || // not enough args - !useVarargs && actuals.nonEmpty()) { // too many args - // argument lists differ in length - throw unambiguousNoInstanceException - .setMessage("arg.length.mismatch"); - } + + if (formals.head != varargsFormal) // not enough args + throw unambiguousNoInstanceException.setMessage("infer.arg.length.mismatch"); // for varargs arguments as well if (useVarargs) { @@ -416,7 +405,7 @@ public class Infer { boolean works = types.isConvertible(actual, elemUndet, warn); if (!works) { throw unambiguousNoInstanceException - .setMessage("no.conforming.assignment.exists", + .setMessage("infer.no.conforming.assignment.exists", tvars, actualNoCapture, elemType); } actuals = actuals.tail; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index c7ffb485946..9498781064e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -68,6 +68,7 @@ public class Lower extends TreeTranslator { private Names names; private Log log; private Symtab syms; + private Scope.ScopeCounter scopeCounter; private Resolve rs; private Check chk; private Attr attr; @@ -90,6 +91,7 @@ public class Lower extends TreeTranslator { names = Names.instance(context); log = Log.instance(context); syms = Symtab.instance(context); + scopeCounter = Scope.ScopeCounter.instance(context); rs = Resolve.instance(context); chk = Check.instance(context); attr = Attr.instance(context); @@ -107,7 +109,7 @@ public class Lower extends TreeTranslator { types = Types.instance(context); Options options = Options.instance(context); - debugLower = options.get("debuglower") != null; + debugLower = options.isSet("debuglower"); pkginfoOpt = PkgInfo.get(options); } @@ -569,7 +571,7 @@ public class Lower extends TreeTranslator { c.flatname = chk.localClassName(c); c.sourcefile = owner.sourcefile; c.completer = null; - c.members_field = new Scope(c); + c.members_field = new Scope.ClassScope(c, scopeCounter); c.flags_field = flags; ClassType ctype = (ClassType) c.type; ctype.supertype_field = syms.objectType; @@ -2677,7 +2679,8 @@ public class Lower extends TreeTranslator { } //where private JCTree convert(JCTree tree, Type pt) { - if (tree.type == pt) return tree; + if (tree.type == pt || tree.type.tag == TypeTags.BOT) + return tree; JCTree result = make_at(tree.pos()).TypeCast(make.Type(pt), (JCExpression)tree); result.type = (tree.type.constValue() != null) ? cfolder.coerce(tree.type, pt) : pt; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index 8740dce1ab7..73fe36cbf7d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -67,6 +67,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { private final Check chk; private final Attr attr; private final Symtab syms; + private final Scope.ScopeCounter scopeCounter; private final TreeMaker make; private final ClassReader reader; private final Todo todo; @@ -92,6 +93,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { chk = Check.instance(context); attr = Attr.instance(context); syms = Symtab.instance(context); + scopeCounter = Scope.ScopeCounter.instance(context); make = TreeMaker.instance(context); reader = ClassReader.instance(context); todo = Todo.instance(context); @@ -100,7 +102,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { diags = JCDiagnostic.Factory.instance(context); target = Target.instance(context); Options options = Options.instance(context); - skipAnnotations = options.get("skipAnnotations") != null; + skipAnnotations = options.isSet("skipAnnotations"); } /** A queue for classes whose members still need to be entered into the @@ -925,7 +927,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { tp.accept(new TypeAnnotate(baseEnv)); tree.accept(new TypeAnnotate(env)); - chk.checkNonCyclic(tree.pos(), c.type); + chk.checkNonCyclicDecl(tree); attr.attribTypeVariables(tree.typarams, baseEnv); @@ -1087,7 +1089,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { private Env baseEnv(JCClassDecl tree, Env env) { - Scope baseScope = new Scope(tree.sym); + Scope baseScope = new Scope.ClassScope(tree.sym, scopeCounter); //import already entered local classes into base scope for (Scope.Entry e = env.outer.info.scope.elems ; e != null ; e = e.sibling) { if (e.sym.isLocal()) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index d2920e9ec1b..85d8161dac6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -110,15 +110,17 @@ public class Resolve { boxingEnabled = source.allowBoxing(); varargsEnabled = source.allowVarargs(); Options options = Options.instance(context); - debugResolve = options.get("debugresolve") != null; - allowTransitionalJSR292 = options.get("allowTransitionalJSR292") != null; + debugResolve = options.isSet("debugresolve"); + allowTransitionalJSR292 = options.isSet("allowTransitionalJSR292"); Target target = Target.instance(context); allowMethodHandles = allowTransitionalJSR292 || target.hasMethodHandles(); allowInvokeDynamic = (allowTransitionalJSR292 || target.hasInvokedynamic()) && - options.get("invokedynamic") != null; + options.isSet("invokedynamic"); polymorphicSignatureScope = new Scope(syms.noSymbol); + + inapplicableMethodException = new InapplicableMethodException(diags); } /** error symbols, which are returned when resolution fails @@ -318,7 +320,8 @@ public class Resolve { throws Infer.InferenceException { boolean polymorphicSignature = (m.isPolymorphicSignatureGeneric() && allowMethodHandles) || isTransitionalDynamicCallSite(site, m); - if (useVarargs && (m.flags() & VARARGS) == 0) return null; + if (useVarargs && (m.flags() & VARARGS) == 0) + throw inapplicableMethodException.setMessage(null); Type mt = types.memberType(site, m); // tvars is the list of formal type variables for which type arguments @@ -334,7 +337,7 @@ public class Resolve { } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) { ForAll pmt = (ForAll) mt; if (typeargtypes.length() != pmt.tvars.length()) - return null; + throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args // Check type arguments are within bounds List formals = pmt.tvars; List actuals = typeargtypes; @@ -343,7 +346,7 @@ public class Resolve { pmt.tvars, typeargtypes); for (; bounds.nonEmpty(); bounds = bounds.tail) if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn)) - return null; + throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds); formals = formals.tail; actuals = actuals.tail; } @@ -375,11 +378,10 @@ public class Resolve { allowBoxing, useVarargs, warn); - return - argumentsAcceptable(argtypes, mt.getParameterTypes(), - allowBoxing, useVarargs, warn) - ? mt - : null; + + checkRawArgumentsAcceptable(argtypes, mt.getParameterTypes(), + allowBoxing, useVarargs, warn); + return mt; } boolean isTransitionalDynamicCallSite(Type site, Symbol sym) { @@ -403,7 +405,7 @@ public class Resolve { try { return rawInstantiate(env, site, m, argtypes, typeargtypes, allowBoxing, useVarargs, warn); - } catch (Infer.InferenceException ex) { + } catch (InapplicableMethodException ex) { return null; } } @@ -415,26 +417,76 @@ public class Resolve { boolean allowBoxing, boolean useVarargs, Warner warn) { + try { + checkRawArgumentsAcceptable(argtypes, formals, allowBoxing, useVarargs, warn); + return true; + } catch (InapplicableMethodException ex) { + return false; + } + } + void checkRawArgumentsAcceptable(List argtypes, + List formals, + boolean allowBoxing, + boolean useVarargs, + Warner warn) { Type varargsFormal = useVarargs ? formals.last() : null; + if (varargsFormal == null && + argtypes.size() != formals.size()) { + throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args + } + while (argtypes.nonEmpty() && formals.head != varargsFormal) { boolean works = allowBoxing ? types.isConvertible(argtypes.head, formals.head, warn) : types.isSubtypeUnchecked(argtypes.head, formals.head, warn); - if (!works) return false; + if (!works) + throw inapplicableMethodException.setMessage("no.conforming.assignment.exists", + argtypes.head, + formals.head); argtypes = argtypes.tail; formals = formals.tail; } - if (formals.head != varargsFormal) return false; // not enough args - if (!useVarargs) - return argtypes.isEmpty(); - Type elt = types.elemtype(varargsFormal); - while (argtypes.nonEmpty()) { - if (!types.isConvertible(argtypes.head, elt, warn)) - return false; - argtypes = argtypes.tail; + + if (formals.head != varargsFormal) + throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args + + if (useVarargs) { + Type elt = types.elemtype(varargsFormal); + while (argtypes.nonEmpty()) { + if (!types.isConvertible(argtypes.head, elt, warn)) + throw inapplicableMethodException.setMessage("varargs.argument.mismatch", + argtypes.head, + elt); + argtypes = argtypes.tail; + } } - return true; + return; } + // where + public static class InapplicableMethodException extends RuntimeException { + private static final long serialVersionUID = 0; + + JCDiagnostic diagnostic; + JCDiagnostic.Factory diags; + + InapplicableMethodException(JCDiagnostic.Factory diags) { + this.diagnostic = null; + this.diags = diags; + } + InapplicableMethodException setMessage(String key) { + this.diagnostic = key != null ? diags.fragment(key) : null; + return this; + } + InapplicableMethodException setMessage(String key, Object... args) { + this.diagnostic = key != null ? diags.fragment(key, args) : null; + return this; + } + + public JCDiagnostic getDiagnostic() { + return diagnostic; + } + } + private final InapplicableMethodException inapplicableMethodException; /* *************************************************************************** * Symbol lookup @@ -595,6 +647,7 @@ public class Resolve { * @param allowBoxing Allow boxing conversions of arguments. * @param useVarargs Box trailing arguments into an array for varargs. */ + @SuppressWarnings("fallthrough") Symbol selectBest(Env env, Type site, List argtypes, @@ -608,21 +661,16 @@ public class Resolve { if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar; assert sym.kind < AMBIGUOUS; try { - if (rawInstantiate(env, site, sym, argtypes, typeargtypes, - allowBoxing, useVarargs, Warner.noWarnings) == null) { - // inapplicable - switch (bestSoFar.kind) { - case ABSENT_MTH: return wrongMethod.setWrongSym(sym); - case WRONG_MTH: return wrongMethods; - default: return bestSoFar; - } - } - } catch (Infer.InferenceException ex) { + rawInstantiate(env, site, sym, argtypes, typeargtypes, + allowBoxing, useVarargs, Warner.noWarnings); + } catch (InapplicableMethodException ex) { switch (bestSoFar.kind) { case ABSENT_MTH: return wrongMethod.setWrongSym(sym, ex.getDiagnostic()); case WRONG_MTH: - return wrongMethods; + wrongMethods.addCandidate(currentStep, wrongMethod.sym, wrongMethod.explanation); + case WRONG_MTHS: + return wrongMethods.addCandidate(currentStep, sym, ex.getDiagnostic()); default: return bestSoFar; } @@ -631,7 +679,7 @@ public class Resolve { return (bestSoFar.kind == ABSENT_MTH) ? new AccessError(env, site, sym) : bestSoFar; - } + } return (bestSoFar.kind > AMBIGUOUS) ? sym : mostSpecific(sym, bestSoFar, env, site, @@ -1253,11 +1301,12 @@ public class Resolve { Name name, List argtypes, List typeargtypes) { - Symbol sym = methodNotFound; + Symbol sym = startResolution(); List steps = methodResolutionSteps; while (steps.nonEmpty() && steps.head.isApplicable(boxingEnabled, varargsEnabled) && sym.kind >= ERRONEOUS) { + currentStep = steps.head; sym = findFun(env, name, argtypes, typeargtypes, steps.head.isBoxingRequired, env.info.varArgs = steps.head.isVarargsRequired); @@ -1274,6 +1323,12 @@ public class Resolve { return sym; } + private Symbol startResolution() { + wrongMethod.clear(); + wrongMethods.clear(); + return methodNotFound; + } + /** Resolve a qualified method identifier * @param pos The position to use for error reporting. * @param env The environment current at the method invocation. @@ -1286,11 +1341,12 @@ public class Resolve { Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env env, Type site, Name name, List argtypes, List typeargtypes) { - Symbol sym = methodNotFound; + Symbol sym = startResolution(); List steps = methodResolutionSteps; while (steps.nonEmpty() && steps.head.isApplicable(boxingEnabled, varargsEnabled) && sym.kind >= ERRONEOUS) { + currentStep = steps.head; sym = findMethod(env, site, name, argtypes, typeargtypes, steps.head.isBoxingRequired(), env.info.varArgs = steps.head.isVarargsRequired(), false); @@ -1404,11 +1460,12 @@ public class Resolve { Type site, List argtypes, List typeargtypes) { - Symbol sym = methodNotFound; + Symbol sym = startResolution(); List steps = methodResolutionSteps; while (steps.nonEmpty() && steps.head.isApplicable(boxingEnabled, varargsEnabled) && sym.kind >= ERRONEOUS) { + currentStep = steps.head; sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, steps.head.isBoxingRequired(), env.info.varArgs = steps.head.isVarargsRequired()); @@ -1439,26 +1496,22 @@ public class Resolve { Type site, List argtypes, List typeargtypes) { - Symbol sym = methodNotFound; - JCDiagnostic explanation = null; + Symbol sym = startResolution(); List steps = methodResolutionSteps; while (steps.nonEmpty() && steps.head.isApplicable(boxingEnabled, varargsEnabled) && sym.kind >= ERRONEOUS) { + currentStep = steps.head; sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, steps.head.isBoxingRequired(), env.info.varArgs = steps.head.isVarargsRequired()); methodResolutionCache.put(steps.head, sym); - if (sym.kind == WRONG_MTH && - ((InapplicableSymbolError)sym).explanation != null) { - //if the symbol is an inapplicable method symbol, then the - //explanation contains the reason for which inference failed - explanation = ((InapplicableSymbolError)sym).explanation; - } steps = steps.tail; } if (sym.kind >= AMBIGUOUS) { - final JCDiagnostic details = explanation; + final JCDiagnostic details = sym.kind == WRONG_MTH ? + ((InapplicableSymbolError)sym).explanation : + null; Symbol errSym = new ResolveError(WRONG_MTH, "diamond error") { @Override JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Type site, Name name, List argtypes, List typeargtypes) { @@ -1860,7 +1913,8 @@ public class Resolve { */ InapplicableSymbolError setWrongSym(Symbol sym, JCDiagnostic explanation) { this.sym = sym; - this.explanation = explanation; + if (this.sym == sym && explanation != null) + this.explanation = explanation; //update the details return this; } @@ -1868,7 +1922,6 @@ public class Resolve { */ InapplicableSymbolError setWrongSym(Symbol sym) { this.sym = sym; - this.explanation = null; return this; } @@ -1905,6 +1958,10 @@ public class Resolve { } } + void clear() { + explanation = null; + } + @Override public Symbol access(Name name, TypeSymbol location) { return types.createErrorType(name, location, syms.errSymbol.type).tsym; @@ -1917,6 +1974,9 @@ public class Resolve { * given an actual arguments/type argument list. */ class InapplicableSymbolsError extends ResolveError { + + private List candidates = List.nil(); + InapplicableSymbolsError(Symbol sym) { super(WRONG_MTHS, "inapplicable symbols"); } @@ -1928,8 +1988,85 @@ public class Resolve { Name name, List argtypes, List typeargtypes) { - return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos, + if (candidates.nonEmpty()) { + JCDiagnostic err = diags.create(dkind, + log.currentSource(), + pos, + "cant.apply.symbols", + name == names.init ? KindName.CONSTRUCTOR : absentKind(kind), + getName(), + argtypes); + return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site)); + } else { + return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos, site, name, argtypes, typeargtypes); + } + } + + //where + List candidateDetails(Type site) { + List details = List.nil(); + for (Candidate c : candidates) + details = details.prepend(c.getDiagnostic(site)); + return details.reverse(); + } + + Symbol addCandidate(MethodResolutionPhase currentStep, Symbol sym, JCDiagnostic details) { + Candidate c = new Candidate(currentStep, sym, details); + if (c.isValid() && !candidates.contains(c)) + candidates = candidates.append(c); + return this; + } + + void clear() { + candidates = List.nil(); + } + + private Name getName() { + Symbol sym = candidates.head.sym; + return sym.name == names.init ? + sym.owner.name : + sym.name; + } + + private class Candidate { + + final MethodResolutionPhase step; + final Symbol sym; + final JCDiagnostic details; + + private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details) { + this.step = step; + this.sym = sym; + this.details = details; + } + + JCDiagnostic getDiagnostic(Type site) { + return diags.fragment("inapplicable.method", + Kinds.kindName(sym), + sym.location(site, types), + sym.asMemberOf(site, types), + details); + } + + @Override + public boolean equals(Object o) { + if (o instanceof Candidate) { + Symbol s1 = this.sym; + Symbol s2 = ((Candidate)o).sym; + if ((s1 != s2 && + (s1.overrides(s2, s1.owner.type.tsym, types, false) || + (s2.overrides(s1, s2.owner.type.tsym, types, false)))) || + ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner)) + return true; + } + return false; + } + + boolean isValid() { + return (((sym.flags() & VARARGS) != 0 && step == VARARITY) || + (sym.flags() & VARARGS) == 0 && step == (boxingEnabled ? BOX : BASIC)); + } } } @@ -2093,6 +2230,8 @@ public class Resolve { final List methodResolutionSteps = List.of(BASIC, BOX, VARARITY); + private MethodResolutionPhase currentStep = null; + private MethodResolutionPhase firstErroneousResolutionPhase() { MethodResolutionPhase bestSoFar = BASIC; Symbol sym = methodNotFound; diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java index 77ea25edf59..5fec67baecc 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2009, 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. * * This code is free software; you can redistribute it and/or modify it @@ -150,8 +150,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil useZipFileIndex = System.getProperty("useJavaUtilZip") == null;// TODO: options.get("useJavaUtilZip") == null; - mmappedIO = options.get("mmappedIO") != null; - ignoreSymbolFile = options.get("ignore.symbol.file") != null; + mmappedIO = options.isSet("mmappedIO"); + ignoreSymbolFile = options.isSet("ignore.symbol.file"); } public JavaFileObject getFileForInput(String name) { @@ -435,7 +435,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil zdir = new ZipFile(zipFileName); } else { - usePreindexedCache = options.get("usezipindex") != null; + usePreindexedCache = options.isSet("usezipindex"); preindexCacheLocation = options.get("java.io.tmpdir"); String optCacheLoc = options.get("cachezipindexdir"); @@ -469,7 +469,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil null, usePreindexedCache, preindexCacheLocation, - options.get("writezipindexfiles") != null)); + options.isSet("writezipindexfiles"))); } } else { @@ -482,7 +482,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil symbolFilePrefix, usePreindexedCache, preindexCacheLocation, - options.get("writezipindexfiles") != null)); + options.isSet("writezipindexfiles"))); } } } catch (FileNotFoundException ex) { @@ -605,7 +605,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil nullCheck(className); nullCheck(kind); if (!sourceOrClass.contains(kind)) - throw new IllegalArgumentException("Invalid kind " + kind); + throw new IllegalArgumentException("Invalid kind: " + kind); return getFileForInput(location, RelativeFile.forClass(className, kind)); } @@ -658,7 +658,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil nullCheck(className); nullCheck(kind); if (!sourceOrClass.contains(kind)) - throw new IllegalArgumentException("Invalid kind " + kind); + throw new IllegalArgumentException("Invalid kind: " + kind); return getFileForOutput(location, RelativeFile.forClass(className, kind), sibling); } @@ -672,7 +672,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil // validatePackageName(packageName); nullCheck(packageName); if (!isRelativeUri(relativeName)) - throw new IllegalArgumentException("relativeName is invalid"); + throw new IllegalArgumentException("Invalid relative name: " + relativeName); RelativeFile name = packageName.length() == 0 ? new RelativeFile(relativeName) : new RelativeFile(RelativeDirectory.forPackage(packageName), relativeName); @@ -806,6 +806,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil String path = uri.normalize().getPath(); if (path.length() == 0 /* isEmpty() is mustang API */) return false; + if (!path.equals(uri.getPath())) // implicitly checks for embedded . and .. + return false; char first = path.charAt(0); return first != '.' && first != '/'; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index 5330c97185a..912d0dbf293 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -56,6 +56,8 @@ import static com.sun.tools.javac.code.TypeTags.*; import static com.sun.tools.javac.jvm.ClassFile.*; import static com.sun.tools.javac.jvm.ClassFile.Version.*; +import static com.sun.tools.javac.main.OptionName.*; + /** This class provides operations to read a classfile into an internal * representation. The internal representation is anchored in a * ClassSymbol which contains in its scope symbol representations @@ -122,6 +124,9 @@ public class ClassReader implements Completer { /** The symbol table. */ Symtab syms; + /** The scope counter */ + Scope.ScopeCounter scopeCounter; + Types types; /** The name table. */ @@ -244,6 +249,7 @@ public class ClassReader implements Completer { names = Names.instance(context); syms = Symtab.instance(context); + scopeCounter = Scope.ScopeCounter.instance(context); types = Types.instance(context); fileManager = context.get(JavaFileManager.class); if (fileManager == null) @@ -255,23 +261,23 @@ public class ClassReader implements Completer { Options options = Options.instance(context); annotate = Annotate.instance(context); - verbose = options.get("-verbose") != null; - checkClassFile = options.get("-checkclassfile") != null; + verbose = options.isSet(VERBOSE); + checkClassFile = options.isSet("-checkclassfile"); Source source = Source.instance(context); allowGenerics = source.allowGenerics(); allowVarargs = source.allowVarargs(); allowAnnotations = source.allowAnnotations(); - saveParameterNames = options.get("save-parameter-names") != null; - cacheCompletionFailure = options.get("dev") == null; + saveParameterNames = options.isSet("save-parameter-names"); + cacheCompletionFailure = options.isUnset("dev"); preferSource = "source".equals(options.get("-Xprefer")); completionFailureName = - (options.get("failcomplete") != null) + options.isSet("failcomplete") ? names.fromString(options.get("failcomplete")) : null; typevars = new Scope(syms.noSymbol); - debugJSR308 = options.get("TA:reader") != null; + debugJSR308 = options.isSet("TA:reader"); initAttributeReaders(); } @@ -1984,7 +1990,7 @@ public class ClassReader implements Completer { ClassType ct = (ClassType)c.type; // allocate scope for members - c.members_field = new Scope(c); + c.members_field = new Scope.ClassScope(c, scopeCounter); // prepare type variable table typevars = typevars.dup(currentOwner); diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java index a413b6fe1c7..08797b63e69 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java @@ -45,8 +45,10 @@ import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTags.*; import static com.sun.tools.javac.jvm.UninitializedType.*; +import static com.sun.tools.javac.main.OptionName.*; import static javax.tools.StandardLocation.CLASS_OUTPUT; + /** This class provides operations to map an internal symbol table graph * rooted in a ClassSymbol into a classfile. * @@ -178,15 +180,16 @@ public class ClassWriter extends ClassFile { types = Types.instance(context); fileManager = context.get(JavaFileManager.class); - debugJSR308 = options.get("TA:writer") != null; - verbose = options.get("-verbose") != null; - scramble = options.get("-scramble") != null; - scrambleAll = options.get("-scrambleAll") != null; - retrofit = options.get("-retrofit") != null; - genCrt = options.get("-Xjcov") != null; - debugstackmap = options.get("debugstackmap") != null; + debugJSR308 = options.isSet("TA:writer"); + verbose = options.isSet(VERBOSE); + scramble = options.isSet("-scramble"); + scrambleAll = options.isSet("-scrambleAll"); + retrofit = options.isSet("-retrofit"); + genCrt = options.isSet(XJCOV); + debugstackmap = options.isSet("debugstackmap"); - emitSourceFile = options.get("-g:")==null || options.get("-g:source")!=null; + emitSourceFile = options.isUnset(G_CUSTOM) || + options.isSet(G_CUSTOM, "source"); String dumpModFlags = options.get("dumpmodifiers"); dumpClassModifiers = diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java index 188793a453a..572380a49e1 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -46,6 +46,7 @@ import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTags.*; import static com.sun.tools.javac.jvm.ByteCodes.*; import static com.sun.tools.javac.jvm.CRTFlags.*; +import static com.sun.tools.javac.main.OptionName.*; /** This pass maps flat Java (i.e. without inner classes) to bytecodes. * @@ -113,19 +114,19 @@ public class Gen extends JCTree.Visitor { Options options = Options.instance(context); lineDebugInfo = - options.get("-g:") == null || - options.get("-g:lines") != null; + options.isUnset(G_CUSTOM) || + options.isSet(G_CUSTOM, "lines"); varDebugInfo = - options.get("-g:") == null - ? options.get("-g") != null - : options.get("-g:vars") != null; - genCrt = options.get("-Xjcov") != null; - debugCode = options.get("debugcode") != null; - allowInvokedynamic = target.hasInvokedynamic() || options.get("invokedynamic") != null; + options.isUnset(G_CUSTOM) + ? options.isSet(G) + : options.isSet(G_CUSTOM, "vars"); + genCrt = options.isSet(XJCOV); + debugCode = options.isSet("debugcode"); + allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic"); generateIproxies = target.requiresIproxy() || - options.get("miranda") != null; + options.isSet("miranda"); if (target.generateStackMapTable()) { // ignore cldc because we cannot have both stackmap formats diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java index 368c77d801c..9d09967b3da 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java @@ -31,6 +31,8 @@ import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.util.*; +import static com.sun.tools.javac.main.OptionName.*; + /** The classfile version target. * *

This is NOT part of any supported API. @@ -73,7 +75,7 @@ public enum Target { Target instance = context.get(targetKey); if (instance == null) { Options options = Options.instance(context); - String targetString = options.get("-target"); + String targetString = options.get(TARGET); if (targetString != null) instance = lookup(targetString); if (instance == null) instance = DEFAULT; context.put(targetKey, instance); diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 43740c83098..7e1996a45d9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -26,48 +26,44 @@ package com.sun.tools.javac.main; import java.io.*; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.MissingResourceException; +import java.util.Queue; import java.util.ResourceBundle; import java.util.Set; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; +import javax.annotation.processing.Processor; +import javax.lang.model.SourceVersion; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; import javax.tools.DiagnosticListener; -import com.sun.tools.javac.file.JavacFileManager; import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskListener; +import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.util.*; import com.sun.tools.javac.code.*; +import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.tree.*; +import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.parser.*; import com.sun.tools.javac.comp.*; import com.sun.tools.javac.jvm.*; - -import com.sun.tools.javac.code.Symbol.*; -import com.sun.tools.javac.tree.JCTree.*; - import com.sun.tools.javac.processing.*; -import javax.annotation.processing.Processor; import static javax.tools.StandardLocation.CLASS_OUTPUT; +import static com.sun.tools.javac.main.OptionName.*; import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*; import static com.sun.tools.javac.util.ListBuffer.lb; -// TEMP, until we have a more efficient way to save doc comment info -import com.sun.tools.javac.parser.DocCommentScanner; - -import java.util.HashMap; -import java.util.Queue; -import javax.lang.model.SourceVersion; /** This class could be the main entry point for GJC when GJC is used as a * component in a larger software system. It provides operations to @@ -359,22 +355,22 @@ public class JavaCompiler implements ClassReader.SourceCompleter { Options options = Options.instance(context); - verbose = options.get("-verbose") != null; - sourceOutput = options.get("-printsource") != null; // used to be -s - stubOutput = options.get("-stubs") != null; - relax = options.get("-relax") != null; - printFlat = options.get("-printflat") != null; - attrParseOnly = options.get("-attrparseonly") != null; - encoding = options.get("-encoding"); - lineDebugInfo = options.get("-g:") == null || - options.get("-g:lines") != null; - genEndPos = options.get("-Xjcov") != null || + verbose = options.isSet(VERBOSE); + sourceOutput = options.isSet(PRINTSOURCE); // used to be -s + stubOutput = options.isSet("-stubs"); + relax = options.isSet("-relax"); + printFlat = options.isSet("-printflat"); + attrParseOnly = options.isSet("-attrparseonly"); + encoding = options.get(ENCODING); + lineDebugInfo = options.isUnset(G_CUSTOM) || + options.isSet(G_CUSTOM, "lines"); + genEndPos = options.isSet(XJCOV) || context.get(DiagnosticListener.class) != null; - devVerbose = options.get("dev") != null; - processPcks = options.get("process.packages") != null; - werror = options.get("-Werror") != null; + devVerbose = options.isSet("dev"); + processPcks = options.isSet("process.packages"); + werror = options.isSet(WERROR); - verboseCompilePolicy = options.get("verboseCompilePolicy") != null; + verboseCompilePolicy = options.isSet("verboseCompilePolicy"); if (attrParseOnly) compilePolicy = CompilePolicy.ATTR_ONLY; @@ -384,15 +380,15 @@ public class JavaCompiler implements ClassReader.SourceCompleter { implicitSourcePolicy = ImplicitSourcePolicy.decode(options.get("-implicit")); completionFailureName = - (options.get("failcomplete") != null) + options.isSet("failcomplete") ? names.fromString(options.get("failcomplete")) : null; shouldStopPolicy = - (options.get("shouldStopPolicy") != null) + options.isSet("shouldStopPolicy") ? CompileState.valueOf(options.get("shouldStopPolicy")) : null; - if (options.get("oldDiags") == null) + if (options.isUnset("oldDiags")) log.setDiagnosticFormatter(RichDiagnosticFormatter.instance(context)); } @@ -957,18 +953,17 @@ public class JavaCompiler implements ClassReader.SourceCompleter { // Process annotations if processing is not disabled and there // is at least one Processor available. Options options = Options.instance(context); - if (options.get("-proc:none") != null) { + if (options.isSet(PROC, "none")) { processAnnotations = false; } else if (procEnvImpl == null) { procEnvImpl = new JavacProcessingEnvironment(context, processors); processAnnotations = procEnvImpl.atLeastOneProcessor(); if (processAnnotations) { - if (context.get(Scanner.Factory.scannerFactoryKey) == null) - DocCommentScanner.Factory.preRegister(context); options.put("save-parameter-names", "save-parameter-names"); reader.saveParameterNames = true; keepComments = true; + genEndPos = true; if (taskListener != null) taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING)); log.deferDiagnostics = true; @@ -1017,7 +1012,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter { // annotation processing is to occur with compilation, // emit a warning. Options options = Options.instance(context); - if (options.get("-proc:only") != null) { + if (options.isSet(PROC, "only")) { log.warning("proc.proc-only.requested.no.procs"); todo.clear(); } @@ -1105,10 +1100,10 @@ public class JavaCompiler implements ClassReader.SourceCompleter { Options options = Options.instance(context); return explicitAnnotationProcessingRequested || - options.get("-processor") != null || - options.get("-processorpath") != null || - options.get("-proc:only") != null || - options.get("-Xprint") != null; + options.isSet(PROCESSOR) || + options.isSet(PROCESSORPATH) || + options.isSet(PROC, "only") || + options.isSet(XPRINT); } /** @@ -1587,6 +1582,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter { } public void initRound(JavaCompiler prev) { + genEndPos = prev.genEndPos; keepComments = prev.keepComments; start_msec = prev.start_msec; hasBeenUsed = true; diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java index 2c89774790d..e5e53dc1ad3 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java @@ -32,6 +32,9 @@ import java.net.URL; import java.security.DigestInputStream; import java.security.MessageDigest; import java.util.MissingResourceException; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.annotation.processing.Processor; import com.sun.tools.javac.code.Source; import com.sun.tools.javac.file.CacheFSInfo; @@ -41,9 +44,8 @@ import com.sun.tools.javac.main.JavacOption.Option; import com.sun.tools.javac.main.RecognizedOptions.OptionHelper; import com.sun.tools.javac.util.*; import com.sun.tools.javac.processing.AnnotationProcessingError; -import javax.tools.JavaFileManager; -import javax.tools.JavaFileObject; -import javax.annotation.processing.Processor; + +import static com.sun.tools.javac.main.OptionName.*; /** This class provides a commandline interface to the GJC compiler. * @@ -239,16 +241,16 @@ public class Main { } } - if (!checkDirectory("-d")) + if (!checkDirectory(D)) return null; - if (!checkDirectory("-s")) + if (!checkDirectory(S)) return null; - String sourceString = options.get("-source"); + String sourceString = options.get(SOURCE); Source source = (sourceString != null) ? Source.lookup(sourceString) : Source.DEFAULT; - String targetString = options.get("-target"); + String targetString = options.get(TARGET); Target target = (targetString != null) ? Target.lookup(targetString) : Target.DEFAULT; @@ -285,7 +287,7 @@ public class Main { // phase this out with JSR 292 PFD if ("no".equals(options.get("allowTransitionalJSR292"))) { options.put("allowTransitionalJSR292", null); - } else if (target.hasInvokedynamic() && options.get("allowTransitionalJSR292") == null) { + } else if (target.hasInvokedynamic() && options.isUnset("allowTransitionalJSR292")) { options.put("allowTransitionalJSR292", "allowTransitionalJSR292"); } @@ -300,7 +302,7 @@ public class Main { return filenames.toList(); } // where - private boolean checkDirectory(String optName) { + private boolean checkDirectory(OptionName optName) { String value = options.get(optName); if (value == null) return true; @@ -367,10 +369,10 @@ public class Main { return EXIT_CMDERR; } else if (files.isEmpty() && fileObjects.isEmpty() && classnames.isEmpty()) { // it is allowed to compile nothing if just asking for help or version info - if (options.get("-help") != null - || options.get("-X") != null - || options.get("-version") != null - || options.get("-fullversion") != null) + if (options.isSet(HELP) + || options.isSet(X) + || options.isSet(VERSION) + || options.isSet(FULLVERSION)) return EXIT_OK; error("err.no.source.files"); return EXIT_CMDERR; @@ -382,7 +384,7 @@ public class Main { return EXIT_SYSERR; } - boolean forceStdOut = options.get("stdout") != null; + boolean forceStdOut = options.isSet("stdout"); if (forceStdOut) { out.flush(); out = new PrintWriter(System.out, true); @@ -391,7 +393,7 @@ public class Main { context.put(Log.outKey, out); // allow System property in following line as a Mustang legacy - boolean batchMode = (options.get("nonBatchMode") == null + boolean batchMode = (options.isUnset("nonBatchMode") && System.getProperty("nonBatchMode") == null); if (batchMode) CacheFSInfo.preRegister(context); @@ -455,7 +457,7 @@ public class Main { // for buggy compiler error recovery by swallowing thrown // exceptions. if (comp == null || comp.errorCount() == 0 || - options == null || options.get("dev") != null) + options == null || options.isSet("dev")) bugMessage(ex); return EXIT_ABNORMAL; } finally { @@ -478,7 +480,7 @@ public class Main { */ void feMessage(Throwable ex) { Log.printLines(out, ex.getMessage()); - if (ex.getCause() != null && options.get("dev") != null) { + if (ex.getCause() != null && options.isSet("dev")) { ex.getCause().printStackTrace(out); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java b/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java index 66fd4c996f9..1181c274e71 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java +++ b/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java @@ -366,11 +366,11 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan // } // } int maxDepth = (recurse ? Integer.MAX_VALUE : 1); - Set opts = EnumSet.of(DETECT_CYCLES, FOLLOW_LINKS); + Set opts = EnumSet.of(FOLLOW_LINKS); Files.walkFileTree(packageDir, opts, maxDepth, new SimpleFileVisitor() { @Override - public FileVisitResult preVisitDirectory(Path dir) { + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { if (SourceVersion.isIdentifier(dir.getName().toString())) // JSR 292? return FileVisitResult.CONTINUE; else diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java b/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java index d7803b89cd2..e6d687d4ca9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -42,50 +42,17 @@ import static com.sun.tools.javac.util.LayoutCharacters.*; */ public class DocCommentScanner extends Scanner { - /** A factory for creating scanners. */ - public static class Factory extends Scanner.Factory { - - public static void preRegister(final Context context) { - context.put(scannerFactoryKey, new Context.Factory() { - public Factory make() { - return new Factory(context); - } - }); - } - - /** Create a new scanner factory. */ - protected Factory(Context context) { - super(context); - } - - @Override - public Scanner newScanner(CharSequence input) { - if (input instanceof CharBuffer) { - return new DocCommentScanner(this, (CharBuffer)input); - } else { - char[] array = input.toString().toCharArray(); - return newScanner(array, array.length); - } - } - - @Override - public Scanner newScanner(char[] input, int inputLength) { - return new DocCommentScanner(this, input, inputLength); - } - } - - /** Create a scanner from the input buffer. buffer must implement * array() and compact(), and remaining() must be less than limit(). */ - protected DocCommentScanner(Factory fac, CharBuffer buffer) { + protected DocCommentScanner(ScannerFactory fac, CharBuffer buffer) { super(fac, buffer); } /** Create a scanner from the input array. The array must have at * least a single character of extra space. */ - protected DocCommentScanner(Factory fac, char[] input, int inputLength) { + protected DocCommentScanner(ScannerFactory fac, char[] input, int inputLength) { super(fac, input, inputLength); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java index 3ca8b64dc8f..d4ec62a19a9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -2473,6 +2473,11 @@ public class JavacParser implements Parser { defs.append(importDeclaration()); } else { JCTree def = typeDeclaration(mods); + if (keepDocComments && dc != null && docComments.get(def) == dc) { + // If the first type declaration has consumed the first doc + // comment, then don't use it for the top level comment as well. + dc = null; + } if (def instanceof JCExpressionStatement) def = ((JCExpressionStatement)def).expr; defs.append(def); diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java b/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java index 9dc794136dc..709bd5f1018 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -59,7 +59,7 @@ public class ParserFactory { final Source source; final Names names; final Options options; - final Scanner.Factory scannerFactory; + final ScannerFactory scannerFactory; protected ParserFactory(Context context) { super(); @@ -70,11 +70,11 @@ public class ParserFactory { this.keywords = Keywords.instance(context); this.source = Source.instance(context); this.options = Options.instance(context); - this.scannerFactory = Scanner.Factory.instance(context); + this.scannerFactory = ScannerFactory.instance(context); } public Parser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) { - Lexer lexer = scannerFactory.newScanner(input); + Lexer lexer = scannerFactory.newScanner(input, keepDocComments); if (keepEndPos) { return new EndPosParser(this, lexer, keepDocComments, keepLineMap); } else { diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java b/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java index ededb7eccf8..2b558d8fa39 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -47,48 +47,6 @@ public class Scanner implements Lexer { private static boolean scannerDebug = false; - /** A factory for creating scanners. */ - public static class Factory { - /** The context key for the scanner factory. */ - public static final Context.Key scannerFactoryKey = - new Context.Key(); - - /** Get the Factory instance for this context. */ - public static Factory instance(Context context) { - Factory instance = context.get(scannerFactoryKey); - if (instance == null) - instance = new Factory(context); - return instance; - } - - final Log log; - final Names names; - final Source source; - final Keywords keywords; - - /** Create a new scanner factory. */ - protected Factory(Context context) { - context.put(scannerFactoryKey, this); - this.log = Log.instance(context); - this.names = Names.instance(context); - this.source = Source.instance(context); - this.keywords = Keywords.instance(context); - } - - public Scanner newScanner(CharSequence input) { - if (input instanceof CharBuffer) { - return new Scanner(this, (CharBuffer)input); - } else { - char[] array = input.toString().toCharArray(); - return newScanner(array, array.length); - } - } - - public Scanner newScanner(char[] input, int inputLength) { - return new Scanner(this, input, inputLength); - } - } - /* Output variables; set by nextToken(): */ @@ -177,7 +135,7 @@ public class Scanner implements Lexer { private final Keywords keywords; /** Common code for constructors. */ - private Scanner(Factory fac) { + private Scanner(ScannerFactory fac) { log = fac.log; names = fac.names; keywords = fac.keywords; @@ -201,7 +159,7 @@ public class Scanner implements Lexer { /** Create a scanner from the input buffer. buffer must implement * array() and compact(), and remaining() must be less than limit(). */ - protected Scanner(Factory fac, CharBuffer buffer) { + protected Scanner(ScannerFactory fac, CharBuffer buffer) { this(fac, JavacFileManager.toArray(buffer), buffer.limit()); } @@ -216,7 +174,7 @@ public class Scanner implements Lexer { * @param inputLength the size of the input. * Must be positive and less than or equal to input.length. */ - protected Scanner(Factory fac, char[] input, int inputLength) { + protected Scanner(ScannerFactory fac, char[] input, int inputLength) { this(fac); eofPos = inputLength; if (inputLength == input.length) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/ScannerFactory.java b/langtools/src/share/classes/com/sun/tools/javac/parser/ScannerFactory.java new file mode 100644 index 00000000000..86c9bb2b11c --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/ScannerFactory.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 1999, 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 com.sun.tools.javac.parser; + +import java.nio.CharBuffer; + +import com.sun.tools.javac.code.Source; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Names; + + +/** + * A factory for creating scanners. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own + * risk. This code and its internal interfaces are subject to change + * or deletion without notice. + */ +public class ScannerFactory { + /** The context key for the scanner factory. */ + public static final Context.Key scannerFactoryKey = + new Context.Key(); + + /** Get the Factory instance for this context. */ + public static ScannerFactory instance(Context context) { + ScannerFactory instance = context.get(scannerFactoryKey); + if (instance == null) + instance = new ScannerFactory(context); + return instance; + } + + final Log log; + final Names names; + final Source source; + final Keywords keywords; + + /** Create a new scanner factory. */ + protected ScannerFactory(Context context) { + context.put(scannerFactoryKey, this); + this.log = Log.instance(context); + this.names = Names.instance(context); + this.source = Source.instance(context); + this.keywords = Keywords.instance(context); + } + + public Scanner newScanner(CharSequence input, boolean keepDocComments) { + if (input instanceof CharBuffer) { + CharBuffer buf = (CharBuffer) input; + if (keepDocComments) + return new DocCommentScanner(this, buf); + else + return new Scanner(this, buf); + } else { + char[] array = input.toString().toCharArray(); + return newScanner(array, array.length, keepDocComments); + } + } + + public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) { + if (keepDocComments) + return new DocCommentScanner(this, input, inputLength); + else + return new Scanner(this, input, inputLength); + } +} diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java index 6b9ec8e1e54..d02a9147d1d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java @@ -25,14 +25,6 @@ package com.sun.tools.javac.processing; -import com.sun.tools.javac.util.*; -import javax.annotation.processing.*; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.NestingKind; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.Element; -import java.util.*; - import java.io.Closeable; import java.io.FileNotFoundException; import java.io.InputStream; @@ -43,14 +35,26 @@ import java.io.Writer; import java.io.FilterWriter; import java.io.PrintWriter; import java.io.IOException; +import java.util.*; -import javax.tools.*; import static java.util.Collections.*; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.NestingKind; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.Element; +import javax.tools.*; import javax.tools.JavaFileManager.Location; + import static javax.tools.StandardLocation.SOURCE_OUTPUT; import static javax.tools.StandardLocation.CLASS_OUTPUT; +import com.sun.tools.javac.code.Lint; +import com.sun.tools.javac.util.*; + +import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING; + /** * The FilerImplementation class must maintain a number of * constraints. First, multiple attempts to open the same path within @@ -366,7 +370,7 @@ public class JavacFiler implements Filer, Closeable { aggregateGeneratedSourceNames = new LinkedHashSet(); aggregateGeneratedClassNames = new LinkedHashSet(); - lint = (Options.instance(context)).lint("processing"); + lint = (Lint.instance(context)).isEnabled(PROCESSING); } public JavaFileObject createSourceFile(CharSequence name, diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index f6623ef9028..49ca742a580 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2009, 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. * * This code is free software; you can redistribute it and/or modify it @@ -49,6 +49,7 @@ import javax.tools.StandardJavaFileManager; import javax.tools.JavaFileObject; import javax.tools.DiagnosticListener; +import com.sun.tools.javac.api.JavacTrees; import com.sun.source.util.AbstractTypeProcessor; import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskListener; @@ -78,6 +79,8 @@ import com.sun.tools.javac.util.Options; import static javax.tools.StandardLocation.*; import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*; +import static com.sun.tools.javac.main.OptionName.*; +import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING; /** * Objects of this class hold and manage the state needed to support @@ -159,15 +162,14 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea source = Source.instance(context); diags = JCDiagnostic.Factory.instance(context); options = Options.instance(context); - printProcessorInfo = options.get("-XprintProcessorInfo") != null; - printRounds = options.get("-XprintRounds") != null; - verbose = options.get("-verbose") != null; - lint = options.lint("processing"); - procOnly = options.get("-proc:only") != null || - options.get("-Xprint") != null; - fatalErrors = options.get("fatalEnterError") != null; - showResolveErrors = options.get("showResolveErrors") != null; - werror = options.get("-Werror") != null; + printProcessorInfo = options.isSet(XPRINTPROCESSORINFO); + printRounds = options.isSet(XPRINTROUNDS); + verbose = options.isSet(VERBOSE); + lint = Lint.instance(context).isEnabled(PROCESSING); + procOnly = options.isSet(PROC, "only") || options.isSet(XPRINT); + fatalErrors = options.isSet("fatalEnterError"); + showResolveErrors = options.isSet("showResolveErrors"); + werror = options.isSet(WERROR); platformAnnotations = initPlatformAnnotations(); foundTypeProcessors = false; @@ -199,7 +201,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea Log log = Log.instance(context); Iterator processorIterator; - if (options.get("-Xprint") != null) { + if (options.isSet(XPRINT)) { try { Processor processor = PrintingProcessor.class.newInstance(); processorIterator = List.of(processor).iterator(); @@ -212,7 +214,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea } else if (processors != null) { processorIterator = processors.iterator(); } else { - String processorNames = options.get("-processor"); + String processorNames = options.get(PROCESSOR); JavaFileManager fileManager = context.get(JavaFileManager.class); try { // If processorpath is not explicitly set, use the classpath. @@ -263,7 +265,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea ? standardFileManager.getLocation(ANNOTATION_PROCESSOR_PATH) : standardFileManager.getLocation(CLASS_PATH); - if (needClassLoader(options.get("-processor"), workingPath) ) + if (needClassLoader(options.get(PROCESSOR), workingPath) ) handleException(key, e); } else { @@ -744,7 +746,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea psi.runContributingProcs(renv); // Debugging - if (options.get("displayFilerState") != null) + if (options.isSet("displayFilerState")) filer.displayState(); } @@ -1104,6 +1106,12 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea task.updateContext(next); } + JavacTrees trees = context.get(JavacTrees.class); + if (trees != null) { + next.put(JavacTrees.class, trees); + trees.updateContext(next); + } + context.clear(); return next; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index dfb32c01cff..36309876dbc 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -93,6 +93,8 @@ compiler.err.cant.apply.symbol.1=\ required: {2}\n\ found: {3}\n\ reason: {6} +compiler.err.cant.apply.symbols=\ + no suitable {0} found for {1}({2}) compiler.err.cant.assign.val.to.final.var=\ cannot assign a value to final variable {0} compiler.err.cant.deref=\ @@ -1075,11 +1077,11 @@ compiler.misc.no.unique.maximal.instance.exists=\ no unique maximal instance exists for type variable {0} with upper bounds {1} compiler.misc.no.unique.minimal.instance.exists=\ no unique minimal instance exists for type variable {0} with lower bounds {1} -compiler.misc.no.conforming.instance.exists=\ +compiler.misc.infer.no.conforming.instance.exists=\ no instance(s) of type variable(s) {0} exist so that {1} conforms to {2} -compiler.misc.no.conforming.assignment.exists=\ +compiler.misc.infer.no.conforming.assignment.exists=\ no instance(s) of type variable(s) {0} exist so that argument type {1} conforms to formal parameter type {2} -compiler.misc.arg.length.mismatch=\ +compiler.misc.infer.arg.length.mismatch=\ cannot instantiate from arguments because actual and formal argument lists differ in length compiler.misc.inferred.do.not.conform.to.bounds=\ inferred type does not conform to declared bound(s)\n\ @@ -1095,6 +1097,16 @@ compiler.misc.diamond.invalid.arg=\ type argument {0} inferred for {1} is not allowed in this context compiler.misc.diamond.invalid.args=\ type arguments {0} inferred for {1} are not allowed in this context + +compiler.misc.explicit.param.do.not.conform.to.bounds=\ + explicit type argument {0} does not conform to declared bound(s) {1} + +compiler.misc.arg.length.mismatch=\ + actual and formal argument lists differ in length +compiler.misc.no.conforming.assignment.exists=\ + actual argument {0} cannot be converted to {1} by method invocation conversion +compiler.misc.varargs.argument.mismatch=\ + argument type {0} does not conform to vararg element type {1} ##### ## The first argument ({0}) is a "kindname". @@ -1232,6 +1244,10 @@ compiler.misc.varargs.clash.with=\ compiler.misc.non.denotable.type=\ Non-denotable type {0} not allowed here +compiler.misc.inapplicable.method=\ + {0} {1}.{2} is not applicable\n\ + ({3}) + ######################################## # Diagnostics for language feature changes ######################################## diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java index 1fa1b87ffc2..b4035a81e25 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java @@ -65,8 +65,6 @@ import static com.sun.tools.javac.util.LayoutCharacters.*; */ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter { - protected int currentIndentation = 0; - /** * Create a basic formatter based on the supplied options. * @@ -107,33 +105,28 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter { } public String formatMessage(JCDiagnostic d, Locale l) { - int prevIndentation = currentIndentation; - try { - StringBuilder buf = new StringBuilder(); - Collection args = formatArguments(d, l); - String msg = localize(l, d.getCode(), args.toArray()); - String[] lines = msg.split("\n"); - if (getConfiguration().getVisible().contains(DiagnosticPart.SUMMARY)) { - currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUMMARY); - buf.append(indent(lines[0], currentIndentation)); //summary + int currentIndentation = 0; + StringBuilder buf = new StringBuilder(); + Collection args = formatArguments(d, l); + String msg = localize(l, d.getCode(), args.toArray()); + String[] lines = msg.split("\n"); + if (getConfiguration().getVisible().contains(DiagnosticPart.SUMMARY)) { + currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUMMARY); + buf.append(indent(lines[0], currentIndentation)); //summary + } + if (lines.length > 1 && getConfiguration().getVisible().contains(DiagnosticPart.DETAILS)) { + currentIndentation += getConfiguration().getIndentation(DiagnosticPart.DETAILS); + for (int i = 1;i < lines.length; i++) { + buf.append("\n" + indent(lines[i], currentIndentation)); } - if (lines.length > 1 && getConfiguration().getVisible().contains(DiagnosticPart.DETAILS)) { - currentIndentation += getConfiguration().getIndentation(DiagnosticPart.DETAILS); - for (int i = 1;i < lines.length; i++) { - buf.append("\n" + indent(lines[i], currentIndentation)); - } - } - if (d.isMultiline() && getConfiguration().getVisible().contains(DiagnosticPart.SUBDIAGNOSTICS)) { - currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUBDIAGNOSTICS); + } + if (d.isMultiline() && getConfiguration().getVisible().contains(DiagnosticPart.SUBDIAGNOSTICS)) { + currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUBDIAGNOSTICS); for (String sub : formatSubdiagnostics(d, l)) { - buf.append("\n" + sub); - } + buf.append("\n" + indent(sub, currentIndentation)); } - return buf.toString(); - } - finally { - currentIndentation = prevIndentation; } + return buf.toString(); } protected String addSourceLineIfNeeded(JCDiagnostic d, String msg) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java index 0ffdc1a6ac0..315d3e75ff0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java @@ -35,11 +35,14 @@ import java.util.Set; import javax.tools.DiagnosticListener; import javax.tools.JavaFileObject; -import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.api.DiagnosticFormatter; +import com.sun.tools.javac.main.OptionName; +import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; +import static com.sun.tools.javac.main.OptionName.*; + /** A class for error logs. Reports errors and warnings, and * keeps track of error numbers and positions. * @@ -129,14 +132,14 @@ public class Log extends AbstractLog { this.noticeWriter = noticeWriter; Options options = Options.instance(context); - this.dumpOnError = options.get("-doe") != null; - this.promptOnError = options.get("-prompt") != null; - this.emitWarnings = options.get("-Xlint:none") == null; - this.suppressNotes = options.get("suppressNotes") != null; - this.MaxErrors = getIntOption(options, "-Xmaxerrs", getDefaultMaxErrors()); - this.MaxWarnings = getIntOption(options, "-Xmaxwarns", getDefaultMaxWarnings()); + this.dumpOnError = options.isSet(DOE); + this.promptOnError = options.isSet(PROMPT); + this.emitWarnings = options.isUnset(XLINT_CUSTOM, "none"); + this.suppressNotes = options.isSet("suppressNotes"); + this.MaxErrors = getIntOption(options, XMAXERRS, getDefaultMaxErrors()); + this.MaxWarnings = getIntOption(options, XMAXWARNS, getDefaultMaxWarnings()); - boolean rawDiagnostics = options.get("rawDiagnostics") != null; + boolean rawDiagnostics = options.isSet("rawDiagnostics"); messages = JavacMessages.instance(context); this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(options) : new BasicDiagnosticFormatter(options, messages); @@ -150,7 +153,7 @@ public class Log extends AbstractLog { expectDiagKeys = new HashSet(Arrays.asList(ek.split(", *"))); } // where - private int getIntOption(Options options, String optionName, int defaultValue) { + private int getIntOption(Options options, OptionName optionName, int defaultValue) { String s = options.get(optionName); try { if (s != null) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java index a0c7218878d..9b939ea7341 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java @@ -271,7 +271,7 @@ public class Names { } protected Name.Table createTable(Options options) { - boolean useUnsharedTable = options.get("useUnsharedTable") != null; + boolean useUnsharedTable = options.isSet("useUnsharedTable"); if (useUnsharedTable) return new UnsharedNameTable(this); else diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Options.java b/langtools/src/share/classes/com/sun/tools/javac/util/Options.java index 23eb56fd37c..100c0f03f99 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Options.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Options.java @@ -25,8 +25,9 @@ package com.sun.tools.javac.util; -import com.sun.tools.javac.main.OptionName; import java.util.*; +import com.sun.tools.javac.main.OptionName; +import static com.sun.tools.javac.main.OptionName.*; /** A table of all command-line options. * If an option has an argument, the option name is mapped to the argument. @@ -60,14 +61,62 @@ public class Options { context.put(optionsKey, this); } + /** + * Get the value for an undocumented option. + */ public String get(String name) { return values.get(name); } + /** + * Get the value for an option. + */ public String get(OptionName name) { return values.get(name.optionName); } + /** + * Check if the value for an undocumented option has been set. + */ + public boolean isSet(String name) { + return (values.get(name) != null); + } + + /** + * Check if the value for an option has been set. + */ + public boolean isSet(OptionName name) { + return (values.get(name.optionName) != null); + } + + /** + * Check if the value for a choice option has been set to a specific value. + */ + public boolean isSet(OptionName name, String value) { + return (values.get(name.optionName + value) != null); + } + + /** + * Check if the value for an undocumented option has not been set. + */ + public boolean isUnset(String name) { + return (values.get(name) == null); + } + + /** + * Check if the value for an option has not been set. + */ + public boolean isUnset(OptionName name) { + return (values.get(name.optionName) == null); + } + + /** + * Check if the value for a choice option has not been set to a specific value. + */ + public boolean isUnset(OptionName name, String value) { + return (values.get(name.optionName + value) == null); + } + public void put(String name, String value) { values.put(name, value); } @@ -92,16 +141,14 @@ public class Options { return values.size(); } - static final String LINT = "-Xlint"; - /** Check for a lint suboption. */ public boolean lint(String s) { // return true if either the specific option is enabled, or // they are all enabled without the specific one being // disabled return - get(LINT + ":" + s)!=null || - (get(LINT)!=null || get(LINT + ":all")!=null) && - get(LINT+":-"+s)==null; + isSet(XLINT_CUSTOM, s) || + (isSet(XLINT) || isSet(XLINT_CUSTOM, "all")) && + isUnset(XLINT_CUSTOM, "-" + s); } } diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java index 580eac04edd..cac7f991354 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -107,9 +107,6 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { // force the use of Messager as a Log messager = Messager.instance0(context); - // force the use of the scanner that captures Javadoc comments - DocCommentScanner.Factory.preRegister(context); - return new JavadocTool(context); } catch (CompletionFailure ex) { messager.error(Position.NOPOS, ex.getMessage()); diff --git a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java index 650460a5c5d..0e885815dc2 100644 --- a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java +++ b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -526,15 +526,17 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask { } private void showVersion(boolean full) { - log.println(version(full ? "full" : "release")); + log.println(version(full)); } private static final String versionRBName = "com.sun.tools.javah.resources.version"; private static ResourceBundle versionRB; - private String version(String key) { - // key=version: mm.nn.oo[-milestone] - // key=full: mm.mm.oo[-milestone]-build + private String version(boolean full) { + String msgKey = (full ? "javah.fullVersion" : "javah.version"); + String versionKey = (full ? "full" : "release"); + // versionKey=product: mm.nn.oo[-milestone] + // versionKey=full: mm.mm.oo[-milestone]-build if (versionRB == null) { try { versionRB = ResourceBundle.getBundle(versionRBName); @@ -543,7 +545,7 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask { } } try { - return versionRB.getString(key); + return getMessage(msgKey, "javah", versionRB.getString(versionKey)); } catch (MissingResourceException e) { return getMessage("version.unknown", System.getProperty("java.version")); diff --git a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties index b9f175e5bf8..305e275b054 100644 --- a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties +++ b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1998, 2003, 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. # # This code is free software; you can redistribute it and/or modify it @@ -113,7 +113,8 @@ main.usage.foot=\ # # Version string. # -javah.version=javah version "{0}" +javah.version={0} version "{1}" +javah.fullVersion={0} full version "{1}" # # These should have better diagnostics. diff --git a/langtools/src/share/classes/com/sun/tools/javah/resources/version.properties-template b/langtools/src/share/classes/com/sun/tools/javah/resources/version.properties-template new file mode 100644 index 00000000000..1e98afc90c7 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/javah/resources/version.properties-template @@ -0,0 +1,28 @@ +# +# Copyright (c) 2005, 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. +# + +jdk=$(JDK_VERSION) +full=$(FULL_VERSION) +release=$(RELEASE) diff --git a/langtools/test/tools/javac/6302184/T6302184.out b/langtools/test/tools/javac/6302184/T6302184.out index 4bfc1f79d78..e69f78750bc 100644 --- a/langtools/test/tools/javac/6302184/T6302184.out +++ b/langtools/test/tools/javac/6302184/T6302184.out @@ -1,4 +1,7 @@ +/** + * This is a test that uses ISO 8859 encoding. + */ class T6302184 { T6302184() { diff --git a/langtools/test/tools/javac/6304921/TestLog.java b/langtools/test/tools/javac/6304921/TestLog.java index 465a6e3cbbb..32217a45d35 100644 --- a/langtools/test/tools/javac/6304921/TestLog.java +++ b/langtools/test/tools/javac/6304921/TestLog.java @@ -1,5 +1,5 @@ /* - * 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. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,6 @@ import javax.tools.SimpleJavaFileObject; import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.parser.Parser; import com.sun.tools.javac.parser.ParserFactory; -import com.sun.tools.javac.parser.Scanner; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.util.Context; @@ -60,7 +59,6 @@ public class TestLog log.multipleErrors = true; JavacFileManager.preRegister(context); - Scanner.Factory sfac = Scanner.Factory.instance(context); ParserFactory pfac = ParserFactory.instance(context); final String text = diff --git a/langtools/test/tools/javac/6758789/T6758789a.out b/langtools/test/tools/javac/6758789/T6758789a.out index 1e1ec6c7b38..4d82fbc4877 100644 --- a/langtools/test/tools/javac/6758789/T6758789a.out +++ b/langtools/test/tools/javac/6758789/T6758789a.out @@ -1,3 +1,3 @@ -T6758789a.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m1, compiler.misc.no.args, int, kindname.class, T6758789a, null -T6758789a.java:15:9: compiler.err.cant.apply.symbol: kindname.method, m2, int, compiler.misc.no.args, kindname.class, T6758789a, null +T6758789a.java:14:9: compiler.err.cant.apply.symbol.1: kindname.method, m1, compiler.misc.no.args, int, kindname.class, T6758789a, (compiler.misc.arg.length.mismatch) +T6758789a.java:15:9: compiler.err.cant.apply.symbol.1: kindname.method, m2, int, compiler.misc.no.args, kindname.class, T6758789a, (compiler.misc.arg.length.mismatch) 2 errors diff --git a/langtools/test/tools/javac/6840059/T6840059.out b/langtools/test/tools/javac/6840059/T6840059.out index a93cdf688a4..c8f01866e79 100644 --- a/langtools/test/tools/javac/6840059/T6840059.out +++ b/langtools/test/tools/javac/6840059/T6840059.out @@ -1,3 +1,3 @@ -T6840059.java:15:9: compiler.err.cant.apply.symbol: kindname.constructor, T6840059, java.lang.Integer, java.lang.String, kindname.class, T6840059, null -T6840059.java:15:25: compiler.err.cant.apply.symbol: kindname.constructor, T6840059, java.lang.Integer, compiler.misc.no.args, kindname.class, T6840059, null +T6840059.java:15:9: compiler.err.cant.apply.symbol.1: kindname.constructor, T6840059, java.lang.Integer, java.lang.String, kindname.class, T6840059, (compiler.misc.no.conforming.assignment.exists: java.lang.String, java.lang.Integer) +T6840059.java:15:25: compiler.err.cant.apply.symbol.1: kindname.constructor, T6840059, java.lang.Integer, compiler.misc.no.args, kindname.class, T6840059, (compiler.misc.arg.length.mismatch) 2 errors diff --git a/langtools/test/tools/javac/6857948/T6857948.out b/langtools/test/tools/javac/6857948/T6857948.out index f6a79ed7745..0ba7deb6a55 100644 --- a/langtools/test/tools/javac/6857948/T6857948.out +++ b/langtools/test/tools/javac/6857948/T6857948.out @@ -1,3 +1,3 @@ T6857948.java:16:32: compiler.err.cant.resolve.location.args: kindname.method, nosuchfunction, , , kindname.class, Test -T6857948.java:16:50: compiler.err.cant.apply.symbol: kindname.constructor, Foo, java.lang.String, compiler.misc.no.args, kindname.class, Foo, null +T6857948.java:16:50: compiler.err.cant.apply.symbol.1: kindname.constructor, Foo, java.lang.String, compiler.misc.no.args, kindname.class, Foo, (compiler.misc.arg.length.mismatch) 2 errors diff --git a/langtools/test/tools/javac/6863465/T6863465a.java b/langtools/test/tools/javac/6863465/T6863465a.java new file mode 100644 index 00000000000..9082f9188d6 --- /dev/null +++ b/langtools/test/tools/javac/6863465/T6863465a.java @@ -0,0 +1,14 @@ +/** + * @test /nodynamiccopyright/ + * @bug 6863465 + * @summary javac doesn't detect circular subclass dependencies via qualified names + * @author Maurizio Cimadamore + * @compile/fail/ref=T6863465a.out -XDrawDiagnostics T6863465a.java + */ + +class T6863465a { + static class a { static interface b {} } + static class c extends a implements z.y {} + static class x { static interface y {} } + static class z extends x implements c.b {} +} diff --git a/langtools/test/tools/javac/6863465/T6863465a.out b/langtools/test/tools/javac/6863465/T6863465a.out new file mode 100644 index 00000000000..1c4513f21aa --- /dev/null +++ b/langtools/test/tools/javac/6863465/T6863465a.out @@ -0,0 +1,2 @@ +T6863465a.java:11:12: compiler.err.cyclic.inheritance: T6863465a.c +1 error diff --git a/langtools/test/tools/javac/6863465/T6863465b.java b/langtools/test/tools/javac/6863465/T6863465b.java new file mode 100644 index 00000000000..fd2aca7fc63 --- /dev/null +++ b/langtools/test/tools/javac/6863465/T6863465b.java @@ -0,0 +1,14 @@ +/** + * @test /nodynamiccopyright/ + * @bug 6863465 + * @summary javac doesn't detect circular subclass dependencies via qualified names + * @author Maurizio Cimadamore + * @compile/fail/ref=T6863465b.out -XDrawDiagnostics T6863465b.java + */ + +class T6863465b { + static class a { static interface b { static interface d {} } } + static class c extends a implements z.y, z.d {} + static class x { static interface y {} } + static class z extends x implements c.b {} +} diff --git a/langtools/test/tools/javac/6863465/T6863465b.out b/langtools/test/tools/javac/6863465/T6863465b.out new file mode 100644 index 00000000000..cb16e933612 --- /dev/null +++ b/langtools/test/tools/javac/6863465/T6863465b.out @@ -0,0 +1,2 @@ +T6863465b.java:11:12: compiler.err.cyclic.inheritance: T6863465b.c +1 error diff --git a/langtools/test/tools/javac/6863465/T6863465c.java b/langtools/test/tools/javac/6863465/T6863465c.java new file mode 100644 index 00000000000..e731c1614a3 --- /dev/null +++ b/langtools/test/tools/javac/6863465/T6863465c.java @@ -0,0 +1,14 @@ +/** + * @test /nodynamiccopyright/ + * @bug 6863465 + * @summary javac doesn't detect circular subclass dependencies via qualified names + * @author Maurizio Cimadamore + * @compile/fail/ref=T6863465c.out -XDrawDiagnostics T6863465c.java + */ + +class T6863465c { + static class x { static interface y {} } + static class z extends x implements c.b {} + static class a { static interface b { static interface d {} } } + static class c extends a implements z.y, z.d {} +} diff --git a/langtools/test/tools/javac/6863465/T6863465c.out b/langtools/test/tools/javac/6863465/T6863465c.out new file mode 100644 index 00000000000..8773cebb55b --- /dev/null +++ b/langtools/test/tools/javac/6863465/T6863465c.out @@ -0,0 +1,3 @@ +T6863465c.java:13:47: compiler.err.cant.resolve.location: kindname.class, d, , , kindname.class, T6863465c.z +T6863465c.java:11:12: compiler.err.cyclic.inheritance: T6863465c.z +2 errors diff --git a/langtools/test/tools/javac/6863465/T6863465d.java b/langtools/test/tools/javac/6863465/T6863465d.java new file mode 100644 index 00000000000..dfc2db164b2 --- /dev/null +++ b/langtools/test/tools/javac/6863465/T6863465d.java @@ -0,0 +1,14 @@ +/** + * @test /nodynamiccopyright/ + * @bug 6863465 + * @summary javac doesn't detect circular subclass dependencies via qualified names + * @author Maurizio Cimadamore + * @compile/fail/ref=T6863465d.out -XDrawDiagnostics T6863465d.java + */ + +class T6863465d { + static class a { static interface b { static interface d {} } } + static class c extends a implements z.y, z.d {} + static class x { static interface y { static interface w {} } } + static class z extends x implements c.b, c.w {} +} diff --git a/langtools/test/tools/javac/6863465/T6863465d.out b/langtools/test/tools/javac/6863465/T6863465d.out new file mode 100644 index 00000000000..8204205d3ff --- /dev/null +++ b/langtools/test/tools/javac/6863465/T6863465d.out @@ -0,0 +1,3 @@ +T6863465d.java:13:47: compiler.err.cant.resolve.location: kindname.class, w, , , kindname.class, T6863465d.c +T6863465d.java:11:12: compiler.err.cyclic.inheritance: T6863465d.c +2 errors diff --git a/langtools/test/tools/javac/6863465/TestCircularClassfile.java b/langtools/test/tools/javac/6863465/TestCircularClassfile.java new file mode 100644 index 00000000000..88d2466d5a4 --- /dev/null +++ b/langtools/test/tools/javac/6863465/TestCircularClassfile.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6863465 + * @summary javac doesn't detect circular subclass dependencies via qualified names + * @run main TestCircularClassfile + */ + +import java.io.*; +import java.net.URI; +import java.util.Arrays; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticListener; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.ToolProvider; + +import com.sun.source.util.JavacTask; +import java.util.EnumSet; + +public class TestCircularClassfile { + + enum ClassName { + A("A"), + B("B"), + C("C"), + OBJECT("Object"); + + String name; + + ClassName(String name) { + this.name = name; + } + } + + static class JavaSource extends SimpleJavaFileObject { + + final static String sourceStub = "class #C extends #S {}"; + + String source; + + public JavaSource(ClassName clazz, ClassName sup) { + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); + source = sourceStub.replace("#C", clazz.name).replace("#S", sup.name); + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return source; + } + } + + public static void main(String... args) throws Exception { + int count = 0; + for (ClassName clazz : EnumSet.of(ClassName.A, ClassName.B, ClassName.C)) { + for (ClassName sup : EnumSet.of(ClassName.A, ClassName.B, ClassName.C)) { + if (sup.ordinal() < clazz.ordinal()) continue; + check("sub_"+count++, clazz, sup); + } + } + } + + static JavaSource[] initialSources = new JavaSource[] { + new JavaSource(ClassName.A, ClassName.OBJECT), + new JavaSource(ClassName.B, ClassName.A), + new JavaSource(ClassName.C, ClassName.B) + }; + + static String workDir = System.getProperty("user.dir"); + + static void check(String destPath, ClassName clazz, ClassName sup) throws Exception { + File destDir = new File(workDir, destPath); destDir.mkdir(); + final JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); + JavacTask ct = (JavacTask)tool.getTask(null, null, null, + Arrays.asList("-d", destPath), null, Arrays.asList(initialSources)); + ct.generate(); + File fileToRemove = new File(destPath, clazz.name + ".class"); + fileToRemove.delete(); + JavaSource newSource = new JavaSource(clazz, sup); + DiagnosticChecker checker = new DiagnosticChecker(); + ct = (JavacTask)tool.getTask(null, null, checker, + Arrays.asList("-cp", destPath), null, Arrays.asList(newSource)); + ct.analyze(); + if (!checker.errorFound) { + throw new AssertionError(newSource.source); + } + } + + static class DiagnosticChecker implements DiagnosticListener { + + boolean errorFound = false; + + public void report(Diagnostic diagnostic) { + if (diagnostic.getKind() == Diagnostic.Kind.ERROR && + diagnostic.getCode().equals("compiler.err.cyclic.inheritance")) { + errorFound = true; + } + } + } +} diff --git a/langtools/test/tools/javac/CyclicInheritance.out b/langtools/test/tools/javac/CyclicInheritance.out index 2923e4f1306..ad5ee0be27e 100644 --- a/langtools/test/tools/javac/CyclicInheritance.out +++ b/langtools/test/tools/javac/CyclicInheritance.out @@ -4,6 +4,6 @@ CyclicInheritance.java:20:1: compiler.err.cyclic.inheritance: I1 CyclicInheritance.java:22:1: compiler.err.cyclic.inheritance: I11 CyclicInheritance.java:27:1: compiler.err.cyclic.inheritance: C211 CyclicInheritance.java:31:1: compiler.err.cyclic.inheritance: C212 -CyclicInheritance.java:36:27: compiler.err.report.access: C221.I, private, C221 -CyclicInheritance.java:40:24: compiler.err.report.access: C222.C, private, C222 +CyclicInheritance.java:36:1: compiler.err.cyclic.inheritance: C221 +CyclicInheritance.java:40:1: compiler.err.cyclic.inheritance: C222 8 errors diff --git a/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_1.out b/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_1.out index 72032584edf..adfe7af8a68 100644 --- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_1.out +++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_1.out @@ -1,2 +1,2 @@ -T6722234a.java:12:9: compiler.err.cant.apply.symbol: kindname.method, m, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T6722234a, null +T6722234a.java:12:9: compiler.err.cant.apply.symbol.1: kindname.method, m, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T6722234a, (compiler.misc.no.conforming.assignment.exists: compiler.misc.type.var: T, 2, compiler.misc.type.var: T, 1) 1 error diff --git a/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_2.out b/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_2.out index 70155066aa1..e535bdce962 100644 --- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_2.out +++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_2.out @@ -1,3 +1,3 @@ -T6722234a.java:12:9: compiler.err.cant.apply.symbol: kindname.method, m, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T6722234a, null +T6722234a.java:12:9: compiler.err.cant.apply.symbol.1: kindname.method, m, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T6722234a, (compiler.misc.no.conforming.assignment.exists: compiler.misc.type.var: T, 2, compiler.misc.type.var: T, 1) - compiler.misc.where.description.typevar.1: compiler.misc.type.var: T, 1,compiler.misc.type.var: T, 2,{(compiler.misc.where.typevar: compiler.misc.type.var: T, 1, java.lang.String, kindname.class, T6722234a),(compiler.misc.where.typevar: compiler.misc.type.var: T, 2, java.lang.Integer, kindname.method, test(compiler.misc.type.var: T, 2))} 1 error diff --git a/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_1.out b/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_1.out index cc41483011e..b019f8ab213 100644 --- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_1.out +++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_1.out @@ -1,2 +1,2 @@ -T6722234b.java:16:9: compiler.err.cant.apply.symbol: kindname.method, m, List,List, List,List, kindname.class, T6722234b, null +T6722234b.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, List,List, List,List, kindname.class, T6722234b, (compiler.misc.infer.no.conforming.assignment.exists: T, List, List) 1 error diff --git a/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_2.out b/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_2.out index d9cc6dab61b..e4e669363c7 100644 --- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_2.out +++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_2.out @@ -1,4 +1,4 @@ -T6722234b.java:16:9: compiler.err.cant.apply.symbol: kindname.method, m, List,List, List,List, kindname.class, T6722234b, null +T6722234b.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, List,List, List,List, kindname.class, T6722234b, (compiler.misc.infer.no.conforming.assignment.exists: T, List, List) - compiler.misc.where.description.typevar: T,{(compiler.misc.where.typevar: T, Object, kindname.method, m(List,List))} - compiler.misc.where.description.captured.1: compiler.misc.captured.type: 1,compiler.misc.captured.type: 2,{(compiler.misc.where.captured.1: compiler.misc.captured.type: 1, T6722234b, compiler.misc.type.null, ? extends T6722234b),(compiler.misc.where.captured.1: compiler.misc.captured.type: 2, T6722234b, compiler.misc.type.null, ? extends T6722234b)} 1 error diff --git a/langtools/test/tools/javac/Diagnostics/6722234/T6722234c.out b/langtools/test/tools/javac/Diagnostics/6722234/T6722234c.out index b79e0d1d19e..a5189139812 100644 --- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234c.out +++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234c.out @@ -1,2 +1,2 @@ -T6722234c.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, T6722234c.String, java.lang.String, kindname.class, T6722234c, null +T6722234c.java:14:9: compiler.err.cant.apply.symbol.1: kindname.method, m, T6722234c.String, java.lang.String, kindname.class, T6722234c, (compiler.misc.infer.no.conforming.assignment.exists: T, java.lang.String, T6722234c.String) 1 error diff --git a/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out b/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out index f3933ef7461..323a354d73e 100644 --- a/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out +++ b/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out @@ -1,4 +1,4 @@ -T6799605.java:17:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605, kindname.class, T6799605 -T6799605.java:18:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605,T6799605, kindname.class, T6799605 -T6799605.java:19:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605,T6799605,T6799605, kindname.class, T6799605 +T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605,{(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605), (compiler.misc.inferred.do.not.conform.to.bounds: compiler.misc.type.captureof: 1, ?, T6799605))} +T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605,T6799605,{(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605), (compiler.misc.infer.no.conforming.assignment.exists: T, T6799605, T6799605)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605), (compiler.misc.infer.arg.length.mismatch))} +T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605,T6799605,T6799605,{(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605,T6799605), (compiler.misc.infer.no.conforming.assignment.exists: T, T6799605, T6799605)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605), (compiler.misc.infer.arg.length.mismatch))} 3 errors diff --git a/langtools/test/tools/javac/Diagnostics/6862608/T6862608a.out b/langtools/test/tools/javac/Diagnostics/6862608/T6862608a.out index 59d1c9b5c3f..b9f85252aaa 100644 --- a/langtools/test/tools/javac/Diagnostics/6862608/T6862608a.out +++ b/langtools/test/tools/javac/Diagnostics/6862608/T6862608a.out @@ -1,3 +1,3 @@ -T6862608a.java:19:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: T, java.util.Comparator, java.util.Comparator)), java.util.Comparator, java.util.Comparator +T6862608a.java:19:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, java.util.Comparator, java.util.Comparator)), java.util.Comparator, java.util.Comparator - compiler.misc.where.description.typevar: T,{(compiler.misc.where.typevar: T, java.lang.Object, kindname.method, compound(java.lang.Iterable>))} 1 error diff --git a/langtools/test/tools/javac/Diagnostics/6862608/T6862608b.out b/langtools/test/tools/javac/Diagnostics/6862608/T6862608b.out index 415700b77ea..d24e7cd1fa9 100644 --- a/langtools/test/tools/javac/Diagnostics/6862608/T6862608b.out +++ b/langtools/test/tools/javac/Diagnostics/6862608/T6862608b.out @@ -1,3 +1,3 @@ -T6862608b.java:11:7: compiler.err.cant.apply.symbol: kindname.method, test, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T66862608b, null +T6862608b.java:11:7: compiler.err.cant.apply.symbol.1: kindname.method, test, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T66862608b, (compiler.misc.no.conforming.assignment.exists: compiler.misc.type.var: T, 2, compiler.misc.type.var: T, 1) - compiler.misc.where.description.typevar.1: compiler.misc.type.var: T, 1,compiler.misc.type.var: T, 2,compiler.misc.type.var: S, 1,compiler.misc.type.var: S, 2,{(compiler.misc.where.typevar: compiler.misc.type.var: T, 1, java.lang.String, kindname.class, T66862608b),(compiler.misc.where.typevar: compiler.misc.type.var: T, 2, compiler.misc.type.var: S, 1, kindname.method, foo(compiler.misc.type.var: T, 2)),(compiler.misc.where.typevar: compiler.misc.type.var: S, 1, java.lang.Object, kindname.method, foo(compiler.misc.type.var: T, 2)),(compiler.misc.where.typevar: compiler.misc.type.var: S, 2, java.lang.Object, kindname.class, T66862608b)} 1 error diff --git a/langtools/test/tools/javac/NameCollision.out b/langtools/test/tools/javac/NameCollision.out index 17b39218513..2bd56497115 100644 --- a/langtools/test/tools/javac/NameCollision.out +++ b/langtools/test/tools/javac/NameCollision.out @@ -1,2 +1,3 @@ NameCollision.java:13:31: compiler.err.intf.expected.here -1 error +NameCollision.java:13:5: compiler.err.cyclic.inheritance: NameCollision.Runnable +2 errors diff --git a/langtools/test/tools/javac/T6326754.out b/langtools/test/tools/javac/T6326754.out index efbd8393b8b..faa786bdc0e 100644 --- a/langtools/test/tools/javac/T6326754.out +++ b/langtools/test/tools/javac/T6326754.out @@ -1,7 +1,7 @@ T6326754.java:44:12: compiler.err.name.clash.same.erasure: TestConstructor(T), TestConstructor(K) T6326754.java:52:17: compiler.err.name.clash.same.erasure: setT(K), setT(T) T6326754.java:64:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types), T, T -T6326754.java:70:11: compiler.err.cant.apply.symbol: kindname.method, setT, java.lang.Object, compiler.misc.no.args, kindname.class, TestC, null +T6326754.java:70:11: compiler.err.cant.apply.symbol.1: kindname.method, setT, java.lang.Object, compiler.misc.no.args, kindname.class, TestC, (compiler.misc.arg.length.mismatch) - compiler.note.unchecked.filename: T6326754.java - compiler.note.unchecked.recompile 4 errors diff --git a/langtools/test/tools/javac/T6587674.java b/langtools/test/tools/javac/T6587674.java new file mode 100644 index 00000000000..9f51d2c2a99 --- /dev/null +++ b/langtools/test/tools/javac/T6587674.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6587674 + * @summary NoClassdefFound when anonymously extending a class. + */ + +import java.util.Vector; + +public class T6587674 { + private static final Vector list = + true ? null : new Vector() { }; + + public static void main(String[] args) { + System.out.println("T6587674 runs fine!"); + } +} diff --git a/langtools/test/tools/javac/api/TestJavacTaskScanner.java b/langtools/test/tools/javac/api/TestJavacTaskScanner.java index 245e2f6edb7..40bde1679e5 100644 --- a/langtools/test/tools/javac/api/TestJavacTaskScanner.java +++ b/langtools/test/tools/javac/api/TestJavacTaskScanner.java @@ -1,5 +1,5 @@ /* - * 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. * * This code is free software; you can redistribute it and/or modify it @@ -31,8 +31,8 @@ */ import com.sun.tools.javac.api.JavacTaskImpl; -import com.sun.tools.javac.parser.*; // XXX -import com.sun.tools.javac.util.*; // XXX +import com.sun.tools.javac.parser.*; +import com.sun.tools.javac.util.*; import java.io.*; import java.net.*; import java.nio.*; @@ -65,7 +65,7 @@ public class TestJavacTaskScanner extends ToolTester { fm.getJavaFileObjects(new File[] {file}); StandardJavaFileManager fm = getLocalFileManager(tool, null, null); task = (JavacTaskImpl)tool.getTask(null, fm, null, null, null, compilationUnits); - task.getContext().put(Scanner.Factory.scannerFactoryKey, + task.getContext().put(ScannerFactory.scannerFactoryKey, new MyScanner.Factory(task.getContext(), this)); elements = task.getElements(); types = task.getTypes(); @@ -170,34 +170,36 @@ public class TestJavacTaskScanner extends ToolTester { class MyScanner extends Scanner { - public static class Factory extends Scanner.Factory { + public static class Factory extends ScannerFactory { public Factory(Context context, TestJavacTaskScanner test) { super(context); this.test = test; } @Override - public Scanner newScanner(CharSequence input) { + public Scanner newScanner(CharSequence input, boolean keepDocComments) { + assert !keepDocComments; if (input instanceof CharBuffer) { return new MyScanner(this, (CharBuffer)input, test); } else { char[] array = input.toString().toCharArray(); - return newScanner(array, array.length); + return newScanner(array, array.length, keepDocComments); } } @Override - public Scanner newScanner(char[] input, int inputLength) { + public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) { + assert !keepDocComments; return new MyScanner(this, input, inputLength, test); } private TestJavacTaskScanner test; } - protected MyScanner(Factory fac, CharBuffer buffer, TestJavacTaskScanner test) { + protected MyScanner(ScannerFactory fac, CharBuffer buffer, TestJavacTaskScanner test) { super(fac, buffer); this.test = test; } - protected MyScanner(Factory fac, char[] input, int inputLength, TestJavacTaskScanner test) { + protected MyScanner(ScannerFactory fac, char[] input, int inputLength, TestJavacTaskScanner test) { super(fac, input, inputLength); this.test = test; } diff --git a/langtools/test/tools/javac/diags/Example.java b/langtools/test/tools/javac/diags/Example.java index 9b833f65989..2cb3a414d2e 100644 --- a/langtools/test/tools/javac/diags/Example.java +++ b/langtools/test/tools/javac/diags/Example.java @@ -401,7 +401,7 @@ class Example implements Comparable { } } for (JCDiagnostic sd: d.getSubdiagnostics()) - scanForKeys(d, keys); + scanForKeys(sd, keys); } } diff --git a/langtools/test/tools/javac/diags/examples.not-yet.txt b/langtools/test/tools/javac/diags/examples.not-yet.txt index 40ddcf385f4..1a1fe5101aa 100644 --- a/langtools/test/tools/javac/diags/examples.not-yet.txt +++ b/langtools/test/tools/javac/diags/examples.not-yet.txt @@ -3,7 +3,7 @@ compiler.err.already.defined.this.unit # seems to be masked by compiler.err.annotation.value.not.allowable.type # cannot happen: precluded by complete type-specific tests compiler.err.assignment.from.super-bound # DEAD compiler.err.assignment.to.extends-bound # DEAD -compiler.err.cant.apply.symbol.1 +compiler.err.cant.apply.symbol compiler.err.cant.read.file # (apt.JavaCompiler?) compiler.err.cant.select.static.class.from.param.type compiler.err.illegal.char.for.encoding @@ -43,7 +43,6 @@ compiler.err.undetermined.type compiler.err.unexpected.type compiler.err.unknown.enum.constant # in bad class file compiler.err.unsupported.cross.fp.lit # Scanner: host system dependent -compiler.misc.arg.length.mismatch compiler.misc.assignment.from.super-bound compiler.misc.assignment.to.extends-bound compiler.misc.bad.class.file.header # bad class file @@ -73,7 +72,6 @@ compiler.misc.kindname.static compiler.misc.kindname.type.variable compiler.misc.kindname.type.variable.bound compiler.misc.kindname.value -compiler.misc.no.conforming.assignment.exists compiler.misc.non.denotable.type compiler.misc.no.unique.minimal.instance.exists compiler.misc.resume.abort # prompt for a response diff --git a/langtools/test/tools/javac/diags/examples/ExplicitParamsDoNotConformToBounds.java b/langtools/test/tools/javac/diags/examples/ExplicitParamsDoNotConformToBounds.java new file mode 100644 index 00000000000..255a09c8cbb --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/ExplicitParamsDoNotConformToBounds.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 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. + * + * 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. + */ + +// key: compiler.err.cant.apply.symbol.1 +// key: compiler.misc.explicit.param.do.not.conform.to.bounds + +class ExplicitParamsDoNotConformToBounds { + void m() {} + { this.m(); } +} diff --git a/langtools/test/tools/javac/diags/examples/InapplicableSymbols.java b/langtools/test/tools/javac/diags/examples/InapplicableSymbols.java new file mode 100644 index 00000000000..17ee4a1f9ec --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/InapplicableSymbols.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 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. + * + * 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. + */ + +// key: compiler.err.cant.apply.symbols +// key: compiler.misc.arg.length.mismatch +// key: compiler.misc.inapplicable.method + +class ExplicitParamsDoNotConformToBounds { + void m(int i1) {} + void m(int i1, int i2) {} + { this.m(); } +} diff --git a/langtools/test/tools/javac/diags/examples/IncompatibleTypes1.java b/langtools/test/tools/javac/diags/examples/IncompatibleTypes1.java index 25b5edc2601..1305d7ff75d 100644 --- a/langtools/test/tools/javac/diags/examples/IncompatibleTypes1.java +++ b/langtools/test/tools/javac/diags/examples/IncompatibleTypes1.java @@ -22,7 +22,7 @@ */ // key: compiler.misc.incompatible.types.1 -// key: compiler.misc.no.conforming.instance.exists +// key: compiler.misc.infer.no.conforming.instance.exists // key: compiler.err.prob.found.req class IncompatibleTypes1 { diff --git a/langtools/test/tools/javac/diags/examples/InferArgsLengthMismatch.java b/langtools/test/tools/javac/diags/examples/InferArgsLengthMismatch.java new file mode 100644 index 00000000000..28411b4a4a4 --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/InferArgsLengthMismatch.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 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. + * + * 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. + */ + +// key: compiler.err.cant.apply.symbol.1 +// key: compiler.misc.infer.arg.length.mismatch + +class InferArgsLengthMismatch { + void m(X x1, X x2) {} + { this.m(1); } +} diff --git a/langtools/test/tools/javac/diags/examples/KindnameConstructor.java b/langtools/test/tools/javac/diags/examples/KindnameConstructor.java index a8a47cf6fff..c451c3a3ad9 100644 --- a/langtools/test/tools/javac/diags/examples/KindnameConstructor.java +++ b/langtools/test/tools/javac/diags/examples/KindnameConstructor.java @@ -24,7 +24,9 @@ // key: compiler.misc.kindname.constructor // key: compiler.misc.kindname.class // key: compiler.misc.no.args -// key: compiler.err.cant.apply.symbol +// key: compiler.err.cant.apply.symbol.1 +// key: compiler.misc.arg.length.mismatch +// key: compiler.misc.no.conforming.assignment.exists // key: compiler.misc.count.error.plural // run: backdoor diff --git a/langtools/test/tools/javac/diags/examples/NoArgs.java b/langtools/test/tools/javac/diags/examples/NoArgs.java index f4b6b931c00..59c27950b78 100644 --- a/langtools/test/tools/javac/diags/examples/NoArgs.java +++ b/langtools/test/tools/javac/diags/examples/NoArgs.java @@ -22,7 +22,8 @@ */ // key: compiler.misc.no.args -// key: compiler.err.cant.apply.symbol +// key: compiler.err.cant.apply.symbol.1 +// key: compiler.misc.arg.length.mismatch // run: simple class X { diff --git a/langtools/test/tools/javac/diags/examples/VarargsArgumentMismatch.java b/langtools/test/tools/javac/diags/examples/VarargsArgumentMismatch.java new file mode 100644 index 00000000000..62ac55217f5 --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/VarargsArgumentMismatch.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 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. + * + * 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. + */ + +// key: compiler.err.cant.apply.symbol.1 +// key: compiler.misc.varargs.argument.mismatch + +class VarargsArgumentMismatch { + void m(String s, Integer... is) {} + { this.m("1", "2", "3"); } +} diff --git a/langtools/test/tools/javac/diags/examples/WhereCaptured.java b/langtools/test/tools/javac/diags/examples/WhereCaptured.java index 7eda22fb464..78ded49f606 100644 --- a/langtools/test/tools/javac/diags/examples/WhereCaptured.java +++ b/langtools/test/tools/javac/diags/examples/WhereCaptured.java @@ -25,7 +25,8 @@ // key: compiler.misc.where.description.captured.1 // key: compiler.misc.where.description.typevar // key: compiler.misc.where.typevar -// key: compiler.err.cant.apply.symbol +// key: compiler.err.cant.apply.symbol.1 +// key: compiler.misc.infer.no.conforming.assignment.exists // key: compiler.misc.captured.type // options: -XDdiags=where,simpleNames // run: simple diff --git a/langtools/test/tools/javac/diags/examples/WhereCaptured1.java b/langtools/test/tools/javac/diags/examples/WhereCaptured1.java index 397b022b01e..28ef10a4739 100644 --- a/langtools/test/tools/javac/diags/examples/WhereCaptured1.java +++ b/langtools/test/tools/javac/diags/examples/WhereCaptured1.java @@ -25,7 +25,8 @@ // key: compiler.misc.where.description.captured.1 // key: compiler.misc.where.description.typevar // key: compiler.misc.where.typevar -// key: compiler.err.cant.apply.symbol +// key: compiler.err.cant.apply.symbol.1 +// key: compiler.misc.infer.no.conforming.assignment.exists // key: compiler.misc.captured.type // key: compiler.misc.type.null // options: -XDdiags=where,simpleNames diff --git a/langtools/test/tools/javac/diags/examples/WhereTypeVar.java b/langtools/test/tools/javac/diags/examples/WhereTypeVar.java index dc307fc5f98..f7c41d6ea79 100644 --- a/langtools/test/tools/javac/diags/examples/WhereTypeVar.java +++ b/langtools/test/tools/javac/diags/examples/WhereTypeVar.java @@ -24,7 +24,8 @@ // key: compiler.misc.where.typevar // key: compiler.misc.where.description.typevar.1 // key: compiler.misc.type.var -// key: compiler.err.cant.apply.symbol +// key: compiler.err.cant.apply.symbol.1 +// key: compiler.misc.no.conforming.assignment.exists // options: -XDdiags=where,disambiguateTvars // run: simple diff --git a/langtools/test/tools/javac/generics/diamond/neg/Neg06.out b/langtools/test/tools/javac/generics/diamond/neg/Neg06.out index eaf8633c51f..0347e2f1b12 100644 --- a/langtools/test/tools/javac/generics/diamond/neg/Neg06.out +++ b/langtools/test/tools/javac/generics/diamond/neg/Neg06.out @@ -1,4 +1,4 @@ -Neg06.java:18:36: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.IFoo), (compiler.misc.no.conforming.instance.exists: X, Neg06.IFoo, Neg06.ISuperFoo) -Neg06.java:19:37: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.no.conforming.instance.exists: X, Neg06.CFoo, Neg06.CSuperFoo) -Neg06.java:20:37: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.no.conforming.instance.exists: X, Neg06.CFoo, Neg06.CSuperFoo) +Neg06.java:18:36: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.IFoo), (compiler.misc.infer.no.conforming.instance.exists: X, Neg06.IFoo, Neg06.ISuperFoo) +Neg06.java:19:37: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.infer.no.conforming.instance.exists: X, Neg06.CFoo, Neg06.CSuperFoo) +Neg06.java:20:37: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.infer.no.conforming.instance.exists: X, Neg06.CFoo, Neg06.CSuperFoo) 3 errors diff --git a/langtools/test/tools/javac/generics/inference/6315770/T6315770.out b/langtools/test/tools/javac/generics/inference/6315770/T6315770.out index 67967d0c8ee..befd56eb63e 100644 --- a/langtools/test/tools/javac/generics/inference/6315770/T6315770.out +++ b/langtools/test/tools/javac/generics/inference/6315770/T6315770.out @@ -1,3 +1,3 @@ T6315770.java:16:42: compiler.err.undetermined.type.1: T6315770, (compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable) -T6315770.java:17:40: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: T, T6315770, T6315770)), T6315770, T6315770 +T6315770.java:17:40: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, T6315770, T6315770)), T6315770, T6315770 2 errors diff --git a/langtools/test/tools/javac/generics/inference/6611449/T6611449.out b/langtools/test/tools/javac/generics/inference/6611449/T6611449.out index e5ff00a6d2b..388f3b7c752 100644 --- a/langtools/test/tools/javac/generics/inference/6611449/T6611449.out +++ b/langtools/test/tools/javac/generics/inference/6611449/T6611449.out @@ -1,5 +1,5 @@ -T6611449.java:18:9: compiler.err.cant.resolve.location.args: kindname.constructor, T6611449, , int, kindname.class, T6611449 -T6611449.java:19:9: compiler.err.cant.resolve.location.args: kindname.constructor, T6611449, , int,int, kindname.class, T6611449 -T6611449.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m1, T, int, kindname.class, T6611449, null -T6611449.java:21:9: compiler.err.cant.apply.symbol: kindname.method, m2, T,T, int,int, kindname.class, T6611449, null +T6611449.java:18:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T,T), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T), (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S))} +T6611449.java:19:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T,T), (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T), (compiler.misc.infer.arg.length.mismatch))} +T6611449.java:20:9: compiler.err.cant.apply.symbol.1: kindname.method, m1, T, int, kindname.class, T6611449, (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S) +T6611449.java:21:9: compiler.err.cant.apply.symbol.1: kindname.method, m2, T,T, int,int, kindname.class, T6611449, (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S) 4 errors diff --git a/langtools/test/tools/javac/generics/inference/6638712/T6638712a.out b/langtools/test/tools/javac/generics/inference/6638712/T6638712a.out index e20744cc1b8..c65e749bd55 100644 --- a/langtools/test/tools/javac/generics/inference/6638712/T6638712a.out +++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712a.out @@ -1,2 +1,2 @@ -T6638712a.java:16:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: T, java.util.Comparator, java.util.Comparator)), java.util.Comparator, java.util.Comparator +T6638712a.java:16:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, java.util.Comparator, java.util.Comparator)), java.util.Comparator, java.util.Comparator 1 error diff --git a/langtools/test/tools/javac/generics/inference/6638712/T6638712b.out b/langtools/test/tools/javac/generics/inference/6638712/T6638712b.out index ed77740a425..003315022db 100644 --- a/langtools/test/tools/javac/generics/inference/6638712/T6638712b.out +++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712b.out @@ -1,2 +1,2 @@ -T6638712b.java:14:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: T, T, java.lang.String)), T, java.lang.String +T6638712b.java:14:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, T, java.lang.String)), T, java.lang.String 1 error diff --git a/langtools/test/tools/javac/generics/inference/6638712/T6638712c.out b/langtools/test/tools/javac/generics/inference/6638712/T6638712c.out index 8b0db849a79..d57185e23c6 100644 --- a/langtools/test/tools/javac/generics/inference/6638712/T6638712c.out +++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712c.out @@ -1,2 +1,2 @@ -T6638712c.java:16:9: compiler.err.cant.apply.symbol: kindname.method, sort, T[],java.util.Comparator, java.lang.Enum[],java.util.Comparator>, kindname.class, T6638712c, null +T6638712c.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, sort, T[],java.util.Comparator, java.lang.Enum[],java.util.Comparator>, kindname.class, T6638712c, (compiler.misc.inferred.do.not.conform.to.params: java.lang.Enum[],java.util.Comparator, java.lang.Enum[],java.util.Comparator>) 1 error diff --git a/langtools/test/tools/javac/generics/inference/6638712/T6638712d.out b/langtools/test/tools/javac/generics/inference/6638712/T6638712d.out index c8c574044eb..1b0285a9c23 100644 --- a/langtools/test/tools/javac/generics/inference/6638712/T6638712d.out +++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712d.out @@ -1,2 +1,2 @@ -T6638712d.java:16:9: compiler.err.cant.apply.symbol: kindname.method, m, U,java.util.List>, int,java.util.List>, kindname.class, T6638712d, null +T6638712d.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, U,java.util.List>, int,java.util.List>, kindname.class, T6638712d, (compiler.misc.inferred.do.not.conform.to.params: java.lang.String,java.util.List>, int,java.util.List>) 1 error diff --git a/langtools/test/tools/javac/generics/inference/6638712/T6638712e.out b/langtools/test/tools/javac/generics/inference/6638712/T6638712e.out index 1ca268b830b..3216ed28cca 100644 --- a/langtools/test/tools/javac/generics/inference/6638712/T6638712e.out +++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712e.out @@ -1,2 +1,2 @@ -T6638712e.java:17:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: X, T6638712e.Foo, T6638712e.Foo)), T6638712e.Foo, T6638712e.Foo +T6638712e.java:17:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: X, T6638712e.Foo, T6638712e.Foo)), T6638712e.Foo, T6638712e.Foo 1 error diff --git a/langtools/test/tools/javac/lib/JavacTestingAbstractProcessor.java b/langtools/test/tools/javac/lib/JavacTestingAbstractProcessor.java new file mode 100644 index 00000000000..2706782b10d --- /dev/null +++ b/langtools/test/tools/javac/lib/JavacTestingAbstractProcessor.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import static javax.lang.model.SourceVersion.*; +import javax.lang.model.element.*; +import javax.lang.model.util.*; + +/** + * An abstract annotation processor tailored to javac regression testing. + */ +public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { + private static final Set allAnnotations; + + static { + Set tmp = new HashSet<>(); + tmp.add("*"); + allAnnotations = Collections.unmodifiableSet(tmp); + } + + protected Elements eltUtils; + protected Elements elements; + protected Types typeUtils; + protected Types types; + protected Filer filer; + protected Messager messager; + protected Map options; + + /** + * Constructor for subclasses to call. + */ + protected JavacTestingAbstractProcessor() { + super(); + } + + /** + * Return the latest source version. Unless this method is + * overridden, an {@code IllegalStateException} will be thrown if a + * subclass has a {@code SupportedSourceVersion} annotation. + */ + @Override + public SourceVersion getSupportedSourceVersion() { + SupportedSourceVersion ssv = this.getClass().getAnnotation(SupportedSourceVersion.class); + if (ssv != null) + throw new IllegalStateException("SupportedSourceVersion annotation not supported here."); + + return SourceVersion.latest(); + } + + /** + * If the processor class is annotated with {@link + * SupportedAnnotationTypes}, return an unmodifiable set with the + * same set of strings as the annotation. If the class is not so + * annotated, a one-element set containing {@code "*"} is returned + * to indicate all annotations are processed. + * + * @return the names of the annotation types supported by this + * processor, or an empty set if none + */ + @Override + public Set getSupportedAnnotationTypes() { + SupportedAnnotationTypes sat = this.getClass().getAnnotation(SupportedAnnotationTypes.class); + if (sat != null) + return super.getSupportedAnnotationTypes(); + else + return allAnnotations; + } + + @Override + public void init(ProcessingEnvironment processingEnv) { + super.init(processingEnv); + elements = eltUtils = processingEnv.getElementUtils(); + types = typeUtils = processingEnv.getTypeUtils(); + filer = processingEnv.getFiler(); + messager = processingEnv.getMessager(); + options = processingEnv.getOptions(); + } +} diff --git a/langtools/test/tools/javac/processing/6348499/A.java b/langtools/test/tools/javac/processing/6348499/A.java index 9bdafaee3e2..b5b3aaf37f2 100644 --- a/langtools/test/tools/javac/processing/6348499/A.java +++ b/langtools/test/tools/javac/processing/6348499/A.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -27,10 +27,8 @@ import javax.annotation.processing.*; import javax.lang.model.*; import javax.lang.model.element.*; -@SupportedAnnotationTypes("*") -public class A extends AbstractProcessor { +public class A extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment renv) { - Filer filer = processingEnv.getFiler(); try { OutputStream out = filer.createClassFile(getClass().getName()+"_0").openOutputStream(); out.close(); @@ -39,8 +37,4 @@ public class A extends AbstractProcessor { } return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/6348499/T6348499.java b/langtools/test/tools/javac/processing/6348499/T6348499.java index e558cc12972..25e2a07a03f 100644 --- a/langtools/test/tools/javac/processing/6348499/T6348499.java +++ b/langtools/test/tools/javac/processing/6348499/T6348499.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -25,7 +25,8 @@ * @test * @bug 6441871 * @summary javac crashes at com.sun.tools.javac.jvm.ClassReader$BadClassFile - * @build A + * @library ../../lib + * @build JavacTestingAbstractProcessor A * @run main T6348499 */ @@ -54,7 +55,6 @@ public class T6348499 { fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "A.java"))); Iterable opts = Arrays.asList("-proc:only", "-processor", "A", - "-source", "1.6", "-processorpath", testClasses); StringWriter out = new StringWriter(); JavacTask task = tool.getTask(out, fm, dl, opts, null, files); diff --git a/langtools/test/tools/javac/processing/6359313/T6359313.java b/langtools/test/tools/javac/processing/6359313/T6359313.java index 025a4821a00..719ea12ff12 100644 --- a/langtools/test/tools/javac/processing/6359313/T6359313.java +++ b/langtools/test/tools/javac/processing/6359313/T6359313.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,8 @@ * @bug 6359313 * @summary error compiling annotated package * @author Peter von der Ah\u00e9 + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile T6359313.java * @compile -processor T6359313 package-info.java Foo.java */ @@ -37,7 +39,7 @@ import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.element.TypeElement; @SupportedAnnotationTypes("Foo") -public class T6359313 extends AbstractProcessor { +public class T6359313 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { return true; diff --git a/langtools/test/tools/javac/processing/6365040/ProcBar.java b/langtools/test/tools/javac/processing/6365040/ProcBar.java index 1fd93bc6acb..3241692b08d 100644 --- a/langtools/test/tools/javac/processing/6365040/ProcBar.java +++ b/langtools/test/tools/javac/processing/6365040/ProcBar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -31,13 +31,11 @@ import static javax.tools.Diagnostic.Kind.*; /** * Second of several processors to run. */ -@SupportedAnnotationTypes("*") -public class ProcBar extends AbstractProcessor { +public class ProcBar extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { if (!roundEnvironment.processingOver()) - processingEnv.getMessager().printMessage(NOTE, - "Hello from ProcBar"); + messager.printMessage(NOTE, "Hello from ProcBar"); return false; } } diff --git a/langtools/test/tools/javac/processing/6365040/ProcFoo.java b/langtools/test/tools/javac/processing/6365040/ProcFoo.java index f86d0ddbec1..14cdec25ade 100644 --- a/langtools/test/tools/javac/processing/6365040/ProcFoo.java +++ b/langtools/test/tools/javac/processing/6365040/ProcFoo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -31,13 +31,11 @@ import static javax.tools.Diagnostic.Kind.*; /** * First of several processors to run. */ -@SupportedAnnotationTypes("*") -public class ProcFoo extends AbstractProcessor { +public class ProcFoo extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { if (!roundEnvironment.processingOver()) - processingEnv.getMessager().printMessage(NOTE, - "Hello from ProcFoo"); + messager.printMessage(NOTE, "Hello from ProcFoo"); return false; } } diff --git a/langtools/test/tools/javac/processing/6365040/T6365040.java b/langtools/test/tools/javac/processing/6365040/T6365040.java index 5215459bee7..0b1e0dc851c 100644 --- a/langtools/test/tools/javac/processing/6365040/T6365040.java +++ b/langtools/test/tools/javac/processing/6365040/T6365040.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,8 @@ * @bug 6365040 6358129 * @summary Test -processor foo,bar,baz * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile ProcFoo.java * @compile ProcBar.java * @compile T6365040.java @@ -43,13 +45,11 @@ import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.element.TypeElement; import static javax.tools.Diagnostic.Kind.*; -@SupportedAnnotationTypes("*") -public class T6365040 extends AbstractProcessor { +public class T6365040 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { if (!roundEnvironment.processingOver()) - processingEnv.getMessager().printMessage(NOTE, - "Hello from T6365040"); + messager.printMessage(NOTE, "Hello from T6365040"); return true; } } diff --git a/langtools/test/tools/javac/processing/6413690/T6413690.java b/langtools/test/tools/javac/processing/6413690/T6413690.java index c51586263ab..a4b2b3fab33 100644 --- a/langtools/test/tools/javac/processing/6413690/T6413690.java +++ b/langtools/test/tools/javac/processing/6413690/T6413690.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,8 @@ * @bug 6413690 6380018 * @summary JavacProcessingEnvironment does not enter trees from preceding rounds * @author Peter von der Ah\u00e9 + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile T6413690.java * @compile -XDfatalEnterError -verbose -processor T6413690 src/Super.java TestMe.java */ @@ -42,11 +44,9 @@ import javax.lang.model.element.TypeElement; import javax.lang.model.util.Elements; @SupportedAnnotationTypes("TestMe") -public class T6413690 extends AbstractProcessor { +public class T6413690 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { - Elements elements = processingEnv.getElementUtils(); - Filer filer = processingEnv.getFiler(); TypeElement testMe = elements.getTypeElement(TestMe.class.getName()); Set supers = roundEnvironment.getElementsAnnotatedWith(testMe); try { diff --git a/langtools/test/tools/javac/processing/6414633/A.java b/langtools/test/tools/javac/processing/6414633/A.java index 814106a7aef..13754d09cbe 100644 --- a/langtools/test/tools/javac/processing/6414633/A.java +++ b/langtools/test/tools/javac/processing/6414633/A.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -29,9 +29,8 @@ import javax.lang.model.*; import javax.lang.model.element.*; import javax.tools.*; -@SupportedAnnotationTypes("*") -public class A extends AbstractProcessor { - +@SuppressWarnings("") +public class A extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { Messager m = processingEnv.getMessager(); for (TypeElement anno: annotations) { @@ -42,8 +41,6 @@ public class A extends AbstractProcessor { return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } + @SuppressWarnings("") + private void foo() {} } diff --git a/langtools/test/tools/javac/processing/6414633/T6414633.java b/langtools/test/tools/javac/processing/6414633/T6414633.java index 29ef3caf599..0ae395153cb 100644 --- a/langtools/test/tools/javac/processing/6414633/T6414633.java +++ b/langtools/test/tools/javac/processing/6414633/T6414633.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -25,7 +25,8 @@ * @test * @bug 6414633 6440109 * @summary Only the first processor message at a source location is reported - * @build A T6414633 + * @library ../../lib + * @build JavacTestingAbstractProcessor A T6414633 * @run main T6414633 */ @@ -55,8 +56,7 @@ public class T6414633 { fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, A.class.getName()+".java"))); String[] opts = { "-proc:only", "-processor", A.class.getName(), - "-source", "1.6", - "-classpath", testClasses }; + "-classpath", testClasses + System.getProperty("path.separator") + "../../lib" }; JavacTask task = tool.getTask(null, fm, dl, Arrays.asList(opts), null, files); task.call(); diff --git a/langtools/test/tools/javac/processing/6430209/T6430209.java b/langtools/test/tools/javac/processing/6430209/T6430209.java index 69b7bf5d294..0f65f86be07 100644 --- a/langtools/test/tools/javac/processing/6430209/T6430209.java +++ b/langtools/test/tools/javac/processing/6430209/T6430209.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -25,7 +25,8 @@ * @test * @bug 6441871 * @summary spurious compiler error elicited by packageElement.getEnclosedElements() - * @build b6341534 + * @library ../../lib + * @build JavacTestingAbstractProcessor b6341534 * @run main T6430209 */ @@ -54,7 +55,7 @@ public class T6430209 { // run annotation processor b6341534 so we can check diagnostics // -proc:only -processor b6341534 -cp . ./src/*.java String testSrc = System.getProperty("test.src", "."); - String testClasses = System.getProperty("test.classes"); + String testClasses = System.getProperty("test.classes") + System.getProperty("path.separator") + "../../lib"; JavacTool tool = JavacTool.create(); MyDiagListener dl = new MyDiagListener(); StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); diff --git a/langtools/test/tools/javac/processing/6430209/b6341534.java b/langtools/test/tools/javac/processing/6430209/b6341534.java index cc52af24a39..5dfad046c90 100644 --- a/langtools/test/tools/javac/processing/6430209/b6341534.java +++ b/langtools/test/tools/javac/processing/6430209/b6341534.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -30,16 +30,9 @@ import static javax.tools.Diagnostic.Kind.*; import java.util.*; import java.util.Set; -@SupportedAnnotationTypes({"*"}) -public class b6341534 extends AbstractProcessor { +public class b6341534 extends JavacTestingAbstractProcessor { static int r = 0; - static Elements E = null; - static Messager msgr = null; - public void init(ProcessingEnvironment penv) { - processingEnv = penv; - msgr = penv.getMessager(); - E = penv.getElementUtils(); - } + //Create directory 'dir1' and a test class in dir1 public boolean process(Set tes, RoundEnvironment renv) { @@ -49,13 +42,13 @@ public class b6341534 extends AbstractProcessor { System.out.println("Round"+r+ ": " + t.toString()); try { - PackageElement PE = E.getPackageElement("dir1"); + PackageElement PE = eltUtils.getPackageElement("dir1"); List LEE = PE.getEnclosedElements(); /* <=This line elicits the error message. */ for(Element e : LEE) System.out.println("found " + e.toString() + " in dir1."); } catch(NullPointerException npe) { - msgr.printMessage(ERROR,npe.toString()); + messager.printMessage(ERROR,npe.toString()); //npe.printStackTrace(); return false; } @@ -63,13 +56,8 @@ public class b6341534 extends AbstractProcessor { // on round 1, expect errorRaised == false && processingOver == false // on round 2, expect errorRaised == true && processingOver == true if( renv.errorRaised() != renv.processingOver()) { - msgr.printMessage(ERROR, "FAILED"); + messager.printMessage(ERROR, "FAILED"); } return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/6499119/ClassProcessor.java b/langtools/test/tools/javac/processing/6499119/ClassProcessor.java index 900474e8460..b2b7203c0e7 100644 --- a/langtools/test/tools/javac/processing/6499119/ClassProcessor.java +++ b/langtools/test/tools/javac/processing/6499119/ClassProcessor.java @@ -32,20 +32,17 @@ import javax.tools.Diagnostic.Kind; * @test * @bug 6499119 * @summary Created package-info class file modeled improperly + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile ClassProcessor.java package-info.java * @compile/process -cp . -processor ClassProcessor -Akind=java java.lang.Object * @compile/process -cp . -processor ClassProcessor -Akind=class java.lang.Object */ @SupportedOptions({ "gen", "expect" }) -@SupportedAnnotationTypes({"*"}) -public class ClassProcessor extends AbstractProcessor { +public class ClassProcessor extends JavacTestingAbstractProcessor { int round = 1; - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - public boolean process(Set annotations, RoundEnvironment roundEnv) { if (round == 1) { System.out.println("-- Round 1 --"); @@ -71,8 +68,6 @@ public class ClassProcessor extends AbstractProcessor { } private void createPackageFile() { - Filer filer = processingEnv.getFiler(); - String kind = processingEnv.getOptions().get("kind"); File pkgInfo; @@ -125,7 +120,6 @@ public class ClassProcessor extends AbstractProcessor { } private void error(String msg) { - Messager messager = processingEnv.getMessager(); messager.printMessage(Kind.ERROR, msg); } } diff --git a/langtools/test/tools/javac/processing/6511613/DummyProcessor.java b/langtools/test/tools/javac/processing/6511613/DummyProcessor.java index a5307f2f1ca..c05537ed6ec 100644 --- a/langtools/test/tools/javac/processing/6511613/DummyProcessor.java +++ b/langtools/test/tools/javac/processing/6511613/DummyProcessor.java @@ -26,15 +26,10 @@ import javax.lang.model.*; import javax.lang.model.element.*; import java.util.Set; -@SupportedAnnotationTypes("*") -public class DummyProcessor extends AbstractProcessor { +public class DummyProcessor extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/6511613/clss41701.java b/langtools/test/tools/javac/processing/6511613/clss41701.java index 1d5c7819f2e..670ae5e269f 100644 --- a/langtools/test/tools/javac/processing/6511613/clss41701.java +++ b/langtools/test/tools/javac/processing/6511613/clss41701.java @@ -26,7 +26,8 @@ * @bug 6511613 * @summary javac unexpectedly doesn't fail in some cases if an annotation processor specified * - * @build DummyProcessor + * @library ../../lib + * @build JavacTestingAbstractProcessor DummyProcessor * @compile/fail clss41701.java * @compile/fail -processor DummyProcessor clss41701.java */ diff --git a/langtools/test/tools/javac/processing/6512707/T6512707.java b/langtools/test/tools/javac/processing/6512707/T6512707.java index 505528fd8ee..26c72f9ff95 100644 --- a/langtools/test/tools/javac/processing/6512707/T6512707.java +++ b/langtools/test/tools/javac/processing/6512707/T6512707.java @@ -1,5 +1,5 @@ /* - * 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. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,9 @@ * @bug 6512707 * @summary "incompatible types" after (unrelated) annotation processing * @author Peter Runge + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile T6512707.java - * * @compile -processor T6512707 TestAnnotation.java */ @@ -41,16 +42,10 @@ import javax.lang.model.util.*; * Dummy processor to force bug 6512707 to show - it does not matter what * the annotation processor does for this bug. */ -@SupportedAnnotationTypes("*") -public class T6512707 extends AbstractProcessor { +public class T6512707 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { - return(false); - } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); + return false; } } diff --git a/langtools/test/tools/javac/processing/6634138/T6634138.java b/langtools/test/tools/javac/processing/6634138/T6634138.java index c7ce94b6e26..54409e5ecb4 100644 --- a/langtools/test/tools/javac/processing/6634138/T6634138.java +++ b/langtools/test/tools/javac/processing/6634138/T6634138.java @@ -26,6 +26,8 @@ * @bug 6634138 * @author Joseph D. Darcy * @summary Verify source files output after processing is over are compiled + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile T6634138.java * @compile -processor T6634138 Dummy.java * @run main ExerciseDependency @@ -44,10 +46,7 @@ import javax.lang.model.SourceVersion; import javax.lang.model.element.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") -public class T6634138 extends AbstractProcessor { - private Filer filer; - +public class T6634138 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { // Write out files *after* processing is over. @@ -77,16 +76,6 @@ public class T6634138 extends AbstractProcessor { } return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - filer = processingEnv.getFiler(); - } } diff --git a/langtools/test/tools/javac/processing/T6439826.java b/langtools/test/tools/javac/processing/T6439826.java index 91c36aeed51..ac484655f37 100644 --- a/langtools/test/tools/javac/processing/T6439826.java +++ b/langtools/test/tools/javac/processing/T6439826.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -48,8 +48,7 @@ public class T6439826 extends AbstractProcessor { StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); Iterable files = fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6439826.class.getName()+".java"))); - Iterable opts = Arrays.asList("-source","1.6", - "-proc:only", + Iterable opts = Arrays.asList("-proc:only", "-processor", "T6439826", "-processorpath", testClasses); StringWriter out = new StringWriter(); diff --git a/langtools/test/tools/javac/processing/T6920317.java b/langtools/test/tools/javac/processing/T6920317.java index 981607cf01c..1f005090361 100644 --- a/langtools/test/tools/javac/processing/T6920317.java +++ b/langtools/test/tools/javac/processing/T6920317.java @@ -25,6 +25,7 @@ * @test * @bug 6920317 * @summary package-info.java file has to be specified on the javac cmdline, else it will not be avail + * @library ../lib */ import java.io.*; @@ -349,12 +350,7 @@ public class T6920317 { /** Annotation processor used to verify the expected value for the package annotations found by javac. */ @SupportedOptions({ "gen", "expect" }) - @SupportedAnnotationTypes({"*"}) - public static class Processor extends AbstractProcessor { - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - + public static class Processor extends JavacTestingAbstractProcessor { public boolean process(Set annots, RoundEnvironment renv) { round++; System.err.println("Round " + round + " annots:" + annots + " rootElems:" + renv.getRootElements()); diff --git a/langtools/test/tools/javac/processing/environment/TestSourceVersion.java b/langtools/test/tools/javac/processing/environment/TestSourceVersion.java index dc3e7773a03..28118bb7e0a 100644 --- a/langtools/test/tools/javac/processing/environment/TestSourceVersion.java +++ b/langtools/test/tools/javac/processing/environment/TestSourceVersion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,8 @@ * @bug 6402506 * @summary Test that getSourceVersion works properly * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestSourceVersion.java * @compile -processor TestSourceVersion -proc:only -source 1.2 -AExpectedVersion=RELEASE_2 HelloWorld.java * @compile -processor TestSourceVersion -proc:only -source 1.3 -AExpectedVersion=RELEASE_3 HelloWorld.java @@ -52,9 +54,8 @@ import static javax.tools.Diagnostic.Kind.*; * This processor checks that ProcessingEnvironment.getSourceVersion() * is consistent with the setting of the -source option. */ -@SupportedAnnotationTypes("*") @SupportedOptions("ExpectedVersion") -public class TestSourceVersion extends AbstractProcessor { +public class TestSourceVersion extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { @@ -68,9 +69,4 @@ public class TestSourceVersion extends AbstractProcessor { return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java b/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java index 22b180ad085..0bf241b8e80 100644 --- a/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java +++ b/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,8 @@ * @bug 6397298 6400986 6425592 6449798 6453386 6508401 6498938 6911854 * @summary Tests that getElementsAnnotatedWith works properly. * @author Joseph D. Darcy + * @library ../../../lib + * @build JavacTestingAbstractProcessor * @compile TestElementsAnnotatedWith.java * @compile InheritedAnnotation.java * @compile -processor TestElementsAnnotatedWith -proc:only SurfaceAnnotations.java @@ -57,16 +59,13 @@ import static javax.lang.model.util.ElementFilter.*; * getElementsAnnotatedWith is consistent with the expected results * stored in an AnnotatedElementInfo annotation. */ -@SupportedAnnotationTypes("*") @AnnotatedElementInfo(annotationName="java.lang.SuppressWarnings", expectedSize=0, names={}) -public class TestElementsAnnotatedWith extends AbstractProcessor { +public class TestElementsAnnotatedWith extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { - Elements elementUtils = processingEnv.getElementUtils(); - TypeElement annotatedElementInfoElement = - elementUtils.getTypeElement("AnnotatedElementInfo"); + elements.getTypeElement("AnnotatedElementInfo"); Set resultsMeta = Collections.emptySet(); Set resultsBase = Collections.emptySet(); @@ -93,9 +92,7 @@ public class TestElementsAnnotatedWith extends AbstractProcessor { resultsMeta = roundEnvironment. - getElementsAnnotatedWith(elementUtils. - getTypeElement(annotatedElementInfo. - annotationName())) ; + getElementsAnnotatedWith(elements.getTypeElement(annotatedElementInfo.annotationName())); System.err.println("Results: " + resultsMeta); @@ -167,9 +164,4 @@ public class TestElementsAnnotatedWith extends AbstractProcessor { throw new RuntimeException("Illegal argument exception not thrown"); } catch(IllegalArgumentException iae) {} } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/errors/TestFatalityOfParseErrors.java b/langtools/test/tools/javac/processing/errors/TestFatalityOfParseErrors.java index 0ba614d4274..cd42f6bd06a 100644 --- a/langtools/test/tools/javac/processing/errors/TestFatalityOfParseErrors.java +++ b/langtools/test/tools/javac/processing/errors/TestFatalityOfParseErrors.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,9 @@ * @bug 6403459 * @summary Test that generating programs with syntax errors is a fatal condition * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor + * @compile TestReturnCode.java * @compile TestFatalityOfParseErrors.java * @compile/fail -XprintRounds -processor TestFatalityOfParseErrors -proc:only TestFatalityOfParseErrors.java */ @@ -45,11 +48,8 @@ import java.io.IOException; * Write out an incomplete source file and observe that the next round * is marked as an error. */ -@SupportedAnnotationTypes("*") -public class TestFatalityOfParseErrors extends AbstractProcessor { +public class TestFatalityOfParseErrors extends JavacTestingAbstractProcessor { int round = 0; - Messager messager; - Filer filer; public boolean process(Set annotations, RoundEnvironment roundEnvironment) { @@ -87,14 +87,4 @@ public class TestFatalityOfParseErrors extends AbstractProcessor { } return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - messager = processingEnv.getMessager(); - filer = processingEnv.getFiler(); - } } diff --git a/langtools/test/tools/javac/processing/errors/TestOptionSyntaxErrors.java b/langtools/test/tools/javac/processing/errors/TestOptionSyntaxErrors.java index 6784def2cd5..4f2ad1b2243 100644 --- a/langtools/test/tools/javac/processing/errors/TestOptionSyntaxErrors.java +++ b/langtools/test/tools/javac/processing/errors/TestOptionSyntaxErrors.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,8 @@ * @bug 6406212 * @summary Test that annotation processor options with illegal syntax are rejected * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestOptionSyntaxErrors.java * @compile/fail -A TestOptionSyntaxErrors.java * @compile/fail -A8adOption TestOptionSyntaxErrors.java @@ -46,14 +48,9 @@ import static javax.tools.Diagnostic.Kind.*; /** * No-op processor; should not be run. */ -@SupportedAnnotationTypes("*") -public class TestOptionSyntaxErrors extends AbstractProcessor { +public class TestOptionSyntaxErrors extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/errors/TestReturnCode.java b/langtools/test/tools/javac/processing/errors/TestReturnCode.java index 61cb2a05b72..22c9aae24f7 100644 --- a/langtools/test/tools/javac/processing/errors/TestReturnCode.java +++ b/langtools/test/tools/javac/processing/errors/TestReturnCode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,8 @@ * @bug 6403468 * @summary Test that an erroneous return code results from raising an error. * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestReturnCode.java * * @compile -processor TestReturnCode -proc:only Foo.java @@ -60,20 +62,17 @@ import static javax.tools.Diagnostic.Kind.*; * This processor raises errors or throws exceptions on different * rounds to allow the return code to be test. */ -@SupportedAnnotationTypes("*") @SupportedOptions({"ErrorOnFirst", "ErrorOnLast", "ExceptionOnFirst", "ExceptionOnLast"}) -public class TestReturnCode extends AbstractProcessor { +public class TestReturnCode extends JavacTestingAbstractProcessor { private boolean errorOnFirst; private boolean errorOnLast; private boolean exceptionOnFirst; private boolean exceptionOnLast; - private Messager messager; - public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { @@ -103,11 +102,5 @@ public class TestReturnCode extends AbstractProcessor { errorOnLast = keySet.contains("ErrorOnLast"); exceptionOnFirst = keySet.contains("ExceptionOnFirst"); exceptionOnLast = keySet.contains("ExceptionOnLast"); - messager = processingEnv.getMessager(); - } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); } } diff --git a/langtools/test/tools/javac/processing/filer/TestFilerConstraints.java b/langtools/test/tools/javac/processing/filer/TestFilerConstraints.java index 7f3202eca30..8509fb2e15a 100644 --- a/langtools/test/tools/javac/processing/filer/TestFilerConstraints.java +++ b/langtools/test/tools/javac/processing/filer/TestFilerConstraints.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,7 @@ * @bug 6380018 6453386 6457283 * @summary Test that the constraints guaranteed by the Filer and maintained * @author Joseph D. Darcy + * @library ../../lib * @build TestFilerConstraints * @compile -encoding iso-8859-1 -processor TestFilerConstraints -proc:only TestFilerConstraints.java */ @@ -69,11 +70,8 @@ import java.nio.charset.Charset; * * */ -@SupportedAnnotationTypes("*") -public class TestFilerConstraints extends AbstractProcessor { +public class TestFilerConstraints extends JavacTestingAbstractProcessor { private int round = 0; - private Messager messager; - private Filer filer; private PrintWriter pw_src1 = null; private PrintWriter pw_src2 = null; @@ -167,17 +165,6 @@ public class TestFilerConstraints extends AbstractProcessor { return true; } - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - messager = processingEnv.getMessager(); - filer = processingEnv.getFiler(); - - } - /** * Test that the single expected expected type, name, is the root * element. diff --git a/langtools/test/tools/javac/processing/filer/TestGetResource.java b/langtools/test/tools/javac/processing/filer/TestGetResource.java index ee55a1a4389..5d5641214e1 100644 --- a/langtools/test/tools/javac/processing/filer/TestGetResource.java +++ b/langtools/test/tools/javac/processing/filer/TestGetResource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,7 +26,8 @@ * @bug 6380018 6449798 * @summary Test Filer.getResource * @author Joseph D. Darcy - * @build TestGetResource + * @library ../../lib + * @build JavacTestingAbstractProcessor TestGetResource * @compile -processor TestGetResource -proc:only -Aphase=write TestGetResource.java * @compile -processor TestGetResource -proc:only -Aphase=read TestGetResource.java */ @@ -49,13 +50,8 @@ import java.io.PrintWriter; * first run of the annotation processor, write out a resource file * and on the second run read it in. */ -@SupportedAnnotationTypes("*") @SupportedOptions("phase") -public class TestGetResource extends AbstractProcessor { - private Messager messager; - private Filer filer; - private Map options; - +public class TestGetResource extends JavacTestingAbstractProcessor { private static String CONTENTS = "Hello World."; private static String PKG = ""; private static String RESOURCE_NAME = "Resource1"; @@ -92,15 +88,4 @@ public class TestGetResource extends AbstractProcessor { } return false; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - messager = processingEnv.getMessager(); - filer = processingEnv.getFiler(); - options = processingEnv.getOptions(); - } } diff --git a/langtools/test/tools/javac/processing/filer/TestGetResource2.java b/langtools/test/tools/javac/processing/filer/TestGetResource2.java index 49befdf4e34..6ce067d4c31 100644 --- a/langtools/test/tools/javac/processing/filer/TestGetResource2.java +++ b/langtools/test/tools/javac/processing/filer/TestGetResource2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -24,6 +24,7 @@ /* @test * @bug 6929404 * @summary Filer.getResource(SOURCE_PATH, ...) does not work when -sourcepath contains >1 entry + * @library ../../lib */ import java.io.*; @@ -114,8 +115,7 @@ public class TestGetResource2 { throw new Exception(errors + " errors occurred"); } - @SupportedAnnotationTypes("*") - static class AnnoProc extends AbstractProcessor { + static class AnnoProc extends JavacTestingAbstractProcessor { public @Override boolean process(Set annotations, RoundEnvironment roundEnv) { if (roundEnv.processingOver()) { @@ -123,27 +123,23 @@ public class TestGetResource2 { } try { - FileObject resource = processingEnv.getFiler().getResource(StandardLocation.SOURCE_PATH, "resources", "file.txt"); + FileObject resource = filer.getResource(StandardLocation.SOURCE_PATH, "resources", "file.txt"); try { resource.openInputStream().close(); - processingEnv.getMessager().printMessage(Kind.NOTE, "found: " + resource.toUri()); + messager.printMessage(Kind.NOTE, "found: " + resource.toUri()); return true; } catch (IOException x) { - processingEnv.getMessager().printMessage(Kind.ERROR, "could not read: " + resource.toUri()); + messager.printMessage(Kind.ERROR, "could not read: " + resource.toUri()); x.printStackTrace(); } } catch (IOException x) { - processingEnv.getMessager().printMessage(Kind.ERROR, "did not find resource"); + messager.printMessage(Kind.ERROR, "did not find resource"); x.printStackTrace(); } return false; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } private File write(File dir, String path, String contents) throws IOException { diff --git a/langtools/test/tools/javac/processing/filer/TestInvalidRelativeNames.java b/langtools/test/tools/javac/processing/filer/TestInvalidRelativeNames.java new file mode 100644 index 00000000000..4a0efd53560 --- /dev/null +++ b/langtools/test/tools/javac/processing/filer/TestInvalidRelativeNames.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6502392 + * @summary Invalid relative names for Filer.createResource and Filer.getResource + * @library ../../lib + * @build JavacTestingAbstractProcessor + * @compile TestInvalidRelativeNames.java + * @compile/process -processor TestInvalidRelativeNames java.lang.Object + */ + +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.tools.Diagnostic; +import javax.tools.StandardLocation; + +public class TestInvalidRelativeNames extends JavacTestingAbstractProcessor { + enum Kind { CREATE_WRITER, GET_READER, CREATE_OUTPUT_STREAM, GET_INPUT_STREAM }; + + static final String[] invalidRelativeNames = { + "/boo", "goo/../hoo", "./ioo", "" + }; + + public boolean process(Set annotations, RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) { + for (String relative: invalidRelativeNames) { + for (Kind kind: Kind.values()) { + test(relative, kind); + } + } + } + return true; + } + + void test(String relative, Kind kind) { + System.out.println("test relative path: " + relative + ", kind: " + kind); + try { + switch (kind) { + case CREATE_WRITER: + Writer writer = filer.createResource( + StandardLocation.SOURCE_OUTPUT, "", relative).openWriter(); + writer.close(); + break; + + case GET_READER: + Reader reader = filer.getResource( + StandardLocation.SOURCE_OUTPUT, "", relative).openReader(true); + reader.close(); + break; + + case CREATE_OUTPUT_STREAM: + OutputStream out = filer.createResource( + StandardLocation.SOURCE_OUTPUT, "", relative).openOutputStream(); + out.close(); + break; + + case GET_INPUT_STREAM: + InputStream in = filer.createResource( + StandardLocation.SOURCE_OUTPUT, "", relative).openInputStream(); + in.close(); + break; + } + } catch (IllegalArgumentException expected) { + System.out.println("expected exception thrown: " + expected); + return; + } catch (Exception e) { + messager.printMessage(Diagnostic.Kind.ERROR, + "relative path: " + relative + ", kind: " + kind + ", unexpected exception: " + e); + return; + } + messager.printMessage(Diagnostic.Kind.ERROR, + "relative path: " + relative + ", kind: " + kind + ", no exception thrown"); + } +} + diff --git a/langtools/test/tools/javac/processing/filer/TestLastRound.java b/langtools/test/tools/javac/processing/filer/TestLastRound.java index efef9e15ec0..57c76af78e7 100644 --- a/langtools/test/tools/javac/processing/filer/TestLastRound.java +++ b/langtools/test/tools/javac/processing/filer/TestLastRound.java @@ -24,6 +24,8 @@ /* * @test 6966604 * @summary JavacFiler not correctly notified of lastRound + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestLastRound.java * @compile/fail/ref=TestLastRound.out -XDrawDiagnostics -Werror -proc:only -processor TestLastRound TestLastRound.java */ @@ -35,12 +37,10 @@ import javax.lang.model.*; import javax.lang.model.element.*; import javax.tools.*; -@SupportedAnnotationTypes("*") -public class TestLastRound extends AbstractProcessor { +public class TestLastRound extends JavacTestingAbstractProcessor { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { - Filer filer = processingEnv.getFiler(); if (roundEnv.processingOver()) { try { JavaFileObject fo = filer.createSourceFile("LastRound.java"); @@ -52,9 +52,4 @@ public class TestLastRound extends AbstractProcessor { } return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/filer/TestPackageInfo.java b/langtools/test/tools/javac/processing/filer/TestPackageInfo.java index 2e7ae10521c..7a905467370 100644 --- a/langtools/test/tools/javac/processing/filer/TestPackageInfo.java +++ b/langtools/test/tools/javac/processing/filer/TestPackageInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,8 @@ * @bug 6380018 6392177 * @summary Test the ability to create and process package-info.java files * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestPackageInfo.java * @compile -processor TestPackageInfo -proc:only foo/bar/package-info.java TestPackageInfo.java */ @@ -49,13 +51,7 @@ import java.io.*; * 1) Visibility of package-info files from the command line * 2) Visibility of generated package-info.java source files */ -@SupportedAnnotationTypes("*") -public class TestPackageInfo extends AbstractProcessor { - private Elements eltUtils; - private Messager messager; - private Filer filer; - private Map options; - +public class TestPackageInfo extends JavacTestingAbstractProcessor { private int round = 0; public boolean process(Set annotations, @@ -64,11 +60,7 @@ public class TestPackageInfo extends AbstractProcessor { // Verify annotations are as expected Set expectedAnnotations = new HashSet(); - if (round == 1) - expectedAnnotations.add(eltUtils. - getTypeElement("javax.annotation.processing.SupportedAnnotationTypes")); - expectedAnnotations.add(eltUtils. - getTypeElement("java.lang.SuppressWarnings")); + expectedAnnotations.add(eltUtils.getTypeElement("java.lang.SuppressWarnings")); if (!roundEnv.processingOver()) { System.out.println("\nRound " + round); @@ -127,16 +119,4 @@ public class TestPackageInfo extends AbstractProcessor { } return false; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - eltUtils = processingEnv.getElementUtils(); - messager = processingEnv.getMessager(); - filer = processingEnv.getFiler(); - options = processingEnv.getOptions(); - } } diff --git a/langtools/test/tools/javac/processing/messager/6362067/T6362067.java b/langtools/test/tools/javac/processing/messager/6362067/T6362067.java index ce5bd8d0bed..ef2cec88d28 100644 --- a/langtools/test/tools/javac/processing/messager/6362067/T6362067.java +++ b/langtools/test/tools/javac/processing/messager/6362067/T6362067.java @@ -2,39 +2,34 @@ * @test /nodynamiccopyright/ * @bug 6362067 * @summary Messager methods do not print out source position information - * @build T6362067 + * @library ../../../lib + * @build JavacTestingAbstractProcessor T6362067 * @compile -processor T6362067 -proc:only T6362067.java * @compile/ref=T6362067.out -XDrawDiagnostics -processor T6362067 -proc:only T6362067.java */ - import java.util.Set; import javax.annotation.processing.*; import javax.lang.model.element.*; import static javax.tools.Diagnostic.Kind.*; -@Deprecated // convenient test annotation -@SupportedAnnotationTypes("*") -public class T6362067 extends AbstractProcessor { +@Deprecated // convenient test annotations +@SuppressWarnings({""}) +public class T6362067 extends JavacTestingAbstractProcessor { public boolean process(Set annos, RoundEnvironment roundEnv) { - Messager msgr = processingEnv.getMessager(); - for (Element e: roundEnv.getRootElements()) { - msgr.printMessage(NOTE, "note:elem", e); - for (AnnotationMirror a: e.getAnnotationMirrors()) { - msgr.printMessage(NOTE, "note:anno", e, a); - for (AnnotationValue v: a.getElementValues().values()) { - msgr.printMessage(NOTE, "note:value", e, a, v); - } + for (Element e: roundEnv.getRootElements()) { + messager.printMessage(NOTE, "note:elem", e); + for (AnnotationMirror a: e.getAnnotationMirrors()) { + messager.printMessage(NOTE, "note:anno", e, a); + for (AnnotationValue v: a.getElementValues().values()) { + messager.printMessage(NOTE, "note:value", e, a, v); + } } } + if (roundEnv.processingOver()) - msgr.printMessage(NOTE, "note:nopos"); + messager.printMessage(NOTE, "note:nopos"); return true; } - - @Override - public javax.lang.model.SourceVersion getSupportedSourceVersion() { - return javax.lang.model.SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/messager/MessagerBasics.java b/langtools/test/tools/javac/processing/messager/MessagerBasics.java index cbcbf094a42..f7980c70109 100644 --- a/langtools/test/tools/javac/processing/messager/MessagerBasics.java +++ b/langtools/test/tools/javac/processing/messager/MessagerBasics.java @@ -1,5 +1,5 @@ /* - * 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. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6341173 6341072 * @summary Test presence of Messager methods * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile MessagerBasics.java * @compile -processor MessagerBasics -proc:only MessagerBasics.java * @compile/fail -processor MessagerBasics -proc:only -AfinalError MessagerBasics.java @@ -39,18 +41,16 @@ import javax.lang.model.element.*; import javax.lang.model.util.*; import static javax.tools.Diagnostic.Kind.*; -@SupportedAnnotationTypes("*") @SupportedOptions("finalError") -public class MessagerBasics extends AbstractProcessor { +public class MessagerBasics extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { - Messager m = processingEnv.getMessager(); if (roundEnv.processingOver()) { if (processingEnv.getOptions().containsKey("finalError")) - m.printMessage(ERROR, "Does not compute"); + messager.printMessage(ERROR, "Does not compute"); else { - m.printMessage(NOTE, "Post no bills"); - m.printMessage(WARNING, "Beware the ides of March!"); + messager.printMessage(NOTE, "Post no bills"); + messager.printMessage(WARNING, "Beware the ides of March!"); } } return true; diff --git a/langtools/test/tools/javac/processing/model/6194785/T6194785.java b/langtools/test/tools/javac/processing/model/6194785/T6194785.java index 8b18b48f712..11abd61a1d6 100644 --- a/langtools/test/tools/javac/processing/model/6194785/T6194785.java +++ b/langtools/test/tools/javac/processing/model/6194785/T6194785.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,8 @@ * @bug 6194785 * @summary ParameterDeclaration.getSimpleName does not return actual name from class files * @author Peter von der Ah\u00e9 + * @library ../../../lib + * @build JavacTestingAbstractProcessor * @compile -g T6194785.java T6194785a.java * @compile -processor T6194785 foo.T6194785a T6194785.java */ @@ -36,13 +38,10 @@ import javax.lang.model.element.*; import javax.lang.model.util.*; import static javax.tools.Diagnostic.Kind.*; -@SupportedAnnotationTypes("*") -public class T6194785 extends AbstractProcessor { +public class T6194785 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { - final Messager log = processingEnv.getMessager(); - final Elements elements = processingEnv.getElementUtils(); class Scan extends ElementScanner7 { @Override public Void visitExecutable(ExecutableElement e, Void ignored) { diff --git a/langtools/test/tools/javac/processing/model/6341534/T6341534.java b/langtools/test/tools/javac/processing/model/6341534/T6341534.java index b374d65eb05..2950909590e 100644 --- a/langtools/test/tools/javac/processing/model/6341534/T6341534.java +++ b/langtools/test/tools/javac/processing/model/6341534/T6341534.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -27,6 +27,8 @@ * @summary PackageElement.getEnclosedElements results in NullPointerException from parse(JavaCompiler.java:429) * @author Steve Sides * @author Peter von der Ahe + * @library ../../../lib + * @build JavacTestingAbstractProcessor * @compile T6341534.java * @compile -proc:only -processor T6341534 dir/package-info.java * @compile -processor T6341534 dir/package-info.java @@ -40,20 +42,11 @@ import java.util.*; import java.util.Set; import static javax.tools.Diagnostic.Kind.*; -@SupportedAnnotationTypes("*") -public class T6341534 extends AbstractProcessor { - Elements elements; - Messager messager; - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - messager = processingEnv.getMessager(); - } - +public class T6341534 extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment renv) { messager.printMessage(NOTE, - String.valueOf(elements.getPackageElement("no.such.package"))); - PackageElement dir = elements.getPackageElement("dir"); + String.valueOf(eltUtils.getPackageElement("no.such.package"))); + PackageElement dir = eltUtils.getPackageElement("dir"); messager.printMessage(NOTE, dir.getQualifiedName().toString()); for (Element e : dir.getEnclosedElements()) messager.printMessage(NOTE, e.toString()); diff --git a/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java b/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java index 62c7964416f..f5bddff0a45 100644 --- a/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java +++ b/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java @@ -26,7 +26,8 @@ * @bug 6449781 * @summary Test that reported names of anonymous classes are non-null. * @author Joseph D. Darcy - * @build TestAnonSourceNames + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestAnonSourceNames * @compile -processor TestAnonSourceNames TestAnonClassNames.java * @run main TestAnonClassNames */ @@ -141,8 +142,7 @@ public class TestAnonClassNames { /** * Probe at the various kinds of names of a type element. */ -@SupportedAnnotationTypes("*") -class ClassNameProber extends AbstractProcessor { +class ClassNameProber extends JavacTestingAbstractProcessor { public ClassNameProber(){super();} private boolean classesFound=false; @@ -174,8 +174,4 @@ class ClassNameProber extends AbstractProcessor { } return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/model/element/TestAnonSourceNames.java b/langtools/test/tools/javac/processing/model/element/TestAnonSourceNames.java index ff16b5df389..84184b30407 100644 --- a/langtools/test/tools/javac/processing/model/element/TestAnonSourceNames.java +++ b/langtools/test/tools/javac/processing/model/element/TestAnonSourceNames.java @@ -36,8 +36,7 @@ import static javax.tools.Diagnostic.Kind.*; * Using the tree API, retrieve element representations of anonymous * classes and verify their names are as specified. */ -@SupportedAnnotationTypes("*") -public class TestAnonSourceNames extends AbstractProcessor { +public class TestAnonSourceNames extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { @@ -84,9 +83,4 @@ public class TestAnonSourceNames extends AbstractProcessor { return super.visitClass(node, cu); } } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/model/element/TestElement.java b/langtools/test/tools/javac/processing/model/element/TestElement.java index 8e38da4879e..004a5058aa2 100644 --- a/langtools/test/tools/javac/processing/model/element/TestElement.java +++ b/langtools/test/tools/javac/processing/model/element/TestElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,7 +26,8 @@ * @bug 6453386 * @summary Test basic properties of javax.lang.element.Element * @author Joseph D. Darcy - * @build TestElement + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestElement * @compile -processor TestElement -proc:only TestElement.java */ @@ -43,8 +44,7 @@ import static javax.tools.StandardLocation.*; /** * Test basic workings of javax.lang.element.Element */ -@SupportedAnnotationTypes("*") -public class TestElement extends AbstractProcessor { +public class TestElement extends JavacTestingAbstractProcessor { /** * For now, just check that constructors have a simple name of * "". @@ -66,9 +66,4 @@ public class TestElement extends AbstractProcessor { } return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - } diff --git a/langtools/test/tools/javac/processing/model/element/TestNames.java b/langtools/test/tools/javac/processing/model/element/TestNames.java index fe1683115a7..1aec65ec4bf 100644 --- a/langtools/test/tools/javac/processing/model/element/TestNames.java +++ b/langtools/test/tools/javac/processing/model/element/TestNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,7 +26,8 @@ * @bug 6380016 * @summary Test that the constraints guaranteed by the Filer and maintained * @author Joseph D. Darcy - * @build TestNames + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestNames * @compile -processor TestNames -proc:only TestNames.java */ @@ -45,11 +46,8 @@ import java.io.*; /** * Basic tests of semantics of javax.lang.model.element.Name */ -@SupportedAnnotationTypes("*") -public class TestNames extends AbstractProcessor { +public class TestNames extends JavacTestingAbstractProcessor { private int round = 0; - private Filer filer; - private Elements eltUtils; String stringStringName = "java.lang.String"; Name stringName = null; @@ -106,16 +104,6 @@ public class TestNames extends AbstractProcessor { return true; } - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - filer = processingEnv.getFiler(); - eltUtils = processingEnv.getElementUtils(); - } - private static class Pseudonym implements Name { private String name; diff --git a/langtools/test/tools/javac/processing/model/element/TestPackageElement.java b/langtools/test/tools/javac/processing/model/element/TestPackageElement.java index 5b44c5ade98..4e0575be93b 100644 --- a/langtools/test/tools/javac/processing/model/element/TestPackageElement.java +++ b/langtools/test/tools/javac/processing/model/element/TestPackageElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,7 +26,8 @@ * @bug 6449798 6399404 * @summary Test basic workings of PackageElement * @author Joseph D. Darcy - * @build TestPackageElement + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestPackageElement * @compile -processor TestPackageElement -proc:only TestPackageElement.java */ @@ -43,11 +44,7 @@ import static javax.tools.StandardLocation.*; /** * Test basic workings of PackageElement. */ -@SupportedAnnotationTypes("*") -public class TestPackageElement extends AbstractProcessor { - private Filer filer; - private Elements eltUtils; - +public class TestPackageElement extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { @@ -71,15 +68,4 @@ public class TestPackageElement extends AbstractProcessor { } return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - filer = processingEnv.getFiler(); - eltUtils = processingEnv.getElementUtils(); - } - } diff --git a/langtools/test/tools/javac/processing/model/element/TestResourceElement.java b/langtools/test/tools/javac/processing/model/element/TestResourceElement.java new file mode 100644 index 00000000000..a6e6de829d5 --- /dev/null +++ b/langtools/test/tools/javac/processing/model/element/TestResourceElement.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6967842 + * @summary Element not returned from tree API for ARM resource variables. + * @author A. Sundararajan + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestResourceElement + * @compile -processor TestResourceElement -proc:only TestResourceElement.java + */ + +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import java.util.*; +import com.sun.source.tree.*; +import com.sun.source.util.*; + +public class TestResourceElement extends JavacTestingAbstractProcessor implements AutoCloseable { + public boolean process(Set annotations, + RoundEnvironment roundEnv) { + if (!roundEnv.processingOver()) { + Trees trees = Trees.instance(processingEnv); + + for(Element rootElement : roundEnv.getRootElements()) { + TreePath treePath = trees.getPath(rootElement); + + VariableScanner varScanner = new VariableScanner(trees); + varScanner.scan(trees.getTree(rootElement), + treePath.getCompilationUnit()); + if (varScanner.getTrvElement() == null) { + throw new AssertionError("Element is null for 'trv'"); + } + } + } + return true; + } + + @Override + public void close() {} + + private void test1() { + // The resource variable "trv"'s Element is checked. + // Do not change the name of the variable. + try(TestResourceElement trv = this) {} + } + + class VariableScanner extends TreeScanner { + private Trees trees; + private Element trvElement; + + public VariableScanner(Trees trees) { + super(); + this.trees = trees; + } + @Override + public Void visitVariable(VariableTree node, CompilationUnitTree cu) { + // if this is "trv", get it's element. + if (node.getName().contentEquals("trv")) { + trvElement = trees.getElement(trees.getPath(cu, node)); + } + return super.visitVariable(node, cu); + } + + Element getTrvElement() { + return trvElement; + } + } +} diff --git a/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java b/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java index 45829b46e33..4b5fcd26b0e 100644 --- a/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java +++ b/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java @@ -23,11 +23,12 @@ /* * @test - * @bug 6911256 6964740 + * @bug 6911256 6964740 6967842 * @summary Test that the resource variable kind is appropriately set * @author Joseph D. Darcy - * @build TestResourceVariable - * @compile/fail -processor TestResourceVariable -proc:only TestResourceVariable.java + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestResourceVariable + * @compile -processor TestResourceVariable -proc:only TestResourceVariable.java */ // Bug should be filed for this misbehavior @@ -48,8 +49,7 @@ import static javax.tools.Diagnostic.Kind.*; * resource of an ARM block and verify their kind tags are set * appropriately. */ -@SupportedAnnotationTypes("*") -public class TestResourceVariable extends AbstractProcessor implements AutoCloseable { +public class TestResourceVariable extends JavacTestingAbstractProcessor implements AutoCloseable { int resourceVariableCount = 0; public boolean process(Set annotations, @@ -105,9 +105,4 @@ public class TestResourceVariable extends AbstractProcessor implements AutoClose return super.visitVariable(node, cu); } } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/model/element/TypeParamBounds.java b/langtools/test/tools/javac/processing/model/element/TypeParamBounds.java index 0442c96a893..c09e12bd49b 100644 --- a/langtools/test/tools/javac/processing/model/element/TypeParamBounds.java +++ b/langtools/test/tools/javac/processing/model/element/TypeParamBounds.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,7 +26,8 @@ * @bug 6423972 * @summary Tests TypeParameter.getBounds. * @author Scott Seligman - * @build TypeParamBounds + * @library ../../../lib + * @build JavacTestingAbstractProcessor TypeParamBounds * @compile -processor TypeParamBounds -proc:only TypeParamBounds.java */ @@ -40,18 +41,7 @@ import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") -public class TypeParamBounds extends AbstractProcessor { - - Elements elements; - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - types = penv.getTypeUtils(); - } - +public class TypeParamBounds extends JavacTestingAbstractProcessor { public boolean process(Set annoTypes, RoundEnvironment round) { if (!round.processingOver()) @@ -59,11 +49,6 @@ public class TypeParamBounds extends AbstractProcessor { return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - private void doit(Set annoTypes, RoundEnvironment round) { TypeElement gen = elements.getTypeElement("TypeParamBounds.Gen"); @@ -91,7 +76,6 @@ public class TypeParamBounds extends AbstractProcessor { // Fodder for the processor - static class Gen { diff --git a/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/OverEager.java b/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/OverEager.java index 30ab564a71b..861014f4cce 100644 --- a/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/OverEager.java +++ b/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/OverEager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,8 @@ * @bug 6362178 * @summary MirroredType[s]Exception shouldn't be created too eagerly * @author Scott Seligman + * @library ../../../../lib + * @build JavacTestingAbstractProcessor * @compile -g OverEager.java * @compile -processor OverEager -proc:only OverEager.java */ @@ -40,17 +42,7 @@ import static javax.lang.model.util.ElementFilter.*; @SupportedAnnotationTypes("IAm") @IAm(OverEager.class) -public class OverEager extends AbstractProcessor { - - Elements elements; - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - types = penv.getTypeUtils(); - } - +public class OverEager extends JavacTestingAbstractProcessor { public boolean process(Set annoTypes, RoundEnvironment round) { if (!round.processingOver()) @@ -58,11 +50,6 @@ public class OverEager extends AbstractProcessor { return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - private void doit(Set annoTypes, RoundEnvironment round) { for (TypeElement t : typesIn(round.getRootElements())) { diff --git a/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/Plurality.java b/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/Plurality.java index f7b6ca6694f..e01ba019c7f 100644 --- a/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/Plurality.java +++ b/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/Plurality.java @@ -25,6 +25,8 @@ * @test * @bug 6519115 * @summary Verify MirroredTypeException vs MirroredTypesException is thrown + * @library ../../../../lib + * @build JavacTestingAbstractProcessor * @compile Plurality.java * @compile -processor Plurality -proc:only Plurality.java * @author Joseph D. Darcy @@ -38,25 +40,13 @@ import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") @P0 @P1 @P2 @S1 -public class Plurality extends AbstractProcessor { +public class Plurality extends JavacTestingAbstractProcessor { private boolean executed = false; - Elements elements; - Types types; - - @Override - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - types = penv.getTypeUtils(); - } - - public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { @@ -164,11 +154,6 @@ public class Plurality extends AbstractProcessor { toStringName); } } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } @Retention(RetentionPolicy.RUNTIME) diff --git a/langtools/test/tools/javac/processing/model/type/NoTypes.java b/langtools/test/tools/javac/processing/model/type/NoTypes.java index 3e26d6fd01d..d67dae187c4 100644 --- a/langtools/test/tools/javac/processing/model/type/NoTypes.java +++ b/langtools/test/tools/javac/processing/model/type/NoTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,8 @@ * @bug 6418666 6423973 6453386 * @summary Test the NoTypes: VOID, PACKAGE, NONE * @author Scott Seligman + * @library ../../../lib + * @build JavacTestingAbstractProcessor * @compile -g NoTypes.java * @compile -processor NoTypes -proc:only NoTypes.java */ @@ -39,18 +41,7 @@ import javax.lang.model.util.*; import static javax.lang.model.type.TypeKind.*; -@SupportedAnnotationTypes("*") -public class NoTypes extends AbstractProcessor { - - Elements elements; - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - types = penv.getTypeUtils(); - } - +public class NoTypes extends JavacTestingAbstractProcessor { public boolean process(Set annoTypes, RoundEnvironment round) { if (!round.processingOver()) @@ -58,11 +49,6 @@ public class NoTypes extends AbstractProcessor { return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - private void doit(Set annoTypes, RoundEnvironment round) { diff --git a/langtools/test/tools/javac/processing/model/util/BinaryName.java b/langtools/test/tools/javac/processing/model/util/BinaryName.java index ebf5612b1eb..02445ff2bd8 100644 --- a/langtools/test/tools/javac/processing/model/util/BinaryName.java +++ b/langtools/test/tools/javac/processing/model/util/BinaryName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,7 +26,8 @@ * @bug 6346251 * @summary Test Elements.getBinaryName * @author Scott Seligman - * @build BinaryName + * @library ../../../lib + * @build JavacTestingAbstractProcessor BinaryName * @compile -processor BinaryName -proc:only BinaryName.java */ @@ -38,17 +39,8 @@ import javax.lang.model.util.*; import static javax.lang.model.util.ElementFilter.typesIn; -@SupportedAnnotationTypes("*") @HelloIm("BinaryName") -public class BinaryName extends AbstractProcessor { - - Elements elements; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - } - +public class BinaryName extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment round) { if (round.processingOver()) return true; diff --git a/langtools/test/tools/javac/processing/model/util/GetTypeElemBadArg.java b/langtools/test/tools/javac/processing/model/util/GetTypeElemBadArg.java index 92b5c088f6d..01782f327a5 100644 --- a/langtools/test/tools/javac/processing/model/util/GetTypeElemBadArg.java +++ b/langtools/test/tools/javac/processing/model/util/GetTypeElemBadArg.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,7 +26,8 @@ * @bug 6346506 6408241 * @summary getTypeElement should tolerate a type that can't be found * @author Scott Seligman - * @build GetTypeElemBadArg + * @library ../../../lib + * @build JavacTestingAbstractProcessor GetTypeElemBadArg * @compile -processor GetTypeElemBadArg -proc:only GetTypeElemBadArg.java */ @@ -37,16 +38,7 @@ import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") -public class GetTypeElemBadArg extends AbstractProcessor { - - Elements elements; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - } - +public class GetTypeElemBadArg extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment round) { if (round.processingOver()) return true; @@ -63,12 +55,6 @@ public class GetTypeElemBadArg extends AbstractProcessor { return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - private static void tellAbout(TypeElement t) { System.out.println(t); System.out.println(t.getClass()); diff --git a/langtools/test/tools/javac/processing/model/util/NoSupers.java b/langtools/test/tools/javac/processing/model/util/NoSupers.java index 64671cc5fae..9967b405580 100644 --- a/langtools/test/tools/javac/processing/model/util/NoSupers.java +++ b/langtools/test/tools/javac/processing/model/util/NoSupers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,7 +26,8 @@ * @bug 6346453 * @summary directSupertypes should return empty list if arg has no supertypes * @author Scott Seligman - * @build NoSupers + * @library ../../../lib + * @build JavacTestingAbstractProcessor NoSupers * @compile -processor NoSupers -proc:only NoSupers.java */ @@ -36,16 +37,7 @@ import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") -public class NoSupers extends AbstractProcessor { - - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - types = penv.getTypeUtils(); - } - +public class NoSupers extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment round) { if (round.processingOver()) return true; diff --git a/langtools/test/tools/javac/processing/model/util/OverridesSpecEx.java b/langtools/test/tools/javac/processing/model/util/OverridesSpecEx.java index e6c7916dbeb..887c6776fb7 100644 --- a/langtools/test/tools/javac/processing/model/util/OverridesSpecEx.java +++ b/langtools/test/tools/javac/processing/model/util/OverridesSpecEx.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,8 @@ * @bug 6453386 * @summary Verify that example code in Elements.overrides works as spec'ed. * @author Scott Seligman + * @library ../../../lib + * @build JavacTestingAbstractProcessor * @compile -g OverridesSpecEx.java * @compile -processor OverridesSpecEx -proc:only OverridesSpecEx.java */ @@ -39,19 +41,7 @@ import javax.lang.model.util.*; import static javax.lang.model.util.ElementFilter.*; - -@SupportedAnnotationTypes("*") -public class OverridesSpecEx extends AbstractProcessor { - - Elements elements; - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - types = penv.getTypeUtils(); - } - +public class OverridesSpecEx extends JavacTestingAbstractProcessor { public boolean process(Set annoTypes, RoundEnvironment round) { if (!round.processingOver()) @@ -59,11 +49,6 @@ public class OverridesSpecEx extends AbstractProcessor { return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - private void doit(Set annoTypes, RoundEnvironment round) { TypeElement string = elements.getTypeElement("java.lang.String"); @@ -113,9 +98,7 @@ public class OverridesSpecEx extends AbstractProcessor { throw new AssertionError("Bogus result"); } - // Fodder for the processor - class A { public void m() {} } diff --git a/langtools/test/tools/javac/processing/model/util/TypesBadArg.java b/langtools/test/tools/javac/processing/model/util/TypesBadArg.java index 8f13c8f7d68..6eadb5759a7 100644 --- a/langtools/test/tools/javac/processing/model/util/TypesBadArg.java +++ b/langtools/test/tools/javac/processing/model/util/TypesBadArg.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,7 +26,8 @@ * @bug 6345812 * @summary Validate argument kinds in Types utilities * @author Scott Seligman - * @build TypesBadArg + * @library ../../../lib + * @build JavacTestingAbstractProcessor TypesBadArg * @compile -processor TypesBadArg -proc:only TypesBadArg.java */ @@ -36,15 +37,9 @@ import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") -public class TypesBadArg extends AbstractProcessor { - +public class TypesBadArg extends JavacTestingAbstractProcessor { boolean success = true; - public void init(ProcessingEnvironment penv) { - super.init(penv); - } - public boolean process(Set tes, RoundEnvironment round) { if (round.processingOver()) return true; diff --git a/langtools/test/tools/javac/processing/model/util/deprecation/TestDeprecation.java b/langtools/test/tools/javac/processing/model/util/deprecation/TestDeprecation.java index a7ff90ba060..ce9b2cdf92c 100644 --- a/langtools/test/tools/javac/processing/model/util/deprecation/TestDeprecation.java +++ b/langtools/test/tools/javac/processing/model/util/deprecation/TestDeprecation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,8 @@ * @bug 6392818 * @summary Tests Elements.isDeprecated(Element) * @author Joseph D. Darcy + * @library ../../../../lib + * @build JavacTestingAbstractProcessor * @compile TestDeprecation.java * @compile -processor TestDeprecation -proc:only Dep1.java * @compile Dep1.java @@ -47,8 +49,7 @@ import java.io.Writer; * getElementsAnnotatedWith is consistent with the expected results * stored in an AnnotatedElementInfo annotation. */ -@SupportedAnnotationTypes("*") -public class TestDeprecation extends AbstractProcessor { +public class TestDeprecation extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { @@ -98,9 +99,4 @@ public class TestDeprecation extends AbstractProcessor { return failure; } } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java b/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java index b74a5dc0af8..db44b564747 100644 --- a/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java +++ b/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,7 +26,8 @@ * @bug 6346973 * @summary directSupertypes(t) should not return t * @author Scott Seligman - * @build DirectSupersOfErr + * @library ../../../../lib + * @build JavacTestingAbstractProcessor DirectSupersOfErr * @compile -processor DirectSupersOfErr -proc:only C1.java */ @@ -37,16 +38,7 @@ import javax.lang.model.type.*; import javax.lang.model.util.*; import static javax.lang.model.util.ElementFilter.*; -@SupportedAnnotationTypes("*") -public class DirectSupersOfErr extends AbstractProcessor { - - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - types = penv.getTypeUtils(); - } - +public class DirectSupersOfErr extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment round) { if (round.processingOver()) return true; diff --git a/langtools/test/tools/javac/processing/model/util/elements/TestGetConstantExpression.java b/langtools/test/tools/javac/processing/model/util/elements/TestGetConstantExpression.java index 17543c6ee9a..355b7d93bc8 100644 --- a/langtools/test/tools/javac/processing/model/util/elements/TestGetConstantExpression.java +++ b/langtools/test/tools/javac/processing/model/util/elements/TestGetConstantExpression.java @@ -1,5 +1,5 @@ /* - * 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. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ * @bug 6471577 6517779 * @summary Test Elements.getConstantExpression * @author Joseph D. Darcy - * @build TestGetConstantExpression + * @library ../../../../lib + * @build JavacTestingAbstractProcessor TestGetConstantExpression * @compile -processor TestGetConstantExpression Foo.java */ @@ -44,10 +45,7 @@ import java.io.*; /** * Test basic workings of Elements.getConstantExpression. */ -@SupportedAnnotationTypes("*") -public class TestGetConstantExpression extends AbstractProcessor { - private Elements eltUtils; - private Filer filer; +public class TestGetConstantExpression extends JavacTestingAbstractProcessor { private int round = 1; /** @@ -130,14 +128,4 @@ public class TestGetConstantExpression extends AbstractProcessor { return 0; } } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - eltUtils = processingEnv.getElementUtils(); - filer = processingEnv.getFiler(); - } } diff --git a/langtools/test/tools/javac/processing/model/util/elements/TestGetPackageOf.java b/langtools/test/tools/javac/processing/model/util/elements/TestGetPackageOf.java index 08e4702104d..6fbc24f0cf8 100644 --- a/langtools/test/tools/javac/processing/model/util/elements/TestGetPackageOf.java +++ b/langtools/test/tools/javac/processing/model/util/elements/TestGetPackageOf.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,7 +26,8 @@ * @bug 6453386 * @summary Test Elements.getPackageOf * @author Joseph D. Darcy - * @build TestGetPackageOf + * @library ../../../../lib + * @build JavacTestingAbstractProcessor TestGetPackageOf * @compile -processor TestGetPackageOf -proc:only TestGetPackageOf.java */ @@ -43,10 +44,7 @@ import static javax.tools.StandardLocation.*; /** * Test basic workings of Elements.getPackageOf */ -@SupportedAnnotationTypes("*") -public class TestGetPackageOf extends AbstractProcessor { - private Elements eltUtils; - +public class TestGetPackageOf extends JavacTestingAbstractProcessor { /** * Check expected behavior on classes and packages. */ @@ -69,13 +67,4 @@ public class TestGetPackageOf extends AbstractProcessor { } return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - eltUtils = processingEnv.getElementUtils(); - } } diff --git a/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java b/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java new file mode 100644 index 00000000000..57cb1c3b014 --- /dev/null +++ b/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java @@ -0,0 +1,310 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6877202 6986246 + * @summary Elements.getDocComment() is not getting JavaDocComments + */ + +import com.sun.source.tree.*; +import com.sun.source.util.*; +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.lang.model.util.*; +import javax.tools.*; + +/* + * For a mixture of pre-existing and generated source files, ensure that we can + * get the doc comments. + * The test uses both a standard ElementScanner to find all the elements being + * processed, and a TreeScanner to find all the local and anonymous inner classes + * as well. + * And, because the relevant code paths in the compiler are different for + * command line and JSR 199 invocation, the test covers both ways of invoking the + * compiler. + */ + +@SupportedOptions("scan") +@SupportedAnnotationTypes("*") +public class TestDocComments extends AbstractProcessor { + enum CompileKind { API, CMD }; + enum ScanKind { TREE, ELEMENT }; + + // ----- Main test driver: invoke compiler for the various test cases ------ + + public static void main(String... args) throws Exception { + for (CompileKind ck: CompileKind.values()) { + for (ScanKind sk: ScanKind.values()) { + try { + test(ck, sk); + } catch (IOException e) { + error(e.toString()); + } + } + } + + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } + + static void test(CompileKind ck, ScanKind sk) throws IOException { + String testClasses = System.getProperty("test.classes"); + String testSrc = System.getProperty("test.src"); + File testDir = new File("test." + ck + "." + sk); + testDir.mkdirs(); + String[] opts = { + "-d", testDir.getPath(), + "-implicit:none", + "-processor", TestDocComments.class.getName(), + "-processorpath", testClasses, + //"-XprintRounds", + "-Ascan=" + sk + }; + File[] files = { + new File(testSrc, "a/First.java") + }; + + if (ck == CompileKind.API) + test_javac_api(opts, files); + else + test_javac_cmd(opts, files); + } + + static void test_javac_api(String[] opts, File[] files) throws IOException { + System.err.println("test javac api: " + Arrays.asList(opts) + " " + Arrays.asList(files)); + DiagnosticListener dl = new DiagnosticListener() { + public void report(Diagnostic diagnostic) { + error(diagnostic.toString()); + } + }; + JavaCompiler c = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); + Iterable units = fm.getJavaFileObjects(files); + JavacTask t = (JavacTask) c.getTask(null, fm, dl, Arrays.asList(opts), null, units); + t.parse(); + t.analyze(); + } + + static void test_javac_cmd(String[] opts, File[] files) { + System.err.println("test javac cmd: " + Arrays.asList(opts) + " " + Arrays.asList(files)); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + List args = new ArrayList(Arrays.asList(opts)); + for (File f: files) + args.add(f.getPath()); + int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw); + pw.close(); + String out = sw.toString(); + if (out.length() > 0) + System.err.println(out); + if (rc > 0) + error("Compilation failed: rc=" + rc); + } + + static void error(String msg) { + System.err.println(msg); + errors++; + //throw new Error(msg); + } + + static int errors; + + // ----- Annotation processor: scan for elements and check doc comments ---- + + Map options; + Filer filer; + Messager messager; + Elements elements; + Trees trees; + ScanKind skind; + + int round = 0; + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + @Override + public void init(ProcessingEnvironment pEnv) { + super.init(pEnv); + options = pEnv.getOptions(); + filer = pEnv.getFiler(); + messager = pEnv.getMessager(); + elements = pEnv.getElementUtils(); + trees = Trees.instance(processingEnv); + skind = ScanKind.valueOf(options.get("scan")); + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + round++; + + // Scan elements using an appropriate scanner, and for each element found, + // call check(Element e) to verify the doc comment on that element + for (Element e: roundEnv.getRootElements()) { + System.err.println("scan " + skind + " " + e.getKind() + " " + e.getSimpleName()); + if (skind == ScanKind.TREE) { + new TestTreeScanner().scan(trees.getPath(e), trees); + } else + new TestElementScanner().scan(e); + } + + // For a few rounds, generate new source files, so that we can check whether + // doc comments are correctly handled in subsequent processing rounds + final int MAX_ROUNDS = 3; + if (round <= MAX_ROUNDS) { + String pkg = "p"; + String currClass = "Gen" + round; + String curr = pkg + "." + currClass; + String next = (round < MAX_ROUNDS) ? (pkg + ".Gen" + (round + 1)) : "z.Last"; + StringBuilder text = new StringBuilder(); + text.append("package ").append(pkg).append(";\n"); + text.append("/** CLASS ").append(currClass).append(" */\n"); + text.append("public class ").append(currClass).append(" {\n"); + text.append(" /** CONSTRUCTOR **/\n"); + text.append(" ").append(currClass).append("() { }\n"); + text.append(" /** FIELD x */\n"); + text.append(" ").append(next).append(" x;\n"); + text.append(" /** METHOD m */\n"); + text.append(" void m() { }\n"); + text.append("}\n"); + + try { + JavaFileObject fo = filer.createSourceFile(curr); + Writer out = fo.openWriter(); + try { + out.write(text.toString()); + } finally { + out.close(); + } + } catch (IOException e) { + throw new Error(e); + } + } + + return true; + } + + /* + * Check that the doc comment on an element is as expected. + * This method is invoked for each element found by the scanners run by process. + */ + void check(Element e) { + System.err.println("Checking " + e); + + String dc = elements.getDocComment(e); + System.err.println(" found " + dc); + + String expect = (e.getKind() + " " + e.getSimpleName()); // default + + Name name = e.getSimpleName(); + Element encl = e.getEnclosingElement(); + Name enclName = encl.getSimpleName(); + ElementKind enclKind = encl.getKind(); + switch (e.getKind()) { + case PARAMETER: + case LOCAL_VARIABLE: + // doc comments not retained for these elements + expect = null; + break; + + case CONSTRUCTOR: + if (enclName.length() == 0 || enclKind == ElementKind.ENUM) { + // Enum constructor is synthetic + expect = null; + } + break; + + case METHOD: + if (enclKind == ElementKind.ENUM + && (name.contentEquals("values") || name.contentEquals("valueOf"))) { + // synthetic enum methods + expect = null; + } + break; + + case CLASS: + if (e.getSimpleName().length() == 0) { + // anon inner class + expect = null; + } + break; + } + + System.err.println(" expect " + expect); + + if (dc == null ? expect == null : dc.trim().equals(expect)) + return; + + if (dc == null) + messager.printMessage(Diagnostic.Kind.ERROR, "doc comment is null", e); + else { + messager.printMessage(Diagnostic.Kind.ERROR, + "unexpected comment: \"" + dc + "\", expected \"" + expect + "\"", e); + } + } + + // ----- Scanners to find elements ----------------------------------------- + + class TestElementScanner extends ElementScanner7 { + @Override + public Void visitExecutable(ExecutableElement e, Void _) { + check(e); + return super.visitExecutable(e, _); + } + @Override + public Void visitType(TypeElement e, Void _) { + check(e); + return super.visitType(e, _); + } + @Override + public Void visitVariable(VariableElement e, Void _) { + check(e); + return super.visitVariable(e, _); + } + } + + class TestTreeScanner extends TreePathScanner { + @Override + public Void visitClass(ClassTree tree, Trees trees) { + check(trees.getElement(getCurrentPath())); + return super.visitClass(tree, trees); + } + @Override + public Void visitMethod(MethodTree tree, Trees trees) { + check(trees.getElement(getCurrentPath())); + return super.visitMethod(tree, trees); + } + @Override + public Void visitVariable(VariableTree tree, Trees trees) { + check(trees.getElement(getCurrentPath())); + return super.visitVariable(tree, trees); + } + } + +} diff --git a/langtools/test/tools/javac/processing/model/util/elements/doccomments/a/First.java b/langtools/test/tools/javac/processing/model/util/elements/doccomments/a/First.java new file mode 100644 index 00000000000..1762abdb3db --- /dev/null +++ b/langtools/test/tools/javac/processing/model/util/elements/doccomments/a/First.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 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. + * + * 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 a; + +/** CLASS First */ +public class First { + /** CONSTRUCTOR */ + First() { } + + /** FIELD x */ + p.Gen1 x; + + /** METHOD m **/ + void m(int i) { + /** CLASS Local */ + class Local { + /** CONSTRUCTOR */ + Local() { } + } + + Runnable r = new Runnable() { + /** METHOD run **/ + public void run() { } + }; + + } + + /** ENUM E */ + enum E { + /** ENUM_CONSTANT e1 */ + e1 + } +} diff --git a/langtools/test/tools/javac/processing/model/util/elements/doccomments/z/Last.java b/langtools/test/tools/javac/processing/model/util/elements/doccomments/z/Last.java new file mode 100644 index 00000000000..eb017607a99 --- /dev/null +++ b/langtools/test/tools/javac/processing/model/util/elements/doccomments/z/Last.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 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. + * + * 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 z; + +// This class should be read last, implicitly. Therefore it should not +// be subject to anno processing. If it is, the lack of doc comments should +// be detected and will flag an error. +public class Last { +} diff --git a/langtools/test/tools/javac/processing/model/util/filter/TestIterables.java b/langtools/test/tools/javac/processing/model/util/filter/TestIterables.java index 2b906b32e75..cbffcda752d 100644 --- a/langtools/test/tools/javac/processing/model/util/filter/TestIterables.java +++ b/langtools/test/tools/javac/processing/model/util/filter/TestIterables.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,8 @@ * @bug 6406164 * @summary Test that ElementFilter iterable methods behave properly. * @author Joseph D. Darcy + * @library ../../../../lib + * @build JavacTestingAbstractProcessor * @compile TestIterables.java * @compile -processor TestIterables -proc:only Foo1.java * @compile Foo1.java @@ -51,9 +53,8 @@ import static javax.lang.model.util.ElementFilter.*; * results. */ @SupportedAnnotationTypes("ExpectedElementCounts") -@ExpectedElementCounts(methods=3) -public class TestIterables extends AbstractProcessor { - +@ExpectedElementCounts(methods=2) +public class TestIterables extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { @@ -118,10 +119,4 @@ public class TestIterables extends AbstractProcessor { return count1; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - } diff --git a/langtools/test/tools/javac/processing/Xprint.java b/langtools/test/tools/javac/processing/options/Xprint.java similarity index 96% rename from langtools/test/tools/javac/processing/Xprint.java rename to langtools/test/tools/javac/processing/options/Xprint.java index 6aae8795290..5417c89e82e 100644 --- a/langtools/test/tools/javac/processing/Xprint.java +++ b/langtools/test/tools/javac/processing/options/Xprint.java @@ -1,5 +1,5 @@ /* - * 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. * * This code is free software; you can redistribute it and/or modify it diff --git a/langtools/test/tools/javac/processing/options/XprintDocComments.java b/langtools/test/tools/javac/processing/options/XprintDocComments.java new file mode 100644 index 00000000000..cf61eb9c8f0 --- /dev/null +++ b/langtools/test/tools/javac/processing/options/XprintDocComments.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6861094 + * @summary javac -Xprint does not print comments + * @compile/ref=XprintDocComments.out -Xprint XprintDocComments.java + */ + +/** + * CLASS XprintDocComments + */ +class XPrintDocComments { + /** + * FIELD i; + */ + int i; +} diff --git a/langtools/test/tools/javac/processing/options/XprintDocComments.out b/langtools/test/tools/javac/processing/options/XprintDocComments.out new file mode 100644 index 00000000000..03b42b220d5 --- /dev/null +++ b/langtools/test/tools/javac/processing/options/XprintDocComments.out @@ -0,0 +1,12 @@ + +/** + * CLASS XprintDocComments + */ +class XPrintDocComments { + + XPrintDocComments(); + /** + * FIELD i; + */ + int i; +} diff --git a/langtools/test/tools/javac/processing/warnings/TestSourceVersionWarnings.java b/langtools/test/tools/javac/processing/warnings/TestSourceVersionWarnings.java index a89d947d7b2..bba89985c57 100644 --- a/langtools/test/tools/javac/processing/warnings/TestSourceVersionWarnings.java +++ b/langtools/test/tools/javac/processing/warnings/TestSourceVersionWarnings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -50,7 +50,8 @@ import static javax.tools.Diagnostic.Kind.*; /** * This processor returns the supported source level as indicated by - * the "SourceLevel" option. + * the "SourceLevel" option; therefore, don't use + * JavacTestingAbstractProcessor which returns the latest source level. */ @SupportedAnnotationTypes("*") @SupportedOptions("SourceVersion") diff --git a/langtools/test/tools/javac/processing/werror/WError1.java b/langtools/test/tools/javac/processing/werror/WError1.java index a247b72723e..08cbe7383d7 100644 --- a/langtools/test/tools/javac/processing/werror/WError1.java +++ b/langtools/test/tools/javac/processing/werror/WError1.java @@ -24,6 +24,8 @@ /* * @test 6403456 * @summary -Werror should work with annotation processing + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile WError1.java * @compile -proc:only -processor WError1 WError1.java * @compile/fail/ref=WError1.out -XDrawDiagnostics -Werror -proc:only -processor WError1 WError1.java @@ -36,22 +38,15 @@ import javax.lang.model.*; import javax.lang.model.element.*; import javax.tools.*; -@SupportedAnnotationTypes("*") -public class WError1 extends AbstractProcessor { +public class WError1 extends JavacTestingAbstractProcessor { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { - Messager messager = processingEnv.getMessager(); if (++round == 1) { messager.printMessage(Diagnostic.Kind.WARNING, "round 1"); } return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - int round = 0; } diff --git a/langtools/test/tools/javac/processing/werror/WErrorGen.java b/langtools/test/tools/javac/processing/werror/WErrorGen.java index 3c622f009f7..383ee791af9 100644 --- a/langtools/test/tools/javac/processing/werror/WErrorGen.java +++ b/langtools/test/tools/javac/processing/werror/WErrorGen.java @@ -24,6 +24,8 @@ /* * @test 6403456 * @summary -Werror should work with annotation processing + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile WErrorGen.java * @compile -proc:only -processor WErrorGen WErrorGen.java * @compile/fail/ref=WErrorGen.out -XDrawDiagnostics -Werror -Xlint:rawtypes -processor WErrorGen WErrorGen.java @@ -36,12 +38,10 @@ import javax.lang.model.*; import javax.lang.model.element.*; import javax.tools.*; -@SupportedAnnotationTypes("*") -public class WErrorGen extends AbstractProcessor { +public class WErrorGen extends JavacTestingAbstractProcessor { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { - Filer filer = processingEnv.getFiler(); if (++round == 1) { try { JavaFileObject fo = filer.createSourceFile("Gen"); @@ -54,10 +54,5 @@ public class WErrorGen extends AbstractProcessor { return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - int round = 0; } diff --git a/langtools/test/tools/javac/processing/werror/WErrorLast.java b/langtools/test/tools/javac/processing/werror/WErrorLast.java index e2ba67f5c9e..33578c84846 100644 --- a/langtools/test/tools/javac/processing/werror/WErrorLast.java +++ b/langtools/test/tools/javac/processing/werror/WErrorLast.java @@ -24,6 +24,8 @@ /* * @test 6403456 * @summary -Werror should work with annotation processing + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile WErrorLast.java * @compile -proc:only -processor WErrorLast WErrorLast.java * @compile/fail/ref=WErrorLast.out -XDrawDiagnostics -Werror -proc:only -processor WErrorLast WErrorLast.java @@ -36,20 +38,13 @@ import javax.lang.model.*; import javax.lang.model.element.*; import javax.tools.*; -@SupportedAnnotationTypes("*") -public class WErrorLast extends AbstractProcessor { +public class WErrorLast extends JavacTestingAbstractProcessor { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { - Messager messager = processingEnv.getMessager(); if (roundEnv.processingOver()) { messager.printMessage(Diagnostic.Kind.WARNING, "last round"); } return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/tree/TreePosRoundsTest.java b/langtools/test/tools/javac/tree/TreePosRoundsTest.java new file mode 100644 index 00000000000..29a41b60795 --- /dev/null +++ b/langtools/test/tools/javac/tree/TreePosRoundsTest.java @@ -0,0 +1,205 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6985205 6986246 + * @summary access to tree positions and doc comments may be lost across annotation processing rounds + * @build TreePosRoundsTest + * @compile -proc:only -processor TreePosRoundsTest TreePosRoundsTest.java + * @run main TreePosRoundsTest + */ + +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.tools.*; + +import com.sun.source.tree.*; +import com.sun.source.util.*; +import javax.tools.JavaCompiler.CompilationTask; + +// This test is an annotation processor that performs multiple rounds of +// processing, and on each round, it checks that source positions are +// available and correct. +// +// The test can be run directly as a processor from the javac command line +// or via JSR 199 by invoking the main program. + +@SupportedAnnotationTypes("*") +public class TreePosRoundsTest extends AbstractProcessor { + public static void main(String... args) throws Exception { + String testSrc = System.getProperty("test.src"); + String testClasses = System.getProperty("test.classes"); + JavaCompiler c = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); + String thisName = TreePosRoundsTest.class.getName(); + File thisFile = new File(testSrc, thisName + ".java"); + Iterable files = fm.getJavaFileObjects(thisFile); + List options = Arrays.asList( + "-proc:only", + "-processor", thisName, + "-processorpath", testClasses); + CompilationTask t = c.getTask(null, fm, null, options, null, files); + boolean ok = t.call(); + if (!ok) + throw new Exception("processing failed"); + } + + Filer filer; + Messager messager; + Trees trees; + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + @Override + public void init(ProcessingEnvironment pEnv) { + super.init(pEnv); + filer = pEnv.getFiler(); + messager = pEnv.getMessager(); + trees = Trees.instance(pEnv); + } + + int round = 0; + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + round++; + + // Scan trees for elements, verifying source tree positions + for (Element e: roundEnv.getRootElements()) { + try { + TreePath p = trees.getPath(e); + new TestTreeScanner(p.getCompilationUnit(), trees).scan(trees.getPath(e), null); + } catch (IOException ex) { + messager.printMessage(Diagnostic.Kind.ERROR, + "Cannot get source: " + ex, e); + } + } + + final int MAXROUNDS = 3; + if (round < MAXROUNDS) + generateSource("Gen" + round); + + return true; + } + + void generateSource(String name) { + StringBuilder text = new StringBuilder(); + text.append("class ").append(name).append("{\n"); + text.append(" int one = 1;\n"); + text.append(" int two = 2;\n"); + text.append(" int three = one + two;\n"); + text.append("}\n"); + + try { + JavaFileObject fo = filer.createSourceFile(name); + Writer out = fo.openWriter(); + try { + out.write(text.toString()); + } finally { + out.close(); + } + } catch (IOException e) { + throw new Error(e); + } + } + + class TestTreeScanner extends TreePathScanner { + TestTreeScanner(CompilationUnitTree unit, Trees trees) throws IOException { + this.unit = unit; + JavaFileObject sf = unit.getSourceFile(); + source = sf.getCharContent(true).toString(); + sourcePositions = trees.getSourcePositions(); + } + + @Override + public Void visitVariable(VariableTree tree, Void _) { + check(getCurrentPath()); + return super.visitVariable(tree, _); + } + + void check(TreePath tp) { + Tree tree = tp.getLeaf(); + + String expect = tree.toString(); + if (tree.getKind() == Tree.Kind.VARIABLE) { + // tree.toString() does not know enough context to add ";", + // so deal with that manually... + Tree.Kind enclKind = tp.getParentPath().getLeaf().getKind(); + //System.err.println(" encl: " +enclKind); + if (enclKind == Tree.Kind.CLASS || enclKind == Tree.Kind.BLOCK) + expect += ";"; + } + //System.err.println("expect: " + expect); + + int start = (int)sourcePositions.getStartPosition(unit, tree); + if (start == Diagnostic.NOPOS) { + messager.printMessage(Diagnostic.Kind.ERROR, "start pos not set for " + trim(tree)); + return; + } + + int end = (int)sourcePositions.getEndPosition(unit, tree); + if (end == Diagnostic.NOPOS) { + messager.printMessage(Diagnostic.Kind.ERROR, "end pos not set for " + trim(tree)); + return; + } + + String found = source.substring(start, end); + //System.err.println(" found: " + found); + + // allow for long lines, in which case just compare beginning and + // end of the strings + boolean equal; + if (found.contains("\n")) { + String head = found.substring(0, found.indexOf("\n")); + String tail = found.substring(found.lastIndexOf("\n")).trim(); + equal = expect.startsWith(head) && expect.endsWith(tail); + } else { + equal = expect.equals(found); + } + + if (!equal) { + messager.printMessage(Diagnostic.Kind.ERROR, + "unexpected value found: '" + found + "'; expected: '" + expect + "'"); + } + } + + String trim(Tree tree) { + final int MAXLEN = 32; + String s = tree.toString().replaceAll("\\s+", " ").trim(); + return (s.length() < MAXLEN) ? s : s.substring(0, MAXLEN); + + } + + CompilationUnitTree unit; + SourcePositions sourcePositions; + String source; + } + +} diff --git a/langtools/test/tools/javah/VersionTest.java b/langtools/test/tools/javah/VersionTest.java new file mode 100644 index 00000000000..12e18d971bf --- /dev/null +++ b/langtools/test/tools/javah/VersionTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6890226 + * @summary javah -version is broken + */ + +import java.io.*; +import java.util.Locale; + +public class VersionTest { + public static void main(String... args) { + Locale prev = Locale.getDefault(); + try { + Locale.setDefault(Locale.ENGLISH); + System.err.println(Locale.getDefault()); + test("-version", "\\S+ version \"\\S+\""); + test("-fullversion", "\\S+ full version \"\\S+\""); + } finally { + Locale.setDefault(prev); + } + } + + static void test(String option, String regex) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + String[] args = { option }; + int rc = com.sun.tools.javah.Main.run(args, pw); + pw.close(); + if (rc != 0) + throw new Error("javah failed: rc=" + rc); + String out = sw.toString().trim(); + System.err.println(out); + if (!out.matches(regex)) + throw new Error("output does not match pattern: " + regex); + } +} diff --git a/make/jprt.properties b/make/jprt.properties index 6a4541d0ab6..777e27c8a2f 100644 --- a/make/jprt.properties +++ b/make/jprt.properties @@ -25,49 +25,310 @@ # Properties for jprt -# Use whatever release that the submitted job requests +# At submit time, the release supplied will be in jprt.submit.release +# and will be one of the official release names defined in jprt. +# jprt supports property value expansion using ${property.name} syntax. + +# This tells jprt what default release we want to build jprt.tools.default.release=${jprt.submit.release} # The different build flavors we want, we override here so we just get these 2 jprt.build.flavors=product,fastdebug -# Shortened list of vm tests -jprt.test.targets= \ - *-product-*-jvm98, \ - *-product-*-scimark, \ - *-product-*-runThese, \ - *-product-*-GCBasher_default, \ - *-product-*-GCOld_default, \ - *-product-*-jbb_default +# Define the Windows we want (temporary) +jprt.my.windows.i586.jdk7b107=windows_i586_5.0 +jprt.my.windows.i586.jdk7temp=windows_i586_5.0 +jprt.my.windows.i586.jdk7=windows_i586_5.1 +jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}} -# Test targets in test/Makefile -jprt.make.rule.test.targets= \ - *-product-*-langtools_jtreg, \ - *-product-*-jdk_beans1, \ - *-product-*-jdk_beans2, \ - *-product-*-jdk_beans3, \ - *-product-*-jdk_io, \ - *-product-*-jdk_lang, \ - *-product-*-jdk_management1, \ - *-product-*-jdk_management2, \ - *-product-*-jdk_math, \ - *-product-*-jdk_misc, \ - *-product-*-jdk_net, \ - *-product-*-jdk_nio1, \ - *-product-*-jdk_nio2, \ - *-product-*-jdk_nio3, \ - *-product-*-jdk_security1, \ - *-product-*-jdk_security2, \ - *-product-*-jdk_security3, \ - *-product-*-jdk_text, \ - *-product-*-jdk_tools1, \ - *-product-*-jdk_tools2, \ - *-product-*-jdk_util +# Standard list of jprt build targets for this source tree +jprt.build.targets= \ + solaris_sparc_5.10-{product|fastdebug}, \ + solaris_sparcv9_5.10-{product|fastdebug}, \ + solaris_i586_5.10-{product|fastdebug}, \ + solaris_x64_5.10-{product|fastdebug}, \ + linux_i586_2.6-{product|fastdebug}, \ + linux_x64_2.6-{product|fastdebug}, \ + ${jprt.my.windows.i586}-{product|fastdebug}, \ + windows_x64_5.2-{product|fastdebug} -# Not Ready Yet: -# *-product-*-jdk_awt -# *-product-*-jdk_rmi -# *-product-*-jdk_swing +# User can select the test set with jprt submit "-testset name" option +jprt.my.test.set=${jprt.test.set} + +# Default vm test targets (no fastdebug & limited c2 testing) +jprt.vm.default.test.targets= \ + \ + solaris_sparc_5.10-product-c1-jvm98, \ + solaris_sparcv9_5.10-product-c2-jvm98, \ + solaris_i586_5.10-product-c1-jvm98, \ + solaris_x64_5.10-product-c2-jvm98, \ + linux_i586_2.6-product-{c1|c2}-jvm98, \ + linux_x64_2.6-product-c2-jvm98, \ + ${jprt.my.windows.i586}-product-c1-jvm98, \ + windows_x64_5.2-product-c2-jvm98, \ + \ + solaris_sparc_5.10-product-c1-scimark, \ + solaris_sparcv9_5.10-product-c2-scimark, \ + solaris_i586_5.10-product-c1-scimark, \ + solaris_x64_5.10-product-c2-scimark, \ + linux_i586_2.6-product-{c1|c2}-scimark, \ + linux_x64_2.6-product-c2-scimark, \ + ${jprt.my.windows.i586}-product-c1-scimark, \ + windows_x64_5.2-product-c2-scimark + +# Default jdk test targets in test/Makefile (no fastdebug & limited c2 testing) +jprt.make.rule.default.test.targets= \ + \ + solaris_sparc_5.10-product-c1-langtools_jtreg, \ + solaris_sparcv9_5.10-product-c2-langtools_jtreg, \ + solaris_i586_5.10-product-c1-langtools_jtreg, \ + solaris_x64_5.10-product-c2-langtools_jtreg, \ + linux_i586_2.6-product-{c1|c2}-langtools_jtreg, \ + linux_x64_2.6-product-c2-langtools_jtreg, \ + ${jprt.my.windows.i586}-product-c1-langtools_jtreg, \ + windows_x64_5.2-product-c2-langtools_jtreg, \ + \ + solaris_sparc_5.10-product-c1-jdk_beans1, \ + solaris_sparcv9_5.10-product-c2-jdk_beans1, \ + solaris_i586_5.10-product-c1-jdk_beans1, \ + solaris_x64_5.10-product-c2-jdk_beans1, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans1, \ + linux_x64_2.6-product-c2-jdk_beans1, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans1, \ + windows_x64_5.2-product-c2-jdk_beans1, \ + \ + solaris_sparc_5.10-product-c1-jdk_io, \ + solaris_sparcv9_5.10-product-c2-jdk_io, \ + solaris_i586_5.10-product-c1-jdk_io, \ + solaris_x64_5.10-product-c2-jdk_io, \ + linux_i586_2.6-product-{c1|c2}-jdk_io, \ + linux_x64_2.6-product-c2-jdk_io, \ + ${jprt.my.windows.i586}-product-c1-jdk_io, \ + windows_x64_5.2-product-c2-jdk_io, \ + \ + solaris_sparc_5.10-product-c1-jdk_lang, \ + solaris_sparcv9_5.10-product-c2-jdk_lang, \ + solaris_i586_5.10-product-c1-jdk_lang, \ + solaris_x64_5.10-product-c2-jdk_lang, \ + linux_i586_2.6-product-{c1|c2}-jdk_lang, \ + linux_x64_2.6-product-c2-jdk_lang, \ + ${jprt.my.windows.i586}-product-c1-jdk_lang, \ + windows_x64_5.2-product-c2-jdk_lang, \ + \ + solaris_sparc_5.10-product-c1-jdk_math, \ + solaris_sparcv9_5.10-product-c2-jdk_math, \ + solaris_i586_5.10-product-c1-jdk_math, \ + solaris_x64_5.10-product-c2-jdk_math, \ + linux_i586_2.6-product-{c1|c2}-jdk_math, \ + linux_x64_2.6-product-c2-jdk_math, \ + ${jprt.my.windows.i586}-product-c1-jdk_math, \ + windows_x64_5.2-product-c2-jdk_math, \ + \ + solaris_sparc_5.10-product-c1-jdk_misc, \ + solaris_sparcv9_5.10-product-c2-jdk_misc, \ + solaris_i586_5.10-product-c1-jdk_misc, \ + solaris_x64_5.10-product-c2-jdk_misc, \ + linux_i586_2.6-product-{c1|c2}-jdk_misc, \ + linux_x64_2.6-product-c2-jdk_misc, \ + ${jprt.my.windows.i586}-product-c1-jdk_misc, \ + windows_x64_5.2-product-c2-jdk_misc, \ + \ + solaris_sparc_5.10-product-c1-jdk_net, \ + solaris_sparcv9_5.10-product-c2-jdk_net, \ + solaris_i586_5.10-product-c1-jdk_net, \ + solaris_x64_5.10-product-c2-jdk_net, \ + linux_i586_2.6-product-{c1|c2}-jdk_net, \ + linux_x64_2.6-product-c2-jdk_net, \ + ${jprt.my.windows.i586}-product-c1-jdk_net, \ + windows_x64_5.2-product-c2-jdk_net, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio1, \ + solaris_sparcv9_5.10-product-c2-jdk_nio1, \ + solaris_i586_5.10-product-c1-jdk_nio1, \ + solaris_x64_5.10-product-c2-jdk_nio1, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio1, \ + linux_x64_2.6-product-c2-jdk_nio1, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio1, \ + windows_x64_5.2-product-c2-jdk_nio1, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio2, \ + solaris_sparcv9_5.10-product-c2-jdk_nio2, \ + solaris_i586_5.10-product-c1-jdk_nio2, \ + solaris_x64_5.10-product-c2-jdk_nio2, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio2, \ + linux_x64_2.6-product-c2-jdk_nio2, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio2, \ + windows_x64_5.2-product-c2-jdk_nio2, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio3, \ + solaris_sparcv9_5.10-product-c2-jdk_nio3, \ + solaris_i586_5.10-product-c1-jdk_nio3, \ + solaris_x64_5.10-product-c2-jdk_nio3, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio3, \ + linux_x64_2.6-product-c2-jdk_nio3, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio3, \ + windows_x64_5.2-product-c2-jdk_nio3, \ + \ + solaris_sparc_5.10-product-c1-jdk_security1, \ + solaris_sparcv9_5.10-product-c2-jdk_security1, \ + solaris_i586_5.10-product-c1-jdk_security1, \ + solaris_x64_5.10-product-c2-jdk_security1, \ + linux_i586_2.6-product-{c1|c2}-jdk_security1, \ + linux_x64_2.6-product-c2-jdk_security1, \ + ${jprt.my.windows.i586}-product-c1-jdk_security1, \ + windows_x64_5.2-product-c2-jdk_security1, \ + \ + solaris_sparc_5.10-product-c1-jdk_text, \ + solaris_sparcv9_5.10-product-c2-jdk_text, \ + solaris_i586_5.10-product-c1-jdk_text, \ + solaris_x64_5.10-product-c2-jdk_text, \ + linux_i586_2.6-product-{c1|c2}-jdk_text, \ + linux_x64_2.6-product-c2-jdk_text, \ + ${jprt.my.windows.i586}-product-c1-jdk_text, \ + windows_x64_5.2-product-c2-jdk_text, \ + \ + solaris_sparc_5.10-product-c1-jdk_tools1, \ + solaris_sparcv9_5.10-product-c2-jdk_tools1, \ + solaris_i586_5.10-product-c1-jdk_tools1, \ + solaris_x64_5.10-product-c2-jdk_tools1, \ + linux_i586_2.6-product-{c1|c2}-jdk_tools1, \ + linux_x64_2.6-product-c2-jdk_tools1, \ + ${jprt.my.windows.i586}-product-c1-jdk_tools1, \ + windows_x64_5.2-product-c2-jdk_tools1, \ + \ + solaris_sparc_5.10-product-c1-jdk_util, \ + solaris_sparcv9_5.10-product-c2-jdk_util, \ + solaris_i586_5.10-product-c1-jdk_util, \ + solaris_x64_5.10-product-c2-jdk_util, \ + linux_i586_2.6-product-{c1|c2}-jdk_util, \ + linux_x64_2.6-product-c2-jdk_util, \ + ${jprt.my.windows.i586}-product-c1-jdk_util, \ + windows_x64_5.2-product-c2-jdk_util + +# All vm test targets (but still no fastdebug & limited c2 testing) +jprt.vm.all.test.targets= \ + \ + ${jprt.vm.default.test.targets}, \ + \ + solaris_sparc_5.10-product-c1-runThese, \ + solaris_sparcv9_5.10-product-c2-runThese, \ + solaris_i586_5.10-product-c1-runThese, \ + solaris_x64_5.10-product-c2-runThese, \ + linux_i586_2.6-product-{c1|c2}-runThese, \ + linux_x64_2.6-product-c2-runThese, \ + ${jprt.my.windows.i586}-product-c1-runThese, \ + windows_x64_5.2-product-c2-runThese, \ + \ + solaris_sparc_5.10-product-c1-jbb_default, \ + solaris_sparcv9_5.10-product-c2-jbb_default, \ + solaris_i586_5.10-product-c1-jbb_default, \ + solaris_x64_5.10-product-c2-jbb_default, \ + linux_i586_2.6-product-{c1|c2}-jbb_default, \ + linux_x64_2.6-product-c2-jbb_default, \ + ${jprt.my.windows.i586}-product-c1-jbb_default, \ + windows_x64_5.2-product-c2-jbb_default + +# All jdk test targets (but still no fastdebug & limited c2 testing) +jprt.make.rule.all.test.targets= \ + \ + ${jprt.make.rule.default.test.targets}, \ + \ + solaris_sparc_5.10-product-c1-jdk_awt, \ + solaris_sparcv9_5.10-product-c2-jdk_awt, \ + solaris_i586_5.10-product-c1-jdk_awt, \ + solaris_x64_5.10-product-c2-jdk_awt, \ + linux_i586_2.6-product-{c1|c2}-jdk_awt, \ + linux_x64_2.6-product-c2-jdk_awt, \ + ${jprt.my.windows.i586}-product-c1-jdk_awt, \ + windows_x64_5.2-product-c2-jdk_awt, \ + \ + solaris_sparc_5.10-product-c1-jdk_beans2, \ + solaris_sparcv9_5.10-product-c2-jdk_beans2, \ + solaris_i586_5.10-product-c1-jdk_beans2, \ + solaris_x64_5.10-product-c2-jdk_beans2, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans2, \ + linux_x64_2.6-product-c2-jdk_beans2, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans2, \ + windows_x64_5.2-product-c2-jdk_beans2, \ + \ + solaris_sparc_5.10-product-c1-jdk_beans3, \ + solaris_sparcv9_5.10-product-c2-jdk_beans3, \ + solaris_i586_5.10-product-c1-jdk_beans3, \ + solaris_x64_5.10-product-c2-jdk_beans3, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans3, \ + linux_x64_2.6-product-c2-jdk_beans3, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans3, \ + windows_x64_5.2-product-c2-jdk_beans3, \ + \ + solaris_sparc_5.10-product-c1-jdk_management1, \ + solaris_sparcv9_5.10-product-c2-jdk_management1, \ + solaris_i586_5.10-product-c1-jdk_management1, \ + solaris_x64_5.10-product-c2-jdk_management1, \ + linux_i586_2.6-product-{c1|c2}-jdk_management1, \ + linux_x64_2.6-product-c2-jdk_management1, \ + ${jprt.my.windows.i586}-product-c1-jdk_management1, \ + windows_x64_5.2-product-c2-jdk_management1, \ + \ + solaris_sparc_5.10-product-c1-jdk_management2, \ + solaris_sparcv9_5.10-product-c2-jdk_management2, \ + solaris_i586_5.10-product-c1-jdk_management2, \ + solaris_x64_5.10-product-c2-jdk_management2, \ + linux_i586_2.6-product-{c1|c2}-jdk_management2, \ + linux_x64_2.6-product-c2-jdk_management2, \ + ${jprt.my.windows.i586}-product-c1-jdk_management2, \ + windows_x64_5.2-product-c2-jdk_management2, \ + \ + solaris_sparc_5.10-product-c1-jdk_rmi, \ + solaris_sparcv9_5.10-product-c2-jdk_rmi, \ + solaris_i586_5.10-product-c1-jdk_rmi, \ + solaris_x64_5.10-product-c2-jdk_rmi, \ + linux_i586_2.6-product-{c1|c2}-jdk_rmi, \ + linux_x64_2.6-product-c2-jdk_rmi, \ + ${jprt.my.windows.i586}-product-c1-jdk_rmi, \ + windows_x64_5.2-product-c2-jdk_rmi, \ + \ + solaris_sparc_5.10-product-c1-jdk_security2, \ + solaris_sparcv9_5.10-product-c2-jdk_security2, \ + solaris_i586_5.10-product-c1-jdk_security2, \ + solaris_x64_5.10-product-c2-jdk_security2, \ + linux_i586_2.6-product-{c1|c2}-jdk_security2, \ + linux_x64_2.6-product-c2-jdk_security2, \ + ${jprt.my.windows.i586}-product-c1-jdk_security2, \ + windows_x64_5.2-product-c2-jdk_security2, \ + \ + solaris_sparc_5.10-product-c1-jdk_security3, \ + solaris_sparcv9_5.10-product-c2-jdk_security3, \ + solaris_i586_5.10-product-c1-jdk_security3, \ + solaris_x64_5.10-product-c2-jdk_security3, \ + linux_i586_2.6-product-{c1|c2}-jdk_security3, \ + linux_x64_2.6-product-c2-jdk_security3, \ + ${jprt.my.windows.i586}-product-c1-jdk_security3, \ + windows_x64_5.2-product-c2-jdk_security3, \ + \ + solaris_sparc_5.10-product-c1-jdk_swing, \ + solaris_sparcv9_5.10-product-c2-jdk_swing, \ + solaris_i586_5.10-product-c1-jdk_swing, \ + solaris_x64_5.10-product-c2-jdk_swing, \ + linux_i586_2.6-product-{c1|c2}-jdk_swing, \ + linux_x64_2.6-product-c2-jdk_swing, \ + ${jprt.my.windows.i586}-product-c1-jdk_swing, \ + windows_x64_5.2-product-c2-jdk_swing, \ + \ + solaris_sparc_5.10-product-c1-jdk_tools2, \ + solaris_sparcv9_5.10-product-c2-jdk_tools2, \ + solaris_i586_5.10-product-c1-jdk_tools2, \ + solaris_x64_5.10-product-c2-jdk_tools2, \ + linux_i586_2.6-product-{c1|c2}-jdk_tools2, \ + linux_x64_2.6-product-c2-jdk_tools2, \ + ${jprt.my.windows.i586}-product-c1-jdk_tools2, \ + windows_x64_5.2-product-c2-jdk_tools2 + +# Select list to use (allow for testset to be empty too) +jprt.make.rule..test.targets=${jprt.make.rule.default.test.targets} +jprt.make.rule.test.targets=${jprt.make.rule.${jprt.my.test.set}.test.targets} +jprt.vm..test.targets=${jprt.vm.default.test.targets} +jprt.vm.test.targets=${jprt.vm.${jprt.my.test.set}.test.targets} +jprt.test.targets=${jprt.vm.test.targets} # Directories to be excluded from the source bundles jprt.bundle.exclude.src.dirs=build dist webrev