--- a/.hgtags Wed Mar 17 12:48:21 2010 +0300
+++ b/.hgtags Wed Mar 17 14:19:07 2010 -0700
@@ -59,3 +59,4 @@
a30062be6d9ca1d48579826f870f85974300004e jdk7-b82
34c8199936a1682aa8587857f44cfaf37c2b6381 jdk7-b83
b1e55627a6980b9508854ed0c0f21d4f981b4494 jdk7-b84
+b6f633a93ae0ec4555ff4bf756f5e2150c9bdede jdk7-b85
--- a/.hgtags-top-repo Wed Mar 17 12:48:21 2010 +0300
+++ b/.hgtags-top-repo Wed Mar 17 14:19:07 2010 -0700
@@ -59,3 +59,4 @@
e1176f86805fe07fd9fb9da065dc51b47712ce76 jdk7-b82
6880a3af9addb41541e80ebe8cde6f79ec402a58 jdk7-b83
2f3ea057d1ad56cf3b269cdc4de2741411151982 jdk7-b84
+cf26288a114be67c39f2758959ce50b60f5ae330 jdk7-b85
--- a/corba/.hgtags Wed Mar 17 12:48:21 2010 +0300
+++ b/corba/.hgtags Wed Mar 17 14:19:07 2010 -0700
@@ -59,3 +59,4 @@
1e8c1bfad1abb4b81407a0f2645e0fb85764ca48 jdk7-b82
fde0df7a2384f7fe33204a79678989807d9c2b98 jdk7-b83
68c8961a82e4a3ad2a67991e5d834192a81eb4cd jdk7-b84
+c67a9df7bc0ca291f08f9a9cc05cb78ea15d25e6 jdk7-b85
--- a/hotspot/.hgtags Wed Mar 17 12:48:21 2010 +0300
+++ b/hotspot/.hgtags Wed Mar 17 14:19:07 2010 -0700
@@ -81,3 +81,5 @@
fafab5d5349c7c066d677538db67a1ee0fb33bd2 hs15-b05
3f370a32906eb5ba993fabd7b4279be7f31052b9 jdk7-b83
ffc8d176b84bcfb5ac21302b4feb3b0c0d69b97c jdk7-b84
+6c9796468b91dcbb39e09dfa1baf9779ac45eb66 jdk7-b85
+418bc80ce13995149eadc9eecbba21d7a9fa02ae hs17-b10
--- a/jaxp/.hgtags Wed Mar 17 12:48:21 2010 +0300
+++ b/jaxp/.hgtags Wed Mar 17 14:19:07 2010 -0700
@@ -59,3 +59,4 @@
c876ad22e4bf9d3c6460080db7ace478e29a3ff9 jdk7-b82
309a0a7fc6ceb1c9fc3a85b3608e97ef8f7b0dfd jdk7-b83
32c0cf01d555747918529a6ff9e06b0090c7a474 jdk7-b84
+6c0ccabb430dacdcd4479f8b197980d5da4eeb66 jdk7-b85
--- a/jaxws/.hgtags Wed Mar 17 12:48:21 2010 +0300
+++ b/jaxws/.hgtags Wed Mar 17 14:19:07 2010 -0700
@@ -59,3 +59,4 @@
31573ae8eed15a6c170f3f0d1abd0b9109c0e086 jdk7-b82
371e3ded591d09112a9f231e37cb072781c486ac jdk7-b83
8bc02839eee4ef02cd1b50e87638874368a26535 jdk7-b84
+8424512588ff95362c1f1e5f11c6efd4e7f7db6e jdk7-b85
--- a/jdk/.hgtags Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/.hgtags Wed Mar 17 14:19:07 2010 -0700
@@ -59,3 +59,4 @@
69ef657320ad5c35cfa12e4d8322d877e778f8b3 jdk7-b82
9027c6b9d7e2c9ca04a1add691b5b50d0f22b1aa jdk7-b83
7cb9388bb1a16365fa5118c5efa38b1cd58be40d jdk7-b84
+b396584a3e64988839cca21ea1f7fbdcc9248783 jdk7-b85
--- a/jdk/make/common/shared/Sanity.gmk Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/make/common/shared/Sanity.gmk Wed Mar 17 14:19:07 2010 -0700
@@ -687,13 +687,13 @@
######################################################
sane-alt_outputdir:
ifdef ALT_OUTPUTDIR
- @if [ `$(ECHO) $(subst \,/,$(ALT_OUTPUTDIR)) | $(EGREP) -ci '^([a-z]:)?/'` -ne 1 ]; then \
+ @if [ `$(ECHO) $(subst \,/,$(ALT_OUTPUTDIR)) | $(EGREP) -c '^([A-Za-z]:)?/'` -ne 1 ]; then \
$(ECHO) "ERROR: ALT_OUTPUTDIR must be an Absolute Path Name, \n" \
" not a Relative Path Name. \n" \
"" >> $(ERROR_FILE) ; \
fi
ifeq ($(PLATFORM), windows)
- @if [ `$(ECHO) $(subst \,/,$(ALT_OUTPUTDIR)) | $(EGREP) -ci '^([a-z]:)'` -ne 1 ]; then \
+ @if [ `$(ECHO) $(subst \,/,$(ALT_OUTPUTDIR)) | $(EGREP) -c '^([A-Za-z]:)'` -ne 1 ]; then \
$(ECHO) "ERROR: On windows, ALT_OUTPUTDIR must contain the drive letter. \n" \
"" >> $(ERROR_FILE) ; \
fi
@@ -742,7 +742,7 @@
######################################################
sane-alt_bootdir:
ifdef ALT_BOOTDIR
- @if [ `$(ECHO) $(subst \,/,$(ALT_BOOTDIR)) | $(EGREP) -ci '^([a-z]:)?/'` -ne 1 ]; then \
+ @if [ `$(ECHO) $(subst \,/,$(ALT_BOOTDIR)) | $(EGREP) -c '^([A-Za-z]:)?/'` -ne 1 ]; then \
$(ECHO) "ERROR: ALT_BOOTDIR must be an Absolute Path Name, \n" \
" not a Relative Path Name. \n" \
" The current value of ALT_BOOTDIR is \n" \
@@ -772,7 +772,7 @@
######################################################
sane-local-bootdir:
ifeq ($(PLATFORM), windows)
- @if [ `$(ECHO) $(BOOTDIR) | $(EGREP) -ci '^J:'` -ne 0 ]; then \
+ @if [ `$(ECHO) $(BOOTDIR) | $(EGREP) -c '^[jJ]:'` -ne 0 ]; then \
$(ECHO) "WARNING: Your BOOTDIR is located on the J: drive. Often the J:\n" \
" drive is mapped over a network. Using a mapped drive for\n" \
" the BOOTDIR may significantly slow down the build process.\n" \
@@ -789,7 +789,7 @@
######################################################
sane-cacerts:
ifdef ALT_CACERTS_FILE
- @if [ `$(ECHO) $(subst \,/,$(ALT_CACERTS_FILE)) | $(EGREP) -ci '^([a-z]:)?/'` -ne 1 ]; then \
+ @if [ `$(ECHO) $(subst \,/,$(ALT_CACERTS_FILE)) | $(EGREP) -c '^([A-Za-z]:)?/'` -ne 1 ]; then \
$(ECHO) "ERROR: ALT_CACERTS_FILE must be an Absolute Path Name, \n" \
" not a Relative Path Name. \n" \
" The current value of ALT_CACERTS_FILE is \n" \
@@ -1538,7 +1538,7 @@
sane-mozilla:
ifeq ($(ARCH_DATA_MODEL), 32)
ifdef ALT_MOZILLA_HEADERS_PATH
- @if [ `$(ECHO) $(subst \,/,$(ALT_MOZILLA_HEADERS_PATH)) | $(EGREP) -ci '^([a-z]:)?/'` -ne 1 ]; then \
+ @if [ `$(ECHO) $(subst \,/,$(ALT_MOZILLA_HEADERS_PATH)) | $(EGREP) -c '^([A-Za-z]:)?/'` -ne 1 ]; then \
$(ECHO) "ERROR: ALT_MOZILLA_HEADERS_PATH must be an Absolute Path Name, \n" \
" not a Relative Path Name. \n" \
" The current value of ALT_MOZILLA_HEADERS_PATH is \n" \
--- a/jdk/make/modules/tools/Makefile Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/make/modules/tools/Makefile Wed Mar 17 14:19:07 2010 -0700
@@ -135,9 +135,8 @@
$(CLASSANALYZER_JAR_FILE): $(BUILDTOOL_MANIFEST_FILE) $(FILES_class)
@$(prep-target)
- $(CD) $(BUILDTOOLCLASSDIR) && \
- $(BOOT_JAR_CMD) cfm $@ $(BUILDTOOL_MANIFEST_FILE) \
- $(PKGDIR) $(BOOT_JAR_JFLAGS) || $(RM) $@
+ $(BOOT_JAR_CMD) cfm $@ $(BUILDTOOL_MANIFEST_FILE) \
+ -C $(BUILDTOOLCLASSDIR) $(PKGDIR) $(BOOT_JAR_JFLAGS) || $(RM) $@
@$(java-vm-cleanup)
$(BUILDTOOLJARDIR)/classfile.jar: $(FILES_classfile_class)
--- a/jdk/src/share/classes/com/sun/jndi/ldap/Filter.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/Filter.java Wed Mar 17 14:19:07 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
/**
* LDAP (RFC-1960) and LDAPv3 (RFC-2254) search filters.
*
+ * @author Xuelei Fan
* @author Vincent Ryan
* @author Jagane Sundar
* @author Rosanna Lee
@@ -258,7 +259,7 @@
byte[] answer = new byte[j];
System.arraycopy(tbuf, 0, answer, 0, j);
if (dbg) {
- Ber.dumpBER(System.err, null, answer, 0, j);
+ Ber.dumpBER(System.err, "", answer, 0, j);
}
return answer;
}
@@ -330,7 +331,7 @@
}
- valueStart = eq + 1; // value starts after equal sign
+ valueStart = eq + 1; // value starts after equal sign
valueEnd = filtEnd;
typeStart = filtStart; // beginning of string
@@ -355,20 +356,199 @@
break;
default:
typeEnd = eq;
+ //initializing ftype to make the compiler happy
+ ftype = 0x00;
+ break;
+ }
+
+ if (dbg) {
+ System.err.println("type: " + typeStart + ", " + typeEnd);
+ System.err.println("value: " + valueStart + ", " + valueEnd);
+ }
+
+ // check validity of type
+ //
+ // RFC4512 defines the type as the following ABNF:
+ // attr = attributedescription
+ // attributedescription = attributetype options
+ // attributetype = oid
+ // oid = descr / numericoid
+ // descr = keystring
+ // keystring = leadkeychar *keychar
+ // leadkeychar = ALPHA
+ // keychar = ALPHA / DIGIT / HYPHEN
+ // numericoid = number 1*( DOT number )
+ // number = DIGIT / ( LDIGIT 1*DIGIT )
+ // options = *( SEMI option )
+ // option = 1*keychar
+ //
+ // And RFC4515 defines the extensible type as the following ABNF:
+ // attr [dnattrs] [matchingrule] / [dnattrs] matchingrule
+ int optionsStart = -1;
+ int extensibleStart = -1;
+ if ((filter[typeStart] >= '0' && filter[typeStart] <= '9') ||
+ (filter[typeStart] >= 'A' && filter[typeStart] <= 'Z') ||
+ (filter[typeStart] >= 'a' && filter[typeStart] <= 'z')) {
+
+ boolean isNumericOid =
+ filter[typeStart] >= '0' && filter[typeStart] <= '9';
+ for (int i = typeStart + 1; i < typeEnd; i++) {
+ // ';' is an indicator of attribute options
+ if (filter[i] == ';') {
+ if (isNumericOid && filter[i - 1] == '.') {
+ throw new InvalidSearchFilterException(
+ "invalid attribute description");
+ }
+
+ // attribute options
+ optionsStart = i;
+ break;
+ }
+
+ // ':' is an indicator of extensible rules
+ if (filter[i] == ':' && ftype == LDAP_FILTER_EXT) {
+ if (isNumericOid && filter[i - 1] == '.') {
+ throw new InvalidSearchFilterException(
+ "invalid attribute description");
+ }
+
+ // extensible matching
+ extensibleStart = i;
+ break;
+ }
+
+ if (isNumericOid) {
+ // numeric object identifier
+ if ((filter[i] == '.' && filter[i - 1] == '.') ||
+ (filter[i] != '.' &&
+ !(filter[i] >= '0' && filter[i] <= '9'))) {
+ throw new InvalidSearchFilterException(
+ "invalid attribute description");
+ }
+ } else {
+ // descriptor
+ if (filter[i] != '-' &&
+ !(filter[i] >= '0' && filter[i] <= '9') &&
+ !(filter[i] >= 'A' && filter[i] <= 'Z') &&
+ !(filter[i] >= 'a' && filter[i] <= 'z')) {
+ throw new InvalidSearchFilterException(
+ "invalid attribute description");
+ }
+ }
+ }
+ } else if (ftype == LDAP_FILTER_EXT && filter[typeStart] == ':') {
+ // extensible matching
+ extensibleStart = typeStart;
+ } else {
+ throw new InvalidSearchFilterException(
+ "invalid attribute description");
+ }
+
+ // check attribute options
+ if (optionsStart > 0) {
+ for (int i = optionsStart + 1; i < typeEnd; i++) {
+ if (filter[i] == ';') {
+ if (filter[i - 1] == ';') {
+ throw new InvalidSearchFilterException(
+ "invalid attribute description");
+ }
+ continue;
+ }
+
+ // ':' is an indicator of extensible rules
+ if (filter[i] == ':' && ftype == LDAP_FILTER_EXT) {
+ if (filter[i - 1] == ';') {
+ throw new InvalidSearchFilterException(
+ "invalid attribute description");
+ }
+
+ // extensible matching
+ extensibleStart = i;
+ break;
+ }
+
+ if (filter[i] != '-' &&
+ !(filter[i] >= '0' && filter[i] <= '9') &&
+ !(filter[i] >= 'A' && filter[i] <= 'Z') &&
+ !(filter[i] >= 'a' && filter[i] <= 'z')) {
+ throw new InvalidSearchFilterException(
+ "invalid attribute description");
+ }
+ }
+ }
+
+ // check extensible matching
+ if (extensibleStart > 0) {
+ boolean isMatchingRule = false;
+ for (int i = extensibleStart + 1; i < typeEnd; i++) {
+ if (filter[i] == ':') {
+ throw new InvalidSearchFilterException(
+ "invalid attribute description");
+ } else if ((filter[i] >= '0' && filter[i] <= '9') ||
+ (filter[i] >= 'A' && filter[i] <= 'Z') ||
+ (filter[i] >= 'a' && filter[i] <= 'z')) {
+ boolean isNumericOid = filter[i] >= '0' && filter[i] <= '9';
+ i++;
+ for (int j = i; j < typeEnd; j++, i++) {
+ // allows no more than two extensible rules
+ if (filter[j] == ':') {
+ if (isMatchingRule) {
+ throw new InvalidSearchFilterException(
+ "invalid attribute description");
+ }
+ if (isNumericOid && filter[j - 1] == '.') {
+ throw new InvalidSearchFilterException(
+ "invalid attribute description");
+ }
+
+ isMatchingRule = true;
+ break;
+ }
+
+ if (isNumericOid) {
+ // numeric object identifier
+ if ((filter[j] == '.' && filter[j - 1] == '.') ||
+ (filter[j] != '.' &&
+ !(filter[j] >= '0' && filter[j] <= '9'))) {
+ throw new InvalidSearchFilterException(
+ "invalid attribute description");
+ }
+ } else {
+ // descriptor
+ if (filter[j] != '-' &&
+ !(filter[j] >= '0' && filter[j] <= '9') &&
+ !(filter[j] >= 'A' && filter[j] <= 'Z') &&
+ !(filter[j] >= 'a' && filter[j] <= 'z')) {
+ throw new InvalidSearchFilterException(
+ "invalid attribute description");
+ }
+ }
+ }
+ } else {
+ throw new InvalidSearchFilterException(
+ "invalid attribute description");
+ }
+ }
+ }
+
+ // ensure the latest byte is not isolated
+ if (filter[typeEnd - 1] == '.' || filter[typeEnd - 1] == ';' ||
+ filter[typeEnd - 1] == ':') {
+ throw new InvalidSearchFilterException(
+ "invalid attribute description");
+ }
+
+ if (typeEnd == eq) { // filter type is of "equal"
if (findUnescaped(filter, '*', valueStart, valueEnd) == -1) {
ftype = LDAP_FILTER_EQUALITY;
- } else if (filter[valueStart] == '*' && valueStart == (valueEnd - 1)) {
+ } else if (filter[valueStart] == '*' &&
+ valueStart == (valueEnd - 1)) {
ftype = LDAP_FILTER_PRESENT;
} else {
encodeSubstringFilter(ber, filter,
typeStart, typeEnd, valueStart, valueEnd);
return;
}
- break;
- }
- if (dbg) {
- System.err.println("type: " + typeStart + ", " + typeEnd);
- System.err.println("value: " + valueStart + ", " + valueEnd);
}
if (ftype == LDAP_FILTER_PRESENT) {
@@ -379,7 +559,7 @@
} else {
ber.beginSeq(ftype);
ber.encodeOctetString(filter, Ber.ASN_OCTET_STR,
- typeStart, typeEnd-typeStart);
+ typeStart, typeEnd - typeStart);
ber.encodeOctetString(
unescapeFilterValue(filter, valueStart, valueEnd),
Ber.ASN_OCTET_STR);
@@ -623,7 +803,8 @@
//
////////////////////////////////////////////////////////////////////////////
- private static final boolean dbg = false;
+ // private static final boolean dbg = false;
+ private static final boolean dbg = true;
private static int dbgIndent = 0;
private static void dprint(String msg) {
--- a/jdk/src/share/classes/java/awt/AlphaComposite.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/share/classes/java/awt/AlphaComposite.java Wed Mar 17 14:19:07 2010 -0700
@@ -614,14 +614,15 @@
}
private AlphaComposite(int rule, float alpha) {
- if (alpha < 0.0f || alpha > 1.0f) {
- throw new IllegalArgumentException("alpha value out of range");
- }
if (rule < MIN_RULE || rule > MAX_RULE) {
throw new IllegalArgumentException("unknown composite rule");
}
- this.rule = rule;
- this.extraAlpha = alpha;
+ if (alpha >= 0.0f && alpha <= 1.0f) {
+ this.rule = rule;
+ this.extraAlpha = alpha;
+ } else {
+ throw new IllegalArgumentException("alpha value out of range");
+ }
}
/**
--- a/jdk/src/share/classes/java/lang/Iterable.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/share/classes/java/lang/Iterable.java Wed Mar 17 14:19:07 2010 -0700
@@ -27,8 +27,12 @@
import java.util.Iterator;
-/** Implementing this interface allows an object to be the target of
- * the "foreach" statement.
+/**
+ * Implementing this interface allows an object to be the target of
+ * the "foreach" statement.
+ *
+ * @param <T> the type of elements returned by the iterator
+ *
* @since 1.5
*/
public interface Iterable<T> {
--- a/jdk/src/share/classes/java/lang/String.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/share/classes/java/lang/String.java Wed Mar 17 14:19:07 2010 -0700
@@ -1492,7 +1492,7 @@
*/
public int hashCode() {
int h = hash;
- if (h == 0) {
+ if (h == 0 && count > 0) {
int off = offset;
char val[] = value;
int len = count;
--- a/jdk/src/share/classes/java/security/IdentityScope.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/share/classes/java/security/IdentityScope.java Wed Mar 17 14:19:07 2010 -0700
@@ -129,7 +129,8 @@
/**
* Returns the system's identity scope.
*
- * @return the system's identity scope.
+ * @return the system's identity scope, or {@code null} if none has been
+ * set.
*
* @see #setSystemScope
*/
--- a/jdk/src/share/classes/java/util/Collection.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/share/classes/java/util/Collection.java Wed Mar 17 14:19:07 2010 -0700
@@ -103,6 +103,8 @@
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
+ * @param <E> the type of elements in this collection
+ *
* @author Josh Bloch
* @author Neal Gafter
* @see Set
--- a/jdk/src/share/classes/java/util/DualPivotQuicksort.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/share/classes/java/util/DualPivotQuicksort.java Wed Mar 17 14:19:07 2010 -0700
@@ -253,7 +253,7 @@
a[less] = ak;
}
less++;
- } else { // (a[k] > pivot1) - Move a[k] to right part
+ } 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
@@ -531,7 +531,7 @@
a[less] = ak;
}
less++;
- } else { // (a[k] > pivot1) - Move a[k] to right part
+ } 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
@@ -826,7 +826,7 @@
a[less] = ak;
}
less++;
- } else { // (a[k] > pivot1) - Move a[k] to right part
+ } 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
@@ -1119,7 +1119,7 @@
a[less] = ak;
}
less++;
- } else { // (a[k] > pivot1) - Move a[k] to right part
+ } 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
@@ -1414,7 +1414,7 @@
a[less] = ak;
}
less++;
- } else { // (a[k] > pivot1) - Move a[k] to right part
+ } 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
@@ -1531,7 +1531,7 @@
* 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 range to be sorted is empty and the call is a no-op).
*
* <p>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}
@@ -1787,7 +1787,7 @@
a[less] = ak;
}
less++;
- } else { // (a[k] > pivot1) - Move a[k] to right part
+ } 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
@@ -2160,7 +2160,7 @@
a[less] = ak;
}
less++;
- } else { // (a[k] > pivot1) - Move a[k] to right part
+ } 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
--- a/jdk/src/share/classes/java/util/Iterator.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/share/classes/java/util/Iterator.java Wed Mar 17 14:19:07 2010 -0700
@@ -41,6 +41,8 @@
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
+ * @param <E> the type of elements returned by this iterator
+ *
* @author Josh Bloch
* @see Collection
* @see ListIterator
--- a/jdk/src/share/classes/java/util/List.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/share/classes/java/util/List.java Wed Mar 17 14:19:07 2010 -0700
@@ -89,6 +89,8 @@
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
+ * @param <E> the type of elements in this list
+ *
* @author Josh Bloch
* @author Neal Gafter
* @see Collection
--- a/jdk/src/share/classes/sun/font/SunFontManager.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/share/classes/sun/font/SunFontManager.java Wed Mar 17 14:19:07 2010 -0700
@@ -3058,7 +3058,7 @@
return;
}
/* Use lock specific to the font system */
- synchronized (lucidaFontName) {
+ synchronized (this) {
if (FontUtilities.debugFonts()) {
Thread.dumpStack();
FontUtilities.getLogger()
@@ -3194,7 +3194,7 @@
return;
}
/* Use lock specific to the font system */
- synchronized (lucidaFontName) {
+ synchronized (this) {
if (FontUtilities.debugFonts()) {
Thread.dumpStack();
FontUtilities.getLogger().info("loadAllFontFiles() called");
--- a/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java Wed Mar 17 14:19:07 2010 -0700
@@ -59,10 +59,15 @@
// pending events
private List<WatchEvent<?>> events;
+ // maps a context to the last event for the context (iff the last queued
+ // event for the context is an ENTRY_MODIFY event).
+ private Map<Object,WatchEvent<?>> lastModifyEvents;
+
protected AbstractWatchKey(AbstractWatchService watcher) {
this.watcher = watcher;
this.state = State.READY;
this.events = new ArrayList<WatchEvent<?>>();
+ this.lastModifyEvents = new HashMap<Object,WatchEvent<?>>();
}
final AbstractWatchService watcher() {
@@ -86,6 +91,7 @@
*/
@SuppressWarnings("unchecked")
final void signalEvent(WatchEvent.Kind<?> kind, Object context) {
+ boolean isModify = (kind == StandardWatchEventKind.ENTRY_MODIFY);
synchronized (this) {
int size = events.size();
if (size > 0) {
@@ -100,17 +106,43 @@
return;
}
+ // if this is a modify event and the last entry for the context
+ // is a modify event then we simply increment the count
+ if (!lastModifyEvents.isEmpty()) {
+ if (isModify) {
+ WatchEvent<?> ev = lastModifyEvents.get(context);
+ if (ev != null) {
+ assert ev.kind() == StandardWatchEventKind.ENTRY_MODIFY;
+ ((Event<?>)ev).increment();
+ return;
+ }
+ } else {
+ // not a modify event so remove from the map as the
+ // last event will no longer be a modify event.
+ lastModifyEvents.remove(context);
+ }
+ }
+
// if the list has reached the limit then drop pending events
// and queue an OVERFLOW event
if (size >= MAX_EVENT_LIST_SIZE) {
- events.clear();
kind = StandardWatchEventKind.OVERFLOW;
+ isModify = false;
context = null;
}
}
// non-repeated event
- events.add(new Event<Object>((WatchEvent.Kind<Object>)kind, context));
+ Event<Object> ev =
+ new Event<Object>((WatchEvent.Kind<Object>)kind, context);
+ if (isModify) {
+ lastModifyEvents.put(context, ev);
+ } else if (kind == StandardWatchEventKind.OVERFLOW) {
+ // drop all pending events
+ events.clear();
+ lastModifyEvents.clear();
+ }
+ events.add(ev);
signal();
}
}
@@ -120,6 +152,7 @@
synchronized (this) {
List<WatchEvent<?>> result = events;
events = new ArrayList<WatchEvent<?>>();
+ lastModifyEvents.clear();
return result;
}
}
--- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/EType.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/EType.java Wed Mar 17 14:19:07 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Portions Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Portions Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,9 +36,9 @@
import sun.security.krb5.EncryptedData;
import sun.security.krb5.EncryptionKey;
import sun.security.krb5.KrbException;
-import sun.security.krb5.Asn1Exception;
import sun.security.krb5.KrbCryptoException;
import javax.crypto.*;
+import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
@@ -48,6 +48,23 @@
public abstract class EType {
private static final boolean DEBUG = Krb5.DEBUG;
+ private static final boolean ALLOW_WEAK_CRYPTO;
+
+ static {
+ boolean allowed = true;
+ try {
+ Config cfg = Config.getInstance();
+ String temp = cfg.getDefault("allow_weak_crypto", "libdefaults");
+ if (temp != null && temp.equals("false")) allowed = false;
+ } catch (Exception exc) {
+ if (DEBUG) {
+ System.out.println ("Exception in getting allow_weak_crypto, " +
+ "using default value " +
+ exc.getMessage());
+ }
+ }
+ ALLOW_WEAK_CRYPTO = allowed;
+ }
public static EType getInstance (int eTypeConst)
throws KdcErrException {
@@ -163,6 +180,10 @@
return result;
}
+ // Note: the first 2 entries of BUILTIN_ETYPES and BUILTIN_ETYPES_NOAES256
+ // should be kept DES-related. They will be removed when allow_weak_crypto
+ // is set to false.
+
private static final int[] BUILTIN_ETYPES = new int[] {
EncryptedData.ETYPE_DES_CBC_MD5,
EncryptedData.ETYPE_DES_CBC_CRC,
@@ -189,10 +210,17 @@
} catch (Exception e) {
// should not happen
}
+ int[] result;
if (allowed < 256) {
- return BUILTIN_ETYPES_NOAES256;
+ result = BUILTIN_ETYPES_NOAES256;
+ } else {
+ result = BUILTIN_ETYPES;
}
- return BUILTIN_ETYPES;
+ if (!ALLOW_WEAK_CRYPTO) {
+ // The first 2 etypes are now weak ones
+ return Arrays.copyOfRange(result, 2, result.length);
+ }
+ return result;
}
/**
@@ -207,9 +235,7 @@
if (DEBUG) {
System.out.println("Exception while getting " +
configName + exc.getMessage());
- System.out.println("Using defaults " +
- "des-cbc-md5, des-cbc-crc, des3-cbc-sha1," +
- " aes128cts, aes256cts, rc4-hmac");
+ System.out.println("Using default builtin etypes");
}
return getBuiltInDefaults();
}
--- a/jdk/src/share/classes/sun/security/provider/JavaKeyStore.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/share/classes/sun/security/provider/JavaKeyStore.java Wed Mar 17 14:19:07 2010 -0700
@@ -29,9 +29,9 @@
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.util.*;
+import sun.misc.IOUtils;
import sun.security.pkcs.EncryptedPrivateKeyInfo;
@@ -677,50 +677,39 @@
entry.date = new Date(dis.readLong());
// Read the private key
- try {
- entry.protectedPrivKey = new byte[dis.readInt()];
- } catch (OutOfMemoryError e) {
- throw new IOException("Keysize too big");
- }
- dis.readFully(entry.protectedPrivKey);
+ entry.protectedPrivKey =
+ IOUtils.readFully(dis, dis.readInt(), true);
// Read the certificate chain
int numOfCerts = dis.readInt();
- try {
- if (numOfCerts > 0) {
- entry.chain = new Certificate[numOfCerts];
+ if (numOfCerts > 0) {
+ List<Certificate> certs = new ArrayList<>(
+ numOfCerts > 10 ? 10 : numOfCerts);
+ for (int j = 0; j < numOfCerts; j++) {
+ if (xVersion == 2) {
+ // read the certificate type, and instantiate a
+ // certificate factory of that type (reuse
+ // existing factory if possible)
+ String certType = dis.readUTF();
+ if (cfs.containsKey(certType)) {
+ // reuse certificate factory
+ cf = cfs.get(certType);
+ } else {
+ // create new certificate factory
+ cf = CertificateFactory.getInstance(certType);
+ // store the certificate factory so we can
+ // reuse it later
+ cfs.put(certType, cf);
+ }
+ }
+ // instantiate the certificate
+ encoded = IOUtils.readFully(dis, dis.readInt(), true);
+ bais = new ByteArrayInputStream(encoded);
+ certs.add(cf.generateCertificate(bais));
+ bais.close();
}
- } catch (OutOfMemoryError e) {
- throw new IOException
- ("Too many certificates in chain");
- }
- for (int j = 0; j < numOfCerts; j++) {
- if (xVersion == 2) {
- // read the certificate type, and instantiate a
- // certificate factory of that type (reuse
- // existing factory if possible)
- String certType = dis.readUTF();
- if (cfs.containsKey(certType)) {
- // reuse certificate factory
- cf = cfs.get(certType);
- } else {
- // create new certificate factory
- cf = CertificateFactory.getInstance(certType);
- // store the certificate factory so we can
- // reuse it later
- cfs.put(certType, cf);
- }
- }
- // instantiate the certificate
- try {
- encoded = new byte[dis.readInt()];
- } catch (OutOfMemoryError e) {
- throw new IOException("Certificate too big");
- }
- dis.readFully(encoded);
- bais = new ByteArrayInputStream(encoded);
- entry.chain[j] = cf.generateCertificate(bais);
- bais.close();
+ // We can be sure now that numOfCerts of certs are read
+ entry.chain = certs.toArray(new Certificate[numOfCerts]);
}
// Add the entry to the list
@@ -753,12 +742,7 @@
cfs.put(certType, cf);
}
}
- try {
- encoded = new byte[dis.readInt()];
- } catch (OutOfMemoryError e) {
- throw new IOException("Certificate too big");
- }
- dis.readFully(encoded);
+ encoded = IOUtils.readFully(dis, dis.readInt(), true);
bais = new ByteArrayInputStream(encoded);
entry.cert = cf.generateCertificate(bais);
bais.close();
--- a/jdk/src/share/classes/sun/security/tools/TimestampedSigner.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/share/classes/sun/security/tools/TimestampedSigner.java Wed Mar 17 14:19:07 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2007-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -375,7 +375,8 @@
}
if (!isSigner) {
keyPurposes = cert.getExtendedKeyUsage();
- if (! keyPurposes.contains(KP_TIMESTAMPING_OID)) {
+ if (keyPurposes == null ||
+ ! keyPurposes.contains(KP_TIMESTAMPING_OID)) {
throw new CertificateException(
"Certificate is not valid for timestamping");
}
--- a/jdk/src/share/lib/security/java.security Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/share/lib/security/java.security Wed Mar 17 14:19:07 2010 -0700
@@ -118,11 +118,6 @@
keystore.type=jks
#
-# Class to instantiate as the system scope:
-#
-system.scope=sun.security.provider.IdentityDatabase
-
-#
# List of comma-separated packages that start with or equal this string
# will cause a security exception to be thrown when
# passed to checkPackageAccess unless the
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java Wed Mar 17 14:19:07 2010 -0700
@@ -624,8 +624,11 @@
public boolean endsWith(Path other) {
UnixPath that = checkPath(other);
+ int thisLen = path.length;
+ int thatLen = that.path.length;
+
// other path is longer
- if (that.path.length > path.length)
+ if (thatLen > thisLen)
return false;
// other path is absolute so this path must be absolute
@@ -643,10 +646,10 @@
if (thatOffsetCount == thisOffsetCount) {
if (thisOffsetCount == 0)
return true;
- int expectedLen = path.length;
+ int expectedLen = thisLen;
if (this.isAbsolute() && !that.isAbsolute())
expectedLen--;
- if (that.path.length != expectedLen)
+ if (thatLen != expectedLen)
return false;
} else {
// this path has more elements so given path must be relative
@@ -658,7 +661,9 @@
// compare bytes
int thisPos = offsets[thisOffsetCount - thatOffsetCount];
int thatPos = that.offsets[0];
- while (thatPos < that.path.length) {
+ if ((thatLen - thatPos) != (thisLen - thisPos))
+ return false;
+ while (thatPos < thatLen) {
if (this.path[thisPos++] != that.path[thatPos++])
return false;
}
--- a/jdk/src/solaris/native/java/io/UnixFileSystem_md.c Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/src/solaris/native/java/io/UnixFileSystem_md.c Wed Mar 17 14:19:07 2010 -0700
@@ -414,9 +414,9 @@
jlong rv = 0L;
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
- struct statvfs fsstat;
- memset(&fsstat, 0, sizeof(struct statvfs));
- if (statvfs(path, &fsstat) == 0) {
+ struct statvfs64 fsstat;
+ memset(&fsstat, 0, sizeof(fsstat));
+ if (statvfs64(path, &fsstat) == 0) {
switch(t) {
case java_io_FileSystem_SPACE_TOTAL:
rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
--- a/jdk/test/Makefile Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/test/Makefile Wed Mar 17 14:19:07 2010 -0700
@@ -1,5 +1,5 @@
#
-# Copyright 1995-2009 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 1995-2010 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -37,25 +37,19 @@
AWK = awk
CAT = cat
CD = cd
-CHMOD = chmod
CP = cp
CUT = cut
ECHO = echo
EGREP = egrep
EXPAND = expand
-EXPR = expr
-KILL = /usr/bin/kill
MKDIR = mkdir
-NOHUP = nohup
PWD = pwd
SED = sed
-SLEEP = sleep
SORT = sort
TEE = tee
UNAME = uname
UNIQ = uniq
WC = wc
-XHOST = xhost
ZIP = zip
# Get OS name from uname
@@ -211,66 +205,6 @@
ARCHIVE_BUNDLE = $(JPRT_ARCHIVE_BUNDLE)
endif
-# DISPLAY settings for virtual frame buffer
-START_XVFB = start-Xvfb.sh
-NOHUP_OUTPUT = $(ABS_TEST_OUTPUT_DIR)/start-Xvfb.nohup-output.txt
-DISPLAY_PID_FILE=$(ABS_TEST_OUTPUT_DIR)/xvfb-display-number.txt
-DISPLAY_SLEEP_TIME=10
-DISPLAY_MAX_SLEEPS=10
-ifeq ($(OS_NAME),solaris)
- VIRTUAL_FRAME_BUFFER = true
-endif
-ifeq ($(OS_NAME),linux)
- VIRTUAL_FRAME_BUFFER = true
-endif
-
-# Does not work yet, display dies as soon as it gets used. :^(
-VIRTUAL_FRAME_BUFFER = false
-
-# Are we using a VIRTUAL_FRAME_BUFFER (Xvfb)
-ifeq ($(VIRTUAL_FRAME_BUFFER),true)
-
- PREP_DISPLAY = \
- $(CP) $(START_XVFB) $(ABS_TEST_OUTPUT_DIR); \
- $(CHMOD) a+x $(ABS_TEST_OUTPUT_DIR)/$(START_XVFB); \
- ( $(CD) $(ABS_TEST_OUTPUT_DIR) && \
- $(NOHUP) $(ABS_TEST_OUTPUT_DIR)/$(START_XVFB) $(DISPLAY_PID_FILE) > $(NOHUP_OUTPUT) 2>&1 && \
- $(SLEEP) $(DISPLAY_SLEEP_TIME) ) & \
- count=1; \
- while [ ! -s $(DISPLAY_PID_FILE) ] ; do \
- $(ECHO) "Sleeping $(DISPLAY_SLEEP_TIME) more seconds, DISPLAY not ready"; \
- $(SLEEP) $(DISPLAY_SLEEP_TIME); \
- count=`$(EXPR) $${count} '+' 1`; \
- if [ $${count} -gt $(DISPLAY_MAX_SLEEPS) ] ; then \
- $(ECHO) "ERROR: DISPLAY not ready, giving up on DISPLAY"; \
- exit 9; \
- fi; \
- done ; \
- DISPLAY=":`$(CAT) $(DISPLAY_PID_FILE)`"; \
- export DISPLAY; \
- $(CAT) $(NOHUP_OUTPUT); \
- $(ECHO) "Prepared DISPLAY=$${DISPLAY}"; \
- $(XHOST) || \
- ( $(ECHO) "ERROR: No display" ; exit 8)
-
- KILL_DISPLAY = \
- ( \
- DISPLAY=":`$(CAT) $(DISPLAY_PID_FILE)`"; \
- export DISPLAY; \
- if [ -s "$(DISPLAY_PID_FILE)" ] ; then \
- $(KILL) `$(CAT) $(DISPLAY_PID_FILE)` > /dev/null 2>&1; \
- $(KILL) -9 `$(CAT) $(DISPLAY_PID_FILE)` > /dev/null 2>&1; \
- fi; \
- $(ECHO) "Killed DISPLAY=$${DISPLAY}"; \
- )
-
-else
-
- PREP_DISPLAY = $(ECHO) "VIRTUAL_FRAME_BUFFER=$(VIRTUAL_FRAME_BUFFER)"
- KILL_DISPLAY = $(ECHO) "VIRTUAL_FRAME_BUFFER=$(VIRTUAL_FRAME_BUFFER)"
-
-endif
-
# How to create the test bundle (pass or fail, we want to create this)
# Follow command with ";$(BUNDLE_UP_AND_EXIT)", so it always gets executed.
ZIP_UP_RESULTS = ( $(MKDIR) -p `dirname $(ARCHIVE_BUNDLE)` \
@@ -327,7 +261,7 @@
$(ECHO) "Missing file: $${_summary}" >> $(STATS_TXT); \
fi; \
$(CAT) $(STATS_TXT); \
- $(ZIP_UP_RESULTS) && $(KILL_DISPLAY) ; \
+ $(ZIP_UP_RESULTS) ; \
$(TESTEXIT) \
)
@@ -629,7 +563,6 @@
( \
( JT_HOME=$(shell $(GETMIXEDPATH) "$(JT_HOME)"); \
export JT_HOME; \
- $(PREP_DISPLAY) && \
$(shell $(GETMIXEDPATH) "$(JTREG)") \
$(JTREG_BASIC_OPTIONS) \
-r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/JTreport \
--- a/jdk/test/ProblemList.txt Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/test/ProblemList.txt Wed Mar 17 14:19:07 2010 -0700
@@ -1,6 +1,6 @@
###########################################################################
#
-# Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2009-2010 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -431,6 +431,12 @@
# jdk_management
+# Fails on linux: KO: StringMonitor notification missed or not emitted
+javax/management/monitor/NonComparableAttributeValueTest.java generic-all
+
+# Port conflict? Fails with communication error
+sun/management/jmxremote/bootstrap/PasswordFilePermissionTest.sh generic-all
+
# Fails on Windows 2000, Test failed for iiop java.lang.NullPointerException
# at org.omg.stub.javax.management.remote.rmi._RMIConnectionImpl_Tie._invoke(Unknown Source)
# at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:653)
@@ -583,6 +589,9 @@
# Suspect many of these tests auffer from using fixed ports, no concrete
# evidence.
+# Times out on Windows X64
+sun/net/www/http/KeepAliveStream/KeepAliveStreamCloseWithWrongContentLength.java generic-all
+
# Dies on Solaris 10 sparc and sparcv9, Linux -ea -esa with
# Interrupted or IO exception, maybe writing to non-unique named file?
com/sun/net/httpserver/bugs/B6373555.java generic-all
@@ -736,6 +745,13 @@
# Suspect many of these tests auffer from using fixed ports, no concrete
# evidence.
+# Occasionally Failing with java.lang.AssertionError on Windows X64
+# at sun.nio.ch.PendingIoCache.clearPendingIoMap(PendingIoCache.java:144)
+#java/nio/channels/FileChannel/ReleaseOnCloseDeadlock.java windows-all
+
+# Some kind of sleep/wake problem on Windows X64
+java/nio/channels/Selector/Wakeup.java windows-all
+
# Fails with -ea -esa, Assertion error, but only on Solaris 10 machines?
com/sun/nio/sctp/SctpChannel/Send.java generic-all
com/sun/nio/sctp/SctpChannel/Shutdown.java generic-all
@@ -932,6 +948,18 @@
# jdk_security
+# Unknown problem, could be a jtreg -samevm issue?
+# Error while cleaning up threads after test
+java/security/Security/SynchronizedAccess.java generic-all
+
+# Failing on Solaris X64 (-d64 -server) with:
+# GSSException: Failure unspecified at GSS-API level
+# (Mechanism level: Specified version of key is not available (44))
+sun/security/krb5/auto/BasicKrb5Test.java generic-all
+
+# Solaris X86 failures, readjar.jks: No such file or directory
+sun/security/tools/keytool/readjar.sh generic-all
+
# Fails with -ea -esa, but only on Solaris sparc? Suspect it is timing out
sun/security/tools/keytool/standard.sh generic-all
@@ -1256,6 +1284,13 @@
# jdk_util
+# Fails with assertion error on windows
+# 11 separate stacktraces created... file reuse problem?
+java/util/zip/ZipFile/ReadLongZipFileName.java generic-all
+
+# Recent failure on all platforms
+sun/util/resources/TimeZone/Bug6317929.java generic-all
+
# Fails with -ea -esa on all platforms with Assertion error
java/util/ResourceBundle/Test4300693.java generic-all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/jndi/ldap/InvalidLdapFilters.java Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6916202
+ * @summary More cases of invalid ldap filters accepted and processed
+ * @run main/othervm InvalidLdapFilters valid (cn=Babs)
+ * @run main/othervm InvalidLdapFilters valid (&(cn=Bob))
+ * @run main/othervm InvalidLdapFilters valid (&(objectClass=*)(uid=*))
+ * @run main/othervm InvalidLdapFilters valid (|(cn=Bob))
+ * @run main/othervm InvalidLdapFilters valid (|(objectClass=*)(uid=*))
+ * @run main/othervm InvalidLdapFilters valid (!(cn=Tim))
+ * @run main/othervm InvalidLdapFilters valid (!(!(cn=Tim)))
+ * @run main/othervm InvalidLdapFilters valid (!(&(objectClass=*)(uid=*)))
+ * @run main/othervm InvalidLdapFilters valid (!(|(objectClass=*)(uid=*)))
+ * @run main/othervm InvalidLdapFilters valid (o=univ*of*mich*)
+ * @run main/othervm InvalidLdapFilters valid (seeAlso=)
+ * @run main/othervm InvalidLdapFilters valid (cn:caseExactMatch:=Flintstone)
+ * @run main/othervm InvalidLdapFilters valid (cn:=Betty)
+ * @run main/othervm InvalidLdapFilters valid (sn:dn:2.4.6.8.10:=Barney)
+ * @run main/othervm InvalidLdapFilters valid (o:dn:=Ace)
+ * @run main/othervm InvalidLdapFilters valid (:1.2.3:=Wilma)
+ * @run main/othervm InvalidLdapFilters valid (:DN:2.4.6.8.10:=Dino)
+ * @run main/othervm InvalidLdapFilters valid (1.2.3=abc)
+ * @run main/othervm InvalidLdapFilters valid (cn;lang-de;lang-en=abc)
+ * @run main/othervm InvalidLdapFilters valid (owner=abc)
+ * @run main/othervm InvalidLdapFilters valid (sn;lang-en:dn:2.4.6.8.10:=Barney)
+ * @run main/othervm InvalidLdapFilters valid
+ (&(objectClass=Person)(|(sn=Jensen)(cn=Bab*)))
+ * @run main/othervm InvalidLdapFilters invalid "(&(cn=Robert Dean)))"
+ * @run main/othervm InvalidLdapFilters invalid (&|(cn=Bob))
+ * @run main/othervm InvalidLdapFilters invalid (&&(cn=Bob))
+ * @run main/othervm InvalidLdapFilters invalid (|&(cn=Bob))
+ * @run main/othervm InvalidLdapFilters invalid (||(cn=Bob))
+ * @run main/othervm InvalidLdapFilters invalid (:1.2.:=Wilma)
+ * @run main/othervm InvalidLdapFilters invalid (::DN:2.4.6.8.10:=Dino)
+ * @run main/othervm InvalidLdapFilters invalid (:DN::2.4.6.8.10:=Dino)
+ * @run main/othervm InvalidLdapFilters invalid (:DN:2.4.6.8.10::=Dino)
+ * @run main/othervm InvalidLdapFilters invalid (:DN:2.4.6..8.10:=Dino)
+ * @run main/othervm InvalidLdapFilters invalid (:DN:2.4.6.8.:=Dino)
+ * @run main/othervm InvalidLdapFilters invalid (1.2.;::=abc)
+ * @run main/othervm InvalidLdapFilters invalid (1.2.3;::=abc)
+ * @run main/othervm InvalidLdapFilters invalid (1.2.3;x;=abc)
+ * @run main/othervm InvalidLdapFilters invalid (1.2.3:x::=abc)
+ * @run main/othervm InvalidLdapFilters invalid (1.2.3:x=abc)
+ * @run main/othervm InvalidLdapFilters invalid (sn;:dn:2.4.6.8.10:=Barney)
+ * @run main/othervm InvalidLdapFilters invalid "\"((objectClass=*)&(uid=*))\""
+ * @run main/othervm InvalidLdapFilters invalid "&(objectClass=*)(uid=*)"
+ * @run main/othervm InvalidLdapFilters invalid "(:DN:2.4.6.8.10:cn:=Dino)"
+ * @run main/othervm InvalidLdapFilters invalid "(:DN:2.4.6.8.10:cn=Dino)"
+ * @run main/othervm InvalidLdapFilters invalid
+ "((objectCategory=person)(cn=u)(!(cn=u2*)))"
+ * @run main/othervm InvalidLdapFilters invalid
+ "((&(objectClass=user)(cn=andy*)(cn=steve*)(cn=bob*)))"
+ *
+ * @author Xuelei Fan
+ */
+
+import java.io.*;
+import javax.naming.*;
+import javax.naming.directory.*;
+import java.util.Properties;
+import java.util.Hashtable;
+
+import java.net.Socket;
+import java.net.ServerSocket;
+
+public class InvalidLdapFilters {
+ // Should we run the client or server in a separate thread?
+ //
+ // Both sides can throw exceptions, but do you have a preference
+ // as to which side should be the main thread.
+ static boolean separateServerThread = true;
+
+ // use any free port by default
+ volatile int serverPort = 0;
+
+ // Is the server ready to serve?
+ volatile static boolean serverReady = false;
+
+ // Define the server side of the test.
+ //
+ // If the server prematurely exits, serverReady will be set to true
+ // to avoid infinite hangs.
+ void doServerSide() throws Exception {
+ ServerSocket serverSock = new ServerSocket(serverPort);
+
+ // signal client, it's ready to accecpt connection
+ serverPort = serverSock.getLocalPort();
+ serverReady = true;
+
+ // accept a connection
+ Socket socket = serverSock.accept();
+ System.out.println("Server: Connection accepted");
+
+ InputStream is = socket.getInputStream();
+ OutputStream os = socket.getOutputStream();
+
+ // read the bindRequest
+ while (is.read() != -1) {
+ // ignore
+ is.skip(is.available());
+ break;
+ }
+
+ byte[] bindResponse = {0x30, 0x0C, 0x02, 0x01, 0x01, 0x61, 0x07, 0x0A,
+ 0x01, 0x00, 0x04, 0x00, 0x04, 0x00};
+ // write bindResponse
+ os.write(bindResponse);
+ os.flush();
+
+ // ignore any more request.
+ while (is.read() != -1) {
+ // ignore
+ is.skip(is.available());
+ }
+
+ is.close();
+ os.close();
+ socket.close();
+ serverSock.close();
+ }
+
+ // Define the client side of the test.
+ //
+ // If the server prematurely exits, serverReady will be set to true
+ // to avoid infinite hangs.
+ void doClientSide() throws Exception {
+ // Wait for server to get started.
+ while (!serverReady) {
+ Thread.sleep(50);
+ }
+
+ // set up the environment for creating the initial context
+ Hashtable<Object, Object> env = new Hashtable<Object, Object>();
+ env.put(Context.INITIAL_CONTEXT_FACTORY,
+ "com.sun.jndi.ldap.LdapCtxFactory");
+ env.put(Context.PROVIDER_URL, "ldap://localhost:" + serverPort);
+ env.put("com.sun.jndi.ldap.read.timeout", "1000");
+
+ // env.put(Context.SECURITY_AUTHENTICATION, "simple");
+ // env.put(Context.SECURITY_PRINCIPAL,"cn=root");
+ // env.put(Context.SECURITY_CREDENTIALS,"root");
+
+ // create initial context
+ DirContext context = new InitialDirContext(env);
+
+ // searching
+ SearchControls scs = new SearchControls();
+ scs.setSearchScope(SearchControls.SUBTREE_SCOPE);
+
+ try {
+ NamingEnumeration answer =
+ context.search("o=sun,c=us", searchFilter, scs);
+ } catch (InvalidSearchFilterException isfe) {
+ if (filterIsValid) {
+ // unexpected filter exception.
+ throw new Exception("Unexpected ISFE", isfe);
+ } else {
+ // ignore, it is the expected filter exception.
+ System.out.println("Expected exception: " + isfe.getMessage());
+ }
+ } catch (NamingException ne) {
+ // maybe a read timeout exception, as the server does not response.
+ if (filterIsValid) {
+ System.out.println("Expected exception: " + ne.getMessage());
+ } else {
+ throw new Exception("Not an InvalidSearchFilterException", ne);
+ }
+ }
+
+ context.close();
+ }
+
+ private static boolean filterIsValid;
+ private static String searchFilter;
+
+ private static void parseArguments(String[] args) {
+ System.out.println("arguments length: " + args.length);
+ if (args[0].equals("valid")) {
+ filterIsValid = true;
+ }
+
+ searchFilter = args[1];
+ }
+
+ /*
+ * ============================================================
+ * The remainder is just support stuff
+ */
+
+ // client and server thread
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ // client and server exceptions
+ volatile Exception serverException = null;
+ volatile Exception clientException = null;
+
+ void startServer(boolean newThread) throws Exception {
+ if (newThread) {
+ serverThread = new Thread() {
+ public void run() {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ /*
+ * Our server thread just died.
+ *
+ * Release the client, if not active already...
+ */
+ System.err.println("Server died...");
+ System.err.println(e);
+ serverReady = true;
+ serverException = e;
+ }
+ }
+ };
+ serverThread.start();
+ } else {
+ doServerSide();
+ }
+ }
+
+ void startClient(boolean newThread) throws Exception {
+ if (newThread) {
+ clientThread = new Thread() {
+ public void run() {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ /*
+ * Our client thread just died.
+ */
+ System.err.println("Client died...");
+ clientException = e;
+ }
+ }
+ };
+ clientThread.start();
+ } else {
+ doClientSide();
+ }
+ }
+
+ // Primary constructor, used to drive remainder of the test.
+ InvalidLdapFilters() throws Exception {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ serverThread.join();
+ } else {
+ clientThread.join();
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ *
+ * If the main thread excepted, that propagates back
+ * immediately. If the other thread threw an exception, we
+ * should report back.
+ */
+ if (serverException != null) {
+ System.out.print("Server Exception:");
+ throw serverException;
+ }
+ if (clientException != null) {
+ System.out.print("Client Exception:");
+ throw clientException;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ // parse the customized arguments
+ parseArguments(args);
+
+ // start the test
+ new InvalidLdapFilters();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/AlphaComposite/TestAlphaCompositeForNaN.java Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,22 @@
+/*
+ * @test
+ * @bug 6918065
+ * @summary Test for passing NaN as alpha
+ * should throw IllegalArgumentException
+ */
+
+import java.awt.*;
+
+public class TestAlphaCompositeForNaN {
+ public static void main(String[] args) {
+ try {
+ AlphaComposite a = AlphaComposite.getInstance(AlphaComposite.DST, Float.NaN);
+ System.out.println("Failed");
+ throw new RuntimeException(a + " failed to throw IllegalArgumentException for alpha = " + Float.NaN);
+ }
+ catch (IllegalArgumentException ie) {
+ System.out.println("Passed");
+ System.out.println("Caught " + ie);
+ }
+ }
+}
--- a/jdk/test/java/nio/file/Files/PrintFileTree.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/test/java/nio/file/Files/PrintFileTree.java Wed Mar 17 14:19:07 2010 -0700
@@ -28,27 +28,33 @@
/**
* Invokes Files.walkFileTree to traverse a file tree and prints
- * each of the directories and files. The -L option causes symbolic
- * links to be followed.
+ * each of the directories and files. The -follow option causes symbolic
+ * links to be followed and the -printCycles option will print links
+ * where the target of the link is an ancestor directory.
*/
public class PrintFileTree {
public static void main(String[] args) throws Exception {
boolean followLinks = false;
- Path dir;
-
- if (args[0].equals("-L")) {
- followLinks = true;
- dir = Paths.get(args[1]);
- } else {
- dir = Paths.get(args[0]);
+ boolean printCycles = false;
+ int i = 0;
+ while (i < (args.length-1)) {
+ switch (args[i]) {
+ case "-follow" : followLinks = true; break;
+ case "-printCycles" : printCycles = true; break;
+ default:
+ throw new RuntimeException(args[i] + " not recognized");
+ }
+ i++;
}
+ Path dir = Paths.get(args[i]);
Set<FileVisitOption> options = new HashSet<FileVisitOption>();
if (followLinks)
options.add(FileVisitOption.FOLLOW_LINKS);
+ final boolean reportCycles = printCycles;
Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor<FileRef>() {
public FileVisitResult preVisitDirectory(FileRef dir) {
System.out.println(dir);
@@ -59,7 +65,8 @@
return FileVisitResult.CONTINUE;
}
public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
- System.out.println(file);
+ if (!attrs.isDirectory() || reportCycles)
+ System.out.println(file);
return FileVisitResult.CONTINUE;
}
public FileVisitResult postVisitDirectory(FileRef dir, IOException exc) {
--- a/jdk/test/java/nio/file/Files/walk_file_tree.sh Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/test/java/nio/file/Files/walk_file_tree.sh Wed Mar 17 14:19:07 2010 -0700
@@ -61,12 +61,20 @@
diff out1 out2
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-# repeat test following links (use -follow instead of -L
-# to allow running on older systems)
-$JAVA PrintFileTree -L "$ROOT" > out1
-find "$ROOT" -follow > out2
+# repeat test following links. Some versions of find(1) output
+# cycles (sym links to ancestor directories), other versions do
+# not. For that reason we run PrintFileTree with the -printCycles
+# option when the output without this option differs to find(1).
+find "$ROOT" -follow > out1
+$JAVA PrintFileTree -follow "$ROOT" > out2
diff out1 out2
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+if [ $? != 0 ];
+ then
+ # re-run printing cycles to stdout
+ $JAVA PrintFileTree -follow -printCycles "$ROOT" > out2
+ diff out1 out2
+ if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+ fi
# test SKIP_SIBLINGS
$JAVA SkipSiblings "$ROOT"
--- a/jdk/test/java/nio/file/Path/CheckPermissions.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/test/java/nio/file/Path/CheckPermissions.java Wed Mar 17 14:19:07 2010 -0700
@@ -197,7 +197,7 @@
}
public static void main(String[] args) throws IOException {
- Path dir = Paths.get(System.getProperty("test.src", "."));
+ Path dir = Paths.get(System.getProperty("test.dir", "."));
Path file = dir.resolve("file1234").createFile();
try {
LoggingSecurityManager.install();
--- a/jdk/test/java/nio/file/Path/PathOps.java Wed Mar 17 12:48:21 2010 +0300
+++ b/jdk/test/java/nio/file/Path/PathOps.java Wed Mar 17 14:19:07 2010 -0700
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4313887 6838333
+ * @bug 4313887 6838333 6925932
* @summary Unit test for java.nio.file.Path path operations
*/
@@ -614,17 +614,34 @@
test("/foo")
.ends("foo")
.ends("/foo")
- .notEnds("/");
+ .notEnds("fool");
test("/foo/bar")
.ends("bar")
.ends("foo/bar")
.ends("/foo/bar")
- .notEnds("/bar");
+ .notEnds("ar")
+ .notEnds("barack")
+ .notEnds("/bar")
+ .notEnds("o/bar");
test("foo")
- .ends("foo");
+ .ends("foo")
+ .notEnds("oo")
+ .notEnds("oola");
test("foo/bar")
.ends("bar")
- .ends("foo/bar");
+ .ends("foo/bar")
+ .notEnds("r")
+ .notEnds("barmaid")
+ .notEnds("/bar");
+ test("foo/bar/gus")
+ .ends("gus")
+ .ends("bar/gus")
+ .ends("foo/bar/gus")
+ .notEnds("g")
+ .notEnds("/gus")
+ .notEnds("r/gus")
+ .notEnds("barack/gus")
+ .notEnds("bar/gust");
// elements
test("a/b/c")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/WatchService/LotsOfEvents.java Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 6907760 6929532
+ * @summary Tests WatchService behavior when lots of events are pending
+ * @library ..
+ * @run main/timeout=180 LotsOfEvents
+ */
+
+import java.nio.file.*;
+import static java.nio.file.StandardWatchEventKind.*;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+public class LotsOfEvents {
+
+ static final Random rand = new Random();
+
+ public static void main(String[] args) throws Exception {
+ Path dir = TestUtil.createTemporaryDirectory();
+ try {
+ testOverflowEvent(dir);
+ testModifyEventsQueuing(dir);
+ } finally {
+ TestUtil.removeAll(dir);
+ }
+ }
+
+ /**
+ * Tests that OVERFLOW events are not retreived with other events.
+ */
+ static void testOverflowEvent(Path dir)
+ throws IOException, InterruptedException
+ {
+ WatchService watcher = dir.getFileSystem().newWatchService();
+ try {
+ dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE);
+
+ // create a lot of files
+ int n = 1024;
+ Path[] files = new Path[n];
+ for (int i=0; i<n; i++) {
+ files[i] = dir.resolve("foo" + i).createFile();
+ }
+
+ // give time for events to accumulate (improve chance of overflow)
+ Thread.sleep(1000);
+
+ // check that we see the create events (or overflow)
+ drainAndCheckOverflowEvents(watcher, ENTRY_CREATE, n);
+
+ // delete the files
+ for (int i=0; i<n; i++) {
+ files[i].delete();
+ }
+
+ // give time for events to accumulate (improve chance of overflow)
+ Thread.sleep(1000);
+
+ // check that we see the delete events (or overflow)
+ drainAndCheckOverflowEvents(watcher, ENTRY_DELETE, n);
+ } finally {
+ watcher.close();
+ }
+ }
+
+ static void drainAndCheckOverflowEvents(WatchService watcher,
+ WatchEvent.Kind<?> expectedKind,
+ int count)
+ throws IOException, InterruptedException
+ {
+ // wait for key to be signalled - the timeout is long to allow for
+ // polling implementations
+ WatchKey key = watcher.poll(15, TimeUnit.SECONDS);
+ if (key != null && count == 0)
+ throw new RuntimeException("Key was signalled (unexpected)");
+ if (key == null && count > 0)
+ throw new RuntimeException("Key not signalled (unexpected)");
+
+ int nread = 0;
+ boolean gotOverflow = false;
+ while (key != null) {
+ List<WatchEvent<?>> events = key.pollEvents();
+ for (WatchEvent<?> event: events) {
+ WatchEvent.Kind<?> kind = event.kind();
+ if (kind == expectedKind) {
+ // expected event kind
+ if (++nread > count)
+ throw new RuntimeException("More events than expected!!");
+ } else if (kind == OVERFLOW) {
+ // overflow event should not be retrieved with other events
+ if (events.size() > 1)
+ throw new RuntimeException("Overflow retrieved with other events");
+ gotOverflow = true;
+ } else {
+ throw new RuntimeException("Unexpected event '" + kind + "'");
+ }
+ }
+ if (!key.reset())
+ throw new RuntimeException("Key is no longer valid");
+ key = watcher.poll(2, TimeUnit.SECONDS);
+ }
+
+ // check that all expected events were received or there was an overflow
+ if (nread < count && !gotOverflow)
+ throw new RuntimeException("Insufficient events");
+ }
+
+ /**
+ * Tests that check that ENTRY_MODIFY events are queued efficiently
+ */
+ static void testModifyEventsQueuing(Path dir)
+ throws IOException, InterruptedException
+ {
+ // this test uses a random number of files
+ final int nfiles = 5 + rand.nextInt(10);
+ DirectoryEntry[] entries = new DirectoryEntry[nfiles];
+ for (int i=0; i<nfiles; i++) {
+ entries[i] = new DirectoryEntry(dir.resolve("foo" + i));
+
+ // "some" of the files exist, some do not.
+ entries[i].deleteIfExists();
+ if (rand.nextBoolean())
+ entries[i].create();
+ }
+
+ WatchService watcher = dir.getFileSystem().newWatchService();
+ try {
+ dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
+
+ // do several rounds of noise and test
+ for (int round=0; round<10; round++) {
+
+ // make some noise!!!
+ for (int i=0; i<100; i++) {
+ DirectoryEntry entry = entries[rand.nextInt(nfiles)];
+ int action = rand.nextInt(10);
+ switch (action) {
+ case 0 : entry.create(); break;
+ case 1 : entry.deleteIfExists(); break;
+ default: entry.modifyIfExists();
+ }
+ }
+
+ // process events and ensure that we don't get repeated modify
+ // events for the same file.
+ WatchKey key = watcher.poll(15, TimeUnit.SECONDS);
+ while (key != null) {
+ Set<Path> modified = new HashSet<Path>();
+ for (WatchEvent<?> event: key.pollEvents()) {
+ WatchEvent.Kind<?> kind = event.kind();
+ Path file = (kind == OVERFLOW) ? null : (Path)event.context();
+ if (kind == ENTRY_MODIFY) {
+ boolean added = modified.add(file);
+ if (!added) {
+ throw new RuntimeException(
+ "ENTRY_MODIFY events not queued efficiently");
+ }
+ } else {
+ if (file != null) modified.remove(file);
+ }
+ }
+ if (!key.reset())
+ throw new RuntimeException("Key is no longer valid");
+ key = watcher.poll(2, TimeUnit.SECONDS);
+ }
+ }
+
+ } finally {
+ watcher.close();
+ }
+ }
+
+ static class DirectoryEntry {
+ private final Path file;
+ DirectoryEntry(Path file) {
+ this.file = file;
+ }
+ void create() throws IOException {
+ if (file.notExists())
+ file.createFile();
+
+ }
+ void deleteIfExists() throws IOException {
+ file.deleteIfExists();
+ }
+ void modifyIfExists() throws IOException {
+ if (file.exists()) {
+ OutputStream out = file.newOutputStream(StandardOpenOption.APPEND);
+ try {
+ out.write("message".getBytes());
+ } finally {
+ out.close();
+ }
+ }
+ }
+ }
+
+}
--- a/jdk/test/java/nio/file/WatchService/OverflowEventIsLoner.java Wed Mar 17 12:48:21 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/*
- * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-/* @test
- * @bug 6907760
- * @summary Check that the OVERFLOW event is not retrieved with other events
- * @library ..
- */
-
-import java.nio.file.*;
-import static java.nio.file.StandardWatchEventKind.*;
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-public class OverflowEventIsLoner {
-
- static void drainEvents(WatchService watcher,
- WatchEvent.Kind<?> expectedKind,
- int count)
- throws IOException, InterruptedException
- {
- // wait for key to be signalled - the timeout is long to allow for
- // polling implementations
- WatchKey key = watcher.poll(15, TimeUnit.SECONDS);
- if (key != null && count == 0)
- throw new RuntimeException("Key was signalled (unexpected)");
- if (key == null && count > 0)
- throw new RuntimeException("Key not signalled (unexpected)");
-
- int nread = 0;
- boolean gotOverflow = false;
- do {
- List<WatchEvent<?>> events = key.pollEvents();
- for (WatchEvent<?> event: events) {
- WatchEvent.Kind<?> kind = event.kind();
- if (kind == expectedKind) {
- // expected event kind
- if (++nread > count)
- throw new RuntimeException("More events than expected!!");
- } else if (kind == OVERFLOW) {
- // overflow event should not be retrieved with other events
- if (events.size() > 1)
- throw new RuntimeException("Overflow retrieved with other events");
- gotOverflow = true;
- } else {
- throw new RuntimeException("Unexpected event '" + kind + "'");
- }
- }
- if (!key.reset())
- throw new RuntimeException("Key is no longer valid");
- key = watcher.poll(2, TimeUnit.SECONDS);
- } while (key != null);
-
- // check that all expected events were received or there was an overflow
- if (nread < count && !gotOverflow)
- throw new RuntimeException("Insufficient events");
- }
-
-
- static void test(Path dir) throws IOException, InterruptedException {
- WatchService watcher = dir.getFileSystem().newWatchService();
- try {
- WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE);
-
- // create a lot of files
- int n = 1024;
- Path[] files = new Path[n];
- for (int i=0; i<n; i++) {
- files[i] = dir.resolve("foo" + i).createFile();
- }
-
- // give time for events to accumulate (improve chance of overflow)
- Thread.sleep(1000);
-
- // check that we see the create events (or overflow)
- drainEvents(watcher, ENTRY_CREATE, n);
-
- // delete the files
- for (int i=0; i<n; i++) {
- files[i].delete();
- }
-
- // give time for events to accumulate (improve chance of overflow)
- Thread.sleep(1000);
-
- // check that we see the delete events (or overflow)
- drainEvents(watcher, ENTRY_DELETE, n);
- } finally {
- watcher.close();
- }
- }
-
- public static void main(String[] args) throws Exception {
- Path dir = TestUtil.createTemporaryDirectory();
- try {
- test(dir);
- } finally {
- TestUtil.removeAll(dir);
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/IdentityScope/NoDefaultSystemScope.java Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6921001
+ * @summary The default system identity scope is now null.
+ */
+import java.security.*;
+
+public class NoDefaultSystemScope {
+
+ public static void main(String args[]) throws Exception {
+ IdentityScope s = IdentityScope.getSystemScope();
+
+ if (s != null) {
+ throw new Exception("The default system scope should be null");
+ }
+ System.out.println("TEST PASSED");
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/etype/WeakCrypto.java Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+/*
+ * @test
+ * @bug 6844909
+ * @run main/othervm WeakCrypto
+ * @summary support allow_weak_crypto in krb5.conf
+ */
+
+import java.io.File;
+import sun.security.krb5.internal.crypto.EType;
+import sun.security.krb5.EncryptedData;
+
+public class WeakCrypto {
+ public static void main(String[] args) throws Exception {
+ System.setProperty("java.security.krb5.conf",
+ System.getProperty("test.src", ".") +
+ File.separator +
+ "weakcrypto.conf");
+ int[] etypes = EType.getBuiltInDefaults();
+
+ for (int i=0, length = etypes.length; i<length; i++) {
+ if (etypes[i] == EncryptedData.ETYPE_DES_CBC_CRC ||
+ etypes[i] == EncryptedData.ETYPE_DES_CBC_MD4 ||
+ etypes[i] == EncryptedData.ETYPE_DES_CBC_MD5) {
+ throw new Exception("DES should not appear");
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/etype/weakcrypto.conf Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,2 @@
+[libdefaults]
+allow_weak_crypto = false
--- a/langtools/.hgtags Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/.hgtags Wed Mar 17 14:19:07 2010 -0700
@@ -59,3 +59,4 @@
47003a3622f6a17756ab0338bfa8a43e36549e99 jdk7-b82
c9f4ae1f1480e89aaf7e72173184089d9cea397a jdk7-b83
d9cd5b8286e44f3baf90da290cd295433e21c05a jdk7-b84
+136bfc67946219fb02ee223984540a4a9c5b209f jdk7-b85
--- a/langtools/src/share/classes/com/sun/tools/apt/comp/Apt.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/apt/comp/Apt.java Wed Mar 17 14:19:07 2010 -0700
@@ -457,8 +457,10 @@
throw new UsageMessageNeededException();
try {
- for(AnnotationProcessorFactory apFactory: factoryToAnnotation.keySet()) {
- AnnotationProcessor processor = apFactory.getProcessorFor(factoryToAnnotation.get(apFactory),
+ for(Map.Entry<AnnotationProcessorFactory, Set<AnnotationTypeDeclaration>> entry :
+ factoryToAnnotation.entrySet()) {
+ AnnotationProcessorFactory apFactory = entry.getKey();
+ AnnotationProcessor processor = apFactory.getProcessorFor(entry.getValue(),
trivAPE);
if (processor != null)
processors.add(processor);
--- a/langtools/src/share/classes/com/sun/tools/apt/main/CommandLine.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/apt/main/CommandLine.java Wed Mar 17 14:19:07 2010 -0700
@@ -82,7 +82,7 @@
st.commentChar('#');
st.quoteChar('"');
st.quoteChar('\'');
- while (st.nextToken() != st.TT_EOF) {
+ while (st.nextToken() != StreamTokenizer.TT_EOF) {
args.append(st.sval);
}
r.close();
--- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationProxyMaker.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationProxyMaker.java Wed Mar 17 14:19:07 2010 -0700
@@ -270,7 +270,7 @@
* The toString, hashCode, and equals methods foward to the underlying
* type.
*/
- private static class MirroredTypeExceptionProxy extends ExceptionProxy {
+ private static final class MirroredTypeExceptionProxy extends ExceptionProxy {
private static final long serialVersionUID = 6662035281599933545L;
private MirroredTypeException ex;
@@ -312,7 +312,7 @@
* The toString, hashCode, and equals methods foward to the underlying
* types.
*/
- private static class MirroredTypesExceptionProxy extends ExceptionProxy {
+ private static final class MirroredTypesExceptionProxy extends ExceptionProxy {
private static final long serialVersionUID = -6670822532616693951L;
private MirroredTypesException ex;
--- a/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/DeclarationImpl.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/DeclarationImpl.java Wed Mar 17 14:19:07 2010 -0700
@@ -58,7 +58,7 @@
protected final AptEnv env;
public final Symbol sym;
- protected static DeclarationFilter identityFilter =
+ protected static final DeclarationFilter identityFilter =
new DeclarationFilter();
--- a/langtools/src/share/classes/com/sun/tools/apt/mirror/type/TypeMirrorImpl.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/apt/mirror/type/TypeMirrorImpl.java Wed Mar 17 14:19:07 2010 -0700
@@ -71,6 +71,6 @@
* {@inheritDoc}
*/
public int hashCode() {
- return env.jctypes.hashCode(type);
+ return Types.hashCode(type);
}
}
--- a/langtools/src/share/classes/com/sun/tools/classfile/ConstantPool.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/classfile/ConstantPool.java Wed Mar 17 14:19:07 2010 -0700
@@ -40,7 +40,7 @@
*/
public class ConstantPool {
- public class InvalidIndex extends ConstantPoolException {
+ public static class InvalidIndex extends ConstantPoolException {
private static final long serialVersionUID = -4350294289300939730L;
InvalidIndex(int index) {
super(index);
@@ -53,7 +53,7 @@
}
}
- public class UnexpectedEntry extends ConstantPoolException {
+ public static class UnexpectedEntry extends ConstantPoolException {
private static final long serialVersionUID = 6986335935377933211L;
UnexpectedEntry(int index, int expected_tag, int found_tag) {
super(index);
@@ -71,7 +71,7 @@
public final int found_tag;
}
- public class InvalidEntry extends ConstantPoolException {
+ public static class InvalidEntry extends ConstantPoolException {
private static final long serialVersionUID = 1000087545585204447L;
InvalidEntry(int index, int tag) {
super(index);
@@ -87,7 +87,7 @@
public final int tag;
}
- public class EntryNotFound extends ConstantPoolException {
+ public static class EntryNotFound extends ConstantPoolException {
private static final long serialVersionUID = 2885537606468581850L;
EntryNotFound(Object value) {
super(-1);
@@ -694,7 +694,7 @@
public int byteLength() {
class SizeOutputStream extends OutputStream {
@Override
- public void write(int b) throws IOException {
+ public void write(int b) {
size++;
}
int size;
--- a/langtools/src/share/classes/com/sun/tools/doclets/standard/Standard.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/doclets/standard/Standard.java Wed Mar 17 14:19:07 2010 -0700
@@ -31,23 +31,21 @@
public class Standard {
- public static final HtmlDoclet htmlDoclet = new HtmlDoclet();
-
public static int optionLength(String option) {
- return htmlDoclet.optionLength(option);
+ return HtmlDoclet.optionLength(option);
}
public static boolean start(RootDoc root) {
- return htmlDoclet.start(root);
+ return HtmlDoclet.start(root);
}
public static boolean validOptions(String[][] options,
DocErrorReporter reporter) {
- return htmlDoclet.validOptions(options, reporter);
+ return HtmlDoclet.validOptions(options, reporter);
}
public static LanguageVersion languageVersion() {
- return htmlDoclet.languageVersion();
+ return HtmlDoclet.languageVersion();
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/Launcher.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/Launcher.java Wed Mar 17 14:19:07 2010 -0700
@@ -64,7 +64,7 @@
fileChooser.setSelectedFile(new File(fileName));
}
}
- if (fileChooser.showOpenDialog(null) == fileChooser.APPROVE_OPTION) {
+ if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
String fileName = fileChooser.getSelectedFile().getPath();
prefs.put("recent.file", fileName);
javac.run(System.in, null, null, "-d", "/tmp", fileName);
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTool.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTool.java Wed Mar 17 14:19:07 2010 -0700
@@ -137,7 +137,7 @@
}
private static boolean match(OptionKind clientKind, OptionKind optionKind) {
- return (clientKind == (optionKind == OptionKind.HIDDEN ? optionKind.EXTENDED : optionKind));
+ return (clientKind == (optionKind == OptionKind.HIDDEN ? OptionKind.EXTENDED : optionKind));
}
public JavacFileManager getStandardFileManager(
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Wed Mar 17 14:19:07 2010 -0700
@@ -198,7 +198,12 @@
/**
* Warn about Sun proprietary API that may be removed in a future release.
*/
- SUNAPI("sunapi", true);
+ SUNAPI("sunapi", true),
+
+ /**
+ * Warn about issues relating to use of statics
+ */
+ STATIC("static");
LintCategory(String option) {
this(option, false);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Wed Mar 17 14:19:07 2010 -0700
@@ -162,7 +162,7 @@
* the default package; otherwise, the owner symbol is returned
*/
public Symbol location() {
- if (owner.name == null || (owner.name.isEmpty() && owner.kind != PCK)) {
+ if (owner.name == null || (owner.name.isEmpty() && owner.kind != PCK && owner.kind != TYP)) {
return null;
}
return owner;
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Wed Mar 17 14:19:07 2010 -0700
@@ -2504,7 +2504,7 @@
}
@Override
public int hashCode() {
- return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2);
+ return 127 * Types.hashCode(t1) + Types.hashCode(t2);
}
@Override
public boolean equals(Object obj) {
@@ -3375,7 +3375,7 @@
this.t = t;
}
public int hashCode() {
- return Types.this.hashCode(t);
+ return Types.hashCode(t);
}
public boolean equals(Object obj) {
return (obj instanceof SingletonType) &&
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Mar 17 14:19:07 2010 -0700
@@ -2020,6 +2020,10 @@
tree.pos(), site, sym.name, true);
}
}
+ } else if (sym.kind != ERR && (sym.flags() & STATIC) != 0 && sym.name != names._class) {
+ // If the qualified item is not a type and the selected item is static, report
+ // a warning. Make allowance for the class of an array type e.g. Object[].class)
+ chk.warnStatic(tree, "static.not.qualified.by.type", Kinds.kindName(sym.kind), sym.owner);
}
// If we are selecting an instance member via a `super', ...
@@ -2636,6 +2640,7 @@
if (tree.bounds.tail.nonEmpty()) {
log.error(tree.bounds.tail.head.pos(),
"type.var.may.not.be.followed.by.other.bounds");
+ log.unrecoverableError = true;
tree.bounds = List.of(tree.bounds.head);
a.bound = bs.head;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Mar 17 14:19:07 2010 -0700
@@ -189,6 +189,11 @@
sunApiHandler.report(pos, msg, args);
}
+ public void warnStatic(DiagnosticPosition pos, String msg, Object... args) {
+ if (lint.isEnabled(LintCategory.STATIC))
+ log.warning(pos, msg, args);
+ }
+
/**
* Report any deferred diagnostics.
*/
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Wed Mar 17 14:19:07 2010 -0700
@@ -270,6 +270,7 @@
return ts.toList();
}
+ @Override
public void visitTopLevel(JCCompilationUnit tree) {
JavaFileObject prev = log.useSource(tree.sourcefile);
boolean addEnv = false;
@@ -289,13 +290,13 @@
tree.packge = syms.unnamedPackage;
}
tree.packge.complete(); // Find all classes in package.
- Env<AttrContext> env = topLevelEnv(tree);
+ Env<AttrContext> topEnv = topLevelEnv(tree);
// Save environment of package-info.java file.
if (isPkgInfo) {
Env<AttrContext> env0 = typeEnvs.get(tree.packge);
if (env0 == null) {
- typeEnvs.put(tree.packge, env);
+ typeEnvs.put(tree.packge, topEnv);
} else {
JCCompilationUnit tree0 = env0.toplevel;
if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {
@@ -306,7 +307,7 @@
if (addEnv || (tree0.packageAnnotations.isEmpty() &&
tree.docComments != null &&
tree.docComments.get(tree) != null)) {
- typeEnvs.put(tree.packge, env);
+ typeEnvs.put(tree.packge, topEnv);
}
}
}
@@ -322,14 +323,15 @@
c.members_field = new Scope(c);
tree.packge.package_info = c;
}
- classEnter(tree.defs, env);
+ classEnter(tree.defs, topEnv);
if (addEnv) {
- todo.append(env);
+ todo.append(topEnv);
}
log.useSource(prev);
result = null;
}
+ @Override
public void visitClassDef(JCClassDecl tree) {
Symbol owner = env.info.scope.owner;
Scope enclScope = enterScope(env);
@@ -435,6 +437,7 @@
* Enter a symbol for type parameter in local scope, after checking that it
* is unique.
*/
+ @Override
public void visitTypeParameter(JCTypeParameter tree) {
TypeVar a = (tree.type != null)
? (TypeVar)tree.type
@@ -448,6 +451,7 @@
/** Default class enter visitor method: do nothing.
*/
+ @Override
public void visitTree(JCTree tree) {
result = null;
}
@@ -489,10 +493,8 @@
for (JCCompilationUnit tree : trees) {
if (tree.starImportScope.elems == null) {
JavaFileObject prev = log.useSource(tree.sourcefile);
- Env<AttrContext> env = typeEnvs.get(tree);
- if (env == null)
- env = topLevelEnv(tree);
- memberEnter.memberEnter(tree, env);
+ Env<AttrContext> topEnv = topLevelEnv(tree);
+ memberEnter.memberEnter(tree, topEnv);
log.useSource(prev);
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Wed Mar 17 14:19:07 2010 -0700
@@ -607,10 +607,12 @@
public void visitNewArray(JCNewArray tree) {
tree.elemtype = translate(tree.elemtype, null);
translate(tree.dims, syms.intType);
- tree.elems = translate(tree.elems,
- (tree.type == null) ? null
- : erasure(types.elemtype(tree.type)));
- tree.type = erasure(tree.type);
+ if (tree.type != null) {
+ tree.elems = translate(tree.elems, erasure(types.elemtype(tree.type)));
+ tree.type = erasure(tree.type);
+ } else {
+ tree.elems = translate(tree.elems, null);
+ }
result = tree;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Wed Mar 17 14:19:07 2010 -0700
@@ -260,7 +260,7 @@
archive = openArchive(directory);
} catch (IOException ex) {
log.error("error.reading.file",
- directory, ex.getLocalizedMessage());
+ directory, getMessage(ex));
return;
}
}
@@ -489,7 +489,7 @@
archive = new MissingArchive(zipFileName);
} catch (IOException ex) {
if (zipFileName.exists())
- log.error("error.reading.file", zipFileName, ex.getLocalizedMessage());
+ log.error("error.reading.file", zipFileName, getMessage(ex));
archive = new MissingArchive(zipFileName);
}
@@ -838,4 +838,23 @@
}
throw new IllegalArgumentException("Invalid relative path: " + file);
}
+
+ /**
+ * Get a detail message from an IOException.
+ * Most, but not all, instances of IOException provide a non-null result
+ * for getLocalizedMessage(). But some instances return null: in these
+ * cases, fallover to getMessage(), and if even that is null, return the
+ * name of the exception itself.
+ * @param e an IOException
+ * @return a string to include in a compiler diagnostic
+ */
+ public static String getMessage(IOException e) {
+ String s = e.getLocalizedMessage();
+ if (s != null)
+ return s;
+ s = e.getMessage();
+ if (s != null)
+ return s;
+ return e.toString();
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/javac/file/Paths.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/Paths.java Wed Mar 17 14:19:07 2010 -0700
@@ -320,7 +320,7 @@
addFile(f, warn);
}
} catch (IOException e) {
- log.error("error.reading.file", jarFile, e.getLocalizedMessage());
+ log.error("error.reading.file", jarFile, JavacFileManager.getMessage(e));
}
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Mar 17 14:19:07 2010 -0700
@@ -1135,7 +1135,7 @@
self.name = simpleBinaryName(self.flatname, c.flatname) ;
self.owner = m != null ? m : c;
if (self.name.isEmpty())
- self.fullname = null;
+ self.fullname = names.empty;
else
self.fullname = ClassSymbol.formFullName(self.name, self.owner);
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Wed Mar 17 14:19:07 2010 -0700
@@ -808,8 +808,8 @@
code.resolve(secondJumps);
CondItem second = genCond(tree.falsepart, CRT_FLOW_TARGET);
CondItem result = items.makeCondItem(second.opcode,
- code.mergeChains(trueJumps, second.trueJumps),
- code.mergeChains(falseJumps, second.falseJumps));
+ Code.mergeChains(trueJumps, second.trueJumps),
+ Code.mergeChains(falseJumps, second.falseJumps));
if (markBranches) result.tree = tree.falsepart;
return result;
} else {
@@ -1322,7 +1322,7 @@
if (useJsrLocally) {
if (tree.finalizer != null) {
Code.State jsrState = code.state.dup();
- jsrState.push(code.jsrReturnValue);
+ jsrState.push(Code.jsrReturnValue);
tryEnv.info.cont =
new Chain(code.emitJump(jsr),
tryEnv.info.cont,
@@ -1375,7 +1375,7 @@
genFinalizer(env);
if (hasFinalizer || l.tail.nonEmpty()) {
code.statBegin(TreeInfo.endPos(env.tree));
- exitChain = code.mergeChains(exitChain,
+ exitChain = Code.mergeChains(exitChain,
code.branch(goto_));
}
endFinalizerGap(env);
@@ -1963,7 +1963,7 @@
result = items.
makeCondItem(rcond.opcode,
rcond.trueJumps,
- code.mergeChains(falseJumps,
+ Code.mergeChains(falseJumps,
rcond.falseJumps));
} else {
result = lcond;
@@ -1976,7 +1976,7 @@
CondItem rcond = genCond(tree.rhs, CRT_FLOW_TARGET);
result = items.
makeCondItem(rcond.opcode,
- code.mergeChains(trueJumps, rcond.trueJumps),
+ Code.mergeChains(trueJumps, rcond.trueJumps),
rcond.falseJumps);
} else {
result = lcond;
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java Wed Mar 17 14:19:07 2010 -0700
@@ -792,25 +792,25 @@
}
Chain jumpTrue() {
- if (tree == null) return code.mergeChains(trueJumps, code.branch(opcode));
+ if (tree == null) return Code.mergeChains(trueJumps, code.branch(opcode));
// we should proceed further in -Xjcov mode only
int startpc = code.curPc();
- Chain c = code.mergeChains(trueJumps, code.branch(opcode));
+ Chain c = Code.mergeChains(trueJumps, code.branch(opcode));
code.crt.put(tree, CRTable.CRT_BRANCH_TRUE, startpc, code.curPc());
return c;
}
Chain jumpFalse() {
- if (tree == null) return code.mergeChains(falseJumps, code.branch(code.negate(opcode)));
+ if (tree == null) return Code.mergeChains(falseJumps, code.branch(Code.negate(opcode)));
// we should proceed further in -Xjcov mode only
int startpc = code.curPc();
- Chain c = code.mergeChains(falseJumps, code.branch(code.negate(opcode)));
+ Chain c = Code.mergeChains(falseJumps, code.branch(Code.negate(opcode)));
code.crt.put(tree, CRTable.CRT_BRANCH_FALSE, startpc, code.curPc());
return c;
}
CondItem negate() {
- CondItem c = new CondItem(code.negate(opcode), falseJumps, trueJumps);
+ CondItem c = new CondItem(Code.negate(opcode), falseJumps, trueJumps);
c.tree = tree;
return c;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/main/CommandLine.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/CommandLine.java Wed Mar 17 14:19:07 2010 -0700
@@ -82,7 +82,7 @@
st.commentChar('#');
st.quoteChar('"');
st.quoteChar('\'');
- while (st.nextToken() != st.TT_EOF) {
+ while (st.nextToken() != StreamTokenizer.TT_EOF) {
args.append(st.sval);
}
r.close();
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Mar 17 14:19:07 2010 -0700
@@ -549,12 +549,6 @@
return log.nwarnings;
}
- /** Whether or not any parse errors have occurred.
- */
- public boolean parseErrors() {
- return parseErrors;
- }
-
/** Try to open input stream with given name.
* Report an error if this fails.
* @param filename The file name of the input stream to be opened.
@@ -564,7 +558,7 @@
inputFiles.add(filename);
return filename.getCharContent(false);
} catch (IOException e) {
- log.error("error.reading.file", filename, e.getLocalizedMessage());
+ log.error("error.reading.file", filename, JavacFileManager.getMessage(e));
return null;
}
}
@@ -588,7 +582,7 @@
int initialErrorCount = log.nerrors;
Parser parser = parserFactory.newParser(content, keepComments(), genEndPos, lineDebugInfo);
tree = parser.parseCompilationUnit();
- parseErrors |= (log.nerrors > initialErrorCount);
+ log.unrecoverableError |= (log.nerrors > initialErrorCount);
if (verbose) {
printVerbose("parsing.done", Long.toString(elapsed(msec)));
}
@@ -723,7 +717,7 @@
try {
tree = parse(filename, filename.getCharContent(false));
} catch (IOException e) {
- log.error("error.reading.file", filename, e);
+ log.error("error.reading.file", filename, JavacFileManager.getMessage(e));
tree = make.TopLevel(List.<JCTree.JCAnnotation>nil(), null, List.<JCTree>nil());
} finally {
log.useSource(prev);
@@ -768,9 +762,6 @@
private long start_msec = 0;
public long elapsed_msec = 0;
- /** Track whether any errors occurred while parsing source text. */
- private boolean parseErrors = false;
-
public void compile(List<JavaFileObject> sourceFileObject)
throws Throwable {
compile(sourceFileObject, List.<String>nil(), null);
@@ -1114,7 +1105,7 @@
return env;
if (verboseCompilePolicy)
- log.printLines(log.noticeWriter, "[attribute " + env.enclClass.sym + "]");
+ Log.printLines(log.noticeWriter, "[attribute " + env.enclClass.sym + "]");
if (verbose)
printVerbose("checking.attribution", env.enclClass.sym);
--- a/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Wed Mar 17 14:19:07 2010 -0700
@@ -26,6 +26,8 @@
package com.sun.tools.javac.model;
import com.sun.tools.javac.util.*;
+import java.io.ObjectInputStream;
+import java.io.IOException;
import java.lang.annotation.*;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
@@ -268,10 +270,10 @@
* The toString, hashCode, and equals methods foward to the underlying
* type.
*/
- private static class MirroredTypeExceptionProxy extends ExceptionProxy {
+ private static final class MirroredTypeExceptionProxy extends ExceptionProxy {
static final long serialVersionUID = 269;
- private transient final TypeMirror type;
+ private transient TypeMirror type;
private final String typeString;
MirroredTypeExceptionProxy(TypeMirror t) {
@@ -296,6 +298,13 @@
protected RuntimeException generateException() {
return new MirroredTypeException(type);
}
+
+ // Explicitly set all transient fields.
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ s.defaultReadObject();
+ type = null;
+ }
}
@@ -304,10 +313,10 @@
* The toString, hashCode, and equals methods foward to the underlying
* types.
*/
- private static class MirroredTypesExceptionProxy extends ExceptionProxy {
+ private static final class MirroredTypesExceptionProxy extends ExceptionProxy {
static final long serialVersionUID = 269;
- private transient final List<TypeMirror> types;
+ private transient List<TypeMirror> types;
private final String typeStrings;
MirroredTypesExceptionProxy(List<TypeMirror> ts) {
@@ -333,5 +342,12 @@
protected RuntimeException generateException() {
return new MirroredTypesException(types);
}
+
+ // Explicitly set all transient fields.
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ s.defaultReadObject();
+ types = null;
+ }
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Mar 17 14:19:07 2010 -0700
@@ -1561,7 +1561,10 @@
JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
if (newClass.def != null) {
assert newClass.def.mods.annotations.isEmpty();
- newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
+ if (newAnnotations.nonEmpty()) {
+ newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos);
+ newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
+ }
}
return newClass;
} else {
@@ -3016,6 +3019,18 @@
return (oc >= 0) ? TreeInfo.opPrec(oc) : -1;
}
+ /**
+ * Return the lesser of two positions, making allowance for either one
+ * being unset.
+ */
+ static int earlier(int pos1, int pos2) {
+ if (pos1 == Position.NOPOS)
+ return pos2;
+ if (pos2 == Position.NOPOS)
+ return pos1;
+ return (pos1 < pos2 ? pos1 : pos2);
+ }
+
/** Return operation tag of binary operator represented by token,
* -1 if token is not a binary operator.
*/
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Wed Mar 17 14:19:07 2010 -0700
@@ -690,10 +690,12 @@
ProcessorState ps = psi.next();
Set<String> matchedNames = new HashSet<String>();
Set<TypeElement> typeElements = new LinkedHashSet<TypeElement>();
- for (String unmatchedAnnotationName : unmatchedAnnotations.keySet()) {
+
+ for (Map.Entry<String, TypeElement> entry: unmatchedAnnotations.entrySet()) {
+ String unmatchedAnnotationName = entry.getKey();
if (ps.annotationSupported(unmatchedAnnotationName) ) {
matchedNames.add(unmatchedAnnotationName);
- TypeElement te = unmatchedAnnotations.get(unmatchedAnnotationName);
+ TypeElement te = entry.getValue();
if (te != null)
typeElements.add(te);
}
@@ -790,16 +792,13 @@
List<JCCompilationUnit> roots,
List<ClassSymbol> classSymbols,
Iterable<? extends PackageSymbol> pckSymbols)
- throws IOException {
+ throws IOException {
log = Log.instance(context);
// Writer for -XprintRounds and -XprintProcessorInfo data
PrintWriter xout = context.get(Log.outKey);
TaskListener taskListener = context.get(TaskListener.class);
-
- AnnotationCollector collector = new AnnotationCollector();
-
JavaCompiler compiler = JavaCompiler.instance(context);
compiler.todo.clear(); // free the compiler's resources
@@ -878,7 +877,7 @@
roots = cleanTrees(roots).appendList(parsedFiles);
// Check for errors after parsing
- if (compiler.parseErrors()) {
+ if (log.unrecoverableError) {
errorStatus = true;
break runAround;
} else {
@@ -912,7 +911,7 @@
roots = runLastRound(xout, roundNumber, errorStatus, compiler, roots, taskListener);
// Set error status for any files compiled and generated in
// the last round
- if (compiler.parseErrors())
+ if (log.unrecoverableError)
errorStatus = true;
compiler.close(false);
@@ -1218,45 +1217,6 @@
return false;
}
- private class AnnotationCollector extends TreeScanner {
- List<JCTree> path = List.nil();
- static final boolean verbose = false;
- List<JCAnnotation> annotations = List.nil();
-
- public List<JCAnnotation> findAnnotations(List<? extends JCTree> nodes) {
- annotations = List.nil();
- scan(nodes);
- List<JCAnnotation> found = annotations;
- annotations = List.nil();
- return found.reverse();
- }
-
- public void scan(JCTree node) {
- if (node == null)
- return;
- Symbol sym = TreeInfo.symbolFor(node);
- if (sym != null)
- path = path.prepend(node);
- super.scan(node);
- if (sym != null)
- path = path.tail;
- }
-
- public void visitAnnotation(JCAnnotation node) {
- annotations = annotations.prepend(node);
- if (verbose) {
- StringBuilder sb = new StringBuilder();
- for (JCTree tree : path.reverse()) {
- System.err.print(sb);
- System.err.println(TreeInfo.symbolFor(tree));
- sb.append(" ");
- }
- System.err.print(sb);
- System.err.println(node);
- }
- }
- }
-
private static <T extends JCTree> List<T> cleanTrees(List<T> nodes) {
for (T node : nodes)
treeCleaner.scan(node);
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Mar 17 14:19:07 2010 -0700
@@ -720,6 +720,9 @@
{0}: major version {1} is newer than {2}, the highest major version supported by this compiler.\n\
It is recommended that the compiler be upgraded.
+compiler.warn.static.not.qualified.by.type=\
+ [static] static {0} should be qualified by type name, {1}, instead of by an expression
+
# Warnings related to annotation processing
compiler.warn.proc.package.does.not.exist=\
package {0} does not exist
--- a/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java Wed Mar 17 14:19:07 2010 -0700
@@ -201,7 +201,7 @@
private String selectFormat(JCDiagnostic d) {
DiagnosticSource source = d.getDiagnosticSource();
String format = getConfiguration().getFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT);
- if (source != null) {
+ if (source != null && source != DiagnosticSource.NO_SOURCE) {
if (d.getIntPosition() != Position.NOPOS) {
format = getConfiguration().getFormat(BasicFormatKind.DEFAULT_POS_FORMAT);
} else if (source.getFile() != null &&
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Wed Mar 17 14:19:07 2010 -0700
@@ -192,6 +192,12 @@
*/
public int nwarnings = 0;
+ /**
+ * Whether or not an unrecoverable error has been seen.
+ * Unrecoverable errors prevent subsequent annotation processing.
+ */
+ public boolean unrecoverableError;
+
/** A set of all errors generated so far. This is used to avoid printing an
* error message more than once. For each error, a pair consisting of the
* source file name and source code position of the error is added to the set.
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Wed Mar 17 14:19:07 2010 -0700
@@ -34,7 +34,6 @@
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.ClassType;
-import com.sun.tools.javac.comp.Attr;
import com.sun.tools.javac.comp.Check;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.Context;
@@ -73,10 +72,6 @@
/** Referenced directly in RootDocImpl. */
JavadocClassReader reader;
- /** The compiler's attribution phase (needed to evaluate
- * constant initializers). */
- Attr attr;
-
/** Javadoc's own version of the compiler's enter phase. */
JavadocEnter enter;
@@ -91,8 +86,6 @@
/** Access filter (public, protected, ...). */
ModifierFilter showAccess;
- private ClassDocImpl runtimeException;
-
/** True if we are using a sentence BreakIterator. */
boolean breakiterator;
@@ -129,7 +122,6 @@
syms = Symtab.instance(context);
reader = JavadocClassReader.instance0(context);
enter = JavadocEnter.instance0(context);
- attr = Attr.instance(context);
names = Names.instance(context);
externalizableSym = reader.enterClass(names.fromString("java.io.Externalizable"));
chk = Check.instance(context);
--- a/langtools/src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java Wed Mar 17 14:19:07 2010 -0700
@@ -349,12 +349,12 @@
// (int i, String s) ==> [0] = "int", [1] = String
// (int[][], String[]) ==> [0] = "int[][]" // [1] = "String[]"
class ParameterParseMachine {
- final int START = 0;
- final int TYPE = 1;
- final int NAME = 2;
- final int TNSPACE = 3; // space between type and name
- final int ARRAYDECORATION = 4;
- final int ARRAYSPACE = 5;
+ static final int START = 0;
+ static final int TYPE = 1;
+ static final int NAME = 2;
+ static final int TNSPACE = 3; // space between type and name
+ static final int ARRAYDECORATION = 4;
+ static final int ARRAYSPACE = 5;
String parameters;
--- a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java Wed Mar 17 14:19:07 2010 -0700
@@ -255,9 +255,11 @@
}
this.classes = new ArrayList<String>();
- for (String classname: classes) {
- classname.getClass(); // null-check
- this.classes.add(classname);
+ if (classes != null) {
+ for (String classname: classes) {
+ classname.getClass(); // null-check
+ this.classes.add(classname);
+ }
}
}
@@ -316,6 +318,12 @@
int run(String[] args) {
try {
handleOptions(args);
+ if (classes == null || classes.size() == 0) {
+ if (help || version || fullVersion)
+ return 0;
+ else
+ return 1;
+ }
boolean ok = run();
return ok ? 0 : 1;
} catch (BadArgs e) {
@@ -347,8 +355,7 @@
fileManager = getDefaultFileManager(diagnosticListener, log);
Iterator<String> iter = args.iterator();
- if (!iter.hasNext())
- help = true;
+ boolean noArgs = !iter.hasNext();
while (iter.hasNext()) {
String arg = iter.next();
@@ -365,7 +372,7 @@
}
if ((classes == null || classes.size() == 0) &&
- !(help || version || fullVersion)) {
+ !(noArgs || help || version || fullVersion)) {
throw new BadArgs("err.no.classes.specified");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/4880220/T4880220.error.out Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,9 @@
+T4880220.java:20:27: compiler.warn.static.not.qualified.by.type: kindname.method, T4880220.C
+T4880220.java:21:27: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
+T4880220.java:22:27: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
+T4880220.java:24:29: compiler.warn.static.not.qualified.by.type: kindname.method, T4880220.C
+T4880220.java:25:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
+T4880220.java:26:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
+- compiler.err.warnings.and.werror
+1 error
+6 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/4880220/T4880220.java Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,43 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 4880220
+ * @summary Add a warning when accessing a static method via an reference
+ *
+ * @compile/ref=T4880220.empty.out T4880220.java
+ * @compile/ref=T4880220.warn.out -XDrawDiagnostics -Xlint:static T4880220.java
+ * @compile/ref=T4880220.warn.out -XDrawDiagnostics -Xlint:all T4880220.java
+ * @compile/ref=T4880220.empty.out -XDrawDiagnostics -Xlint:all,-static T4880220.java
+ * @compile/ref=T4880220.error.out/fail -XDrawDiagnostics -Werror -Xlint:all T4880220.java
+ */
+
+public class T4880220 {
+ void m1() {
+ int good_1 = C.m();
+ int good_2 = C.f;
+ int good_3 = C.x;
+
+ C c = new C();
+ int bad_inst_1 = c.m();
+ int bad_inst_2 = c.f;
+ int bad_inst_3 = c.x;
+
+ int bad_expr_1 = c().m();
+ int bad_expr_2 = c().f;
+ int bad_expr_3 = c().x;
+ }
+
+ void m2() {
+ Class<?> good_1 = C.class;
+ Class<?> good_2 = C[].class;
+ }
+
+ C c() {
+ return new C();
+ }
+
+ static class C {
+ static int m() { return 0; }
+ static int f;
+ static final int x = 3;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/4880220/T4880220.warn.out Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,7 @@
+T4880220.java:20:27: compiler.warn.static.not.qualified.by.type: kindname.method, T4880220.C
+T4880220.java:21:27: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
+T4880220.java:22:27: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
+T4880220.java:24:29: compiler.warn.static.not.qualified.by.type: kindname.method, T4880220.C
+T4880220.java:25:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
+T4880220.java:26:29: compiler.warn.static.not.qualified.by.type: kindname.variable, T4880220.C
+6 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T6881645.java Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Unchecked method call on a method declared inside anonymous inner causes javac to crash
+ * @compile -Xlint:unchecked T6881645.java
+ */
+
+class T6881645 {
+ Object o = new Object() {
+ <Z> void m (Class<Z> x) {}
+ void test() {
+ m((Class)null);
+ }
+ };
+}
+
--- a/langtools/test/tools/javac/ThrowsIntersection_1.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/ThrowsIntersection_1.java Wed Mar 17 14:19:07 2010 -0700
@@ -30,6 +30,8 @@
* @compile ThrowsIntersection_1.java
*/
+package ThrowsIntersection_1;
+
class Ex1 extends Exception {}
class Ex2 extends Exception {}
--- a/langtools/test/tools/javac/ThrowsIntersection_2.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/ThrowsIntersection_2.java Wed Mar 17 14:19:07 2010 -0700
@@ -30,6 +30,8 @@
* @compile ThrowsIntersection_2.java
*/
+package ThrowsIntersection_2;
+
class Ex1 extends Exception {}
class Ex2 extends Exception {}
class Ex3 extends Exception {}
--- a/langtools/test/tools/javac/ThrowsIntersection_3.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/ThrowsIntersection_3.java Wed Mar 17 14:19:07 2010 -0700
@@ -30,6 +30,8 @@
* @run compile/fail ThrowsIntersection_3.java
*/
+package ThrowsIntersection_3;
+
class Ex1 extends Exception {}
class Ex2 extends Exception {}
--- a/langtools/test/tools/javac/ThrowsIntersection_4.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/ThrowsIntersection_4.java Wed Mar 17 14:19:07 2010 -0700
@@ -30,6 +30,8 @@
* @run compile/fail ThrowsIntersection_4.java
*/
+package ThrowsIntersection_4;
+
// Note: This is the test that actually failed for 4042259. The others are for completeness.
class Ex1 extends Exception {}
--- a/langtools/test/tools/javac/annotations/neg/Constant.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/annotations/neg/Constant.java Wed Mar 17 14:19:07 2010 -0700
@@ -30,7 +30,7 @@
* @compile/fail Constant.java
*/
-package test.tools.javac.annotation.Constant;
+package Constant;
@T(a = X.x)
@interface T {
--- a/langtools/test/tools/javac/api/TestJavacTaskScanner.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/api/TestJavacTaskScanner.java Wed Mar 17 14:19:07 2010 -0700
@@ -34,7 +34,10 @@
import com.sun.tools.javac.parser.*; // XXX
import com.sun.tools.javac.util.*; // XXX
import java.io.*;
+import java.net.*;
import java.nio.*;
+import java.nio.charset.Charset;
+import java.util.Arrays;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
@@ -43,6 +46,10 @@
import javax.lang.model.util.Types;
import javax.tools.*;
+import static javax.tools.StandardLocation.CLASS_PATH;
+import static javax.tools.StandardLocation.SOURCE_PATH;
+import static javax.tools.StandardLocation.CLASS_OUTPUT;
+
public class TestJavacTaskScanner extends ToolTester {
final JavacTaskImpl task;
@@ -56,6 +63,7 @@
TestJavacTaskScanner(File file) {
final Iterable<? extends JavaFileObject> compilationUnits =
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,
new MyScanner.Factory(task.getContext(), this));
@@ -83,7 +91,7 @@
System.out.println("#parseTypeElements: " + numParseTypeElements);
System.out.println("#allMembers: " + numAllMembers);
- check(numTokens, "#Tokens", 891);
+ check(numTokens, "#Tokens", 1222);
check(numParseTypeElements, "#parseTypeElements", 136);
check(numAllMembers, "#allMembers", 67);
}
@@ -117,6 +125,47 @@
numAllMembers++;
}
}
+
+ /* Similar to ToolTester.getFileManager, except that this version also ensures
+ * javac classes will be available on the classpath. The javac classes are assumed
+ * to be on the classpath used to run this test (this is true when using jtreg).
+ * The classes are found by obtaining the URL for a sample javac class, using
+ * getClassLoader().getResource(), and then deconstructing the URL to find the
+ * underlying directory or jar file to place on the classpath.
+ */
+ public StandardJavaFileManager getLocalFileManager(JavaCompiler tool,
+ DiagnosticListener<JavaFileObject> dl,
+ Charset encoding) {
+ File javac_classes;
+ try {
+ final String javacMainClass = "com/sun/tools/javac/Main.class";
+ URL url = getClass().getClassLoader().getResource(javacMainClass);
+ if (url == null)
+ throw new Error("can't locate javac classes");
+ URI uri = url.toURI();
+ String scheme = uri.getScheme();
+ String ssp = uri.getSchemeSpecificPart();
+ if (scheme.equals("jar")) {
+ javac_classes = new File(new URI(ssp.substring(0, ssp.indexOf("!/"))));
+ } else if (scheme.equals("file")) {
+ javac_classes = new File(ssp.substring(0, ssp.indexOf(javacMainClass)));
+ } else
+ throw new Error("unknown URL: " + url);
+ } catch (URISyntaxException e) {
+ throw new Error(e);
+ }
+ System.err.println("javac_classes: " + javac_classes);
+
+ StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, encoding);
+ try {
+ fm.setLocation(SOURCE_PATH, Arrays.asList(test_src));
+ fm.setLocation(CLASS_PATH, Arrays.asList(test_classes, javac_classes));
+ fm.setLocation(CLASS_OUTPUT, Arrays.asList(test_classes));
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ return fm;
+ }
}
class MyScanner extends Scanner {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/api/TestResolveError.java Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6930108
+ * @summary IllegalArgumentException in AbstractDiagnosticFormatter for tools/javac/api/TestJavacTaskScanner.java
+ * @library ./lib
+ * @build ToolTester
+ * @run main TestResolveError
+ */
+
+import java.io.*;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.tools.*;
+
+import com.sun.tools.javac.api.JavacTaskImpl;
+
+/*
+ * This is a cut down version of TestJavacTaskScanner, which as originally written
+ * caused an IllegalArgumentException in AbstractDiagnosticFormatter as a result
+ * of calling task.parseType with a name whose resolution depended on the setting
+ * of the bootclasspath.
+ * This test has the same call, task.parseType("List<String>", clazz), but checks
+ * that the error is handled in a reasonable way by javac.
+ */
+public class TestResolveError extends ToolTester {
+ public static void main(String... args) throws Exception {
+ new TestResolveError().run();
+ }
+
+ void run() throws Exception {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ File file = new File(test_src, "TestResolveError.java");
+ final Iterable<? extends JavaFileObject> compilationUnits =
+ fm.getJavaFileObjects(new File[] {file});
+ task = (JavacTaskImpl)tool.getTask(pw, fm, null, null, null, compilationUnits);
+ elements = task.getElements();
+ types = task.getTypes();
+
+ Iterable<? extends TypeElement> toplevels;
+ try {
+ toplevels = task.enter(task.parse());
+ } catch (IOException ex) {
+ throw new AssertionError(ex);
+ }
+
+ for (TypeElement clazz : toplevels) {
+ System.out.format("Testing %s:%n%n", clazz.getSimpleName());
+ // this should not cause any exception from the compiler,
+ // such as IllegalArgumentException
+ testParseType(clazz);
+ }
+
+ pw.close();
+
+ String out = sw.toString();
+ System.out.println(out);
+
+ if (out.contains("com.sun.tools.javac.util"))
+ throw new Exception("Unexpected output from compiler");
+ }
+
+ void testParseType(TypeElement clazz) {
+ DeclaredType type = (DeclaredType)task.parseType("List<String>", clazz);
+ for (Element member : elements.getAllMembers((TypeElement)type.asElement())) {
+ TypeMirror mt = types.asMemberOf(type, member);
+ System.out.format("%s : %s -> %s%n", member.getSimpleName(), member.asType(), mt);
+ }
+ }
+
+ JavacTaskImpl task;
+ Elements elements;
+ Types types;
+}
--- a/langtools/test/tools/javac/generics/Casting.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/generics/Casting.java Wed Mar 17 14:19:07 2010 -0700
@@ -30,7 +30,7 @@
* @compile Casting.java
*/
-package test.tools.javac.generics.Casting;
+package Casting;
class Test {}
--- a/langtools/test/tools/javac/generics/Casting3.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/generics/Casting3.java Wed Mar 17 14:19:07 2010 -0700
@@ -30,7 +30,7 @@
* @compile Casting3.java
*/
-package test.tools.javac.generics.Casting3;
+package Casting3;
class A<T extends A<T>> {
<U extends A<U>> void f() {
--- a/langtools/test/tools/javac/generics/Casting4.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/generics/Casting4.java Wed Mar 17 14:19:07 2010 -0700
@@ -30,7 +30,7 @@
* @compile -Werror -Xlint:unchecked Casting4.java
*/
-package test.tools.javac.generics.Casting4;
+package Casting4;
class Casting4 {
<M> Integer f(Comparable<M> c) {
--- a/langtools/test/tools/javac/generics/InnerInterface1.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/generics/InnerInterface1.java Wed Mar 17 14:19:07 2010 -0700
@@ -30,7 +30,7 @@
* @compile InnerInterface1.java
*/
-package test.tools.javac.generics.InnerInterface1;
+package InnerInterface1;
interface Iterator<E> {
}
--- a/langtools/test/tools/javac/generics/InnerInterface2.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/generics/InnerInterface2.java Wed Mar 17 14:19:07 2010 -0700
@@ -30,7 +30,7 @@
* @compile InnerInterface2.java
*/
-package test.tools.javac.generics.InnerInterface2;
+package InnerInterface2;
class Builder<Community> {
--- a/langtools/test/tools/javac/generics/Multibound1.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/generics/Multibound1.java Wed Mar 17 14:19:07 2010 -0700
@@ -30,7 +30,7 @@
* @compile/fail Multibound1.java
*/
-package test.tools.javac.generics.Multibound1;
+package Multibound1;
interface A {}
interface B {}
--- a/langtools/test/tools/javac/generics/MultipleInheritance.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/generics/MultipleInheritance.java Wed Mar 17 14:19:07 2010 -0700
@@ -30,7 +30,7 @@
* @compile MultipleInheritance.java
*/
-package test.tools.javac.generics.MultipleInheritance;
+package MultipleInheritance;
import java.util.*;
--- a/langtools/test/tools/javac/generics/NameOrder.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/generics/NameOrder.java Wed Mar 17 14:19:07 2010 -0700
@@ -27,22 +27,22 @@
* @summary generics: type inference failure due to a bug in ClassSymbol.isLess
* @author gafter
*
- * @compile NameOrder.java
+ * @compile NameOrder.java
*/
-package test.tools.javac.generics.NameOrder;
+package NameOrder;
interface a {}
interface b {}
interface c {}
-class A implements a, b {}
-class B implements c, a {}
+class AB implements a, b {}
+class CA implements c, a {}
// this is how to trigger a symptom:
-abstract class C {
+abstract class X {
<T> T f(T t1, T t2) { return null; }
void g() {
- a x = f( new A(), new B() );
+ a x = f( new AB(), new CA() );
}
}
--- a/langtools/test/tools/javac/generics/PermuteBound.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/generics/PermuteBound.java Wed Mar 17 14:19:07 2010 -0700
@@ -30,7 +30,7 @@
* @compile PermuteBound.java
*/
-package test.tools.javac.generics.PermuteBound;
+package PermuteBound;
class C<X, Y> {}
--- a/langtools/test/tools/javac/generics/PrimitiveVariant.java Wed Mar 17 12:48:21 2010 +0300
+++ b/langtools/test/tools/javac/generics/PrimitiveVariant.java Wed Mar 17 14:19:07 2010 -0700
@@ -30,7 +30,7 @@
* @compile/fail PrimitiveVariant.java
*/
-package test.tools.javac.generics.PrimitiveVariant;
+package PrimitiveVariant;
interface I {
double m();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/6511613/DummyProcessor.java Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import java.util.Set;
+
+@SupportedAnnotationTypes("*")
+public class DummyProcessor extends AbstractProcessor {
+ public boolean process(Set<? extends TypeElement> annotations,
+ RoundEnvironment roundEnv) {
+ return true;
+ }
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/6511613/clss41701.java Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6511613
+ * @summary javac unexpectedly doesn't fail in some cases if an annotation processor specified
+ *
+ * @build DummyProcessor
+ * @compile/fail clss41701.java
+ * @compile/fail -processor DummyProcessor clss41701.java
+ */
+
+import java.io.PrintStream;
+
+interface clss41701i {
+ void run();
+}
+
+class clss41701a<A extends clss41701i,
+ B extends clss41701i,
+ C extends A&B> {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6449781
+ * @summary Test that reported names of anonymous classes are non-null.
+ * @author Joseph D. Darcy
+ * @build TestAnonSourceNames
+ * @compile/fail -processor TestAnonSourceNames TestAnonClassNames.java
+ * @build TestAnonClassNames
+ * @run main TestAnonClassNames
+ */
+
+/*
+ * This test operates in phases to test retrieving the qualified name
+ * of anonymous classes from type elements modeling the anonymous
+ * class. The type elements are generated using both source files and
+ * class files as the basis of constructing the elements.
+ *
+ * Source files will be tested by the @compile line which runs
+ * TestAnonSourceNames as an annotation processor over this file.
+ * This compile line is expected to fail until 6930507 is fixed. Once
+ * bug 6930507 is fixed, the "@compile/fail -processor ..." and
+ * following "@build..." steps can be replaced with a single "@compile
+ * -processor ..." directive.
+ *
+ * Class files are tested by the @run command on this type. This
+ * class gets the names of classes with different nesting kinds,
+ * including anonymous classes, and then invokes the compiler with an
+ * annotation processor having the class files names as inputs. The
+ * compiler is invoked via the javax.tools mechanism.
+ */
+
+import java.lang.annotation.*;
+import javax.lang.model.element.*;
+import javax.annotation.processing.*;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.*;
+import javax.lang.model.util.*;
+import javax.tools.*;
+import java.util.*;
+
+import static java.lang.annotation.RetentionPolicy.*;
+import static javax.lang.model.element.NestingKind.*;
+import static javax.lang.model.util.ElementFilter.*;
+import static javax.tools.Diagnostic.Kind.*;
+import static javax.tools.StandardLocation.*;
+
+@Nesting(TOP_LEVEL)
+public class TestAnonClassNames {
+ @Nesting(MEMBER)
+ static class MemberClass1{}
+
+ @Nesting(MEMBER)
+ class MemberClass2{}
+
+ @Nesting(MEMBER)
+ class Win$$AtVegas { } // Class with funny name.
+
+ public static void main(String... argv) {
+ @Nesting(LOCAL)
+ class LocalClass{};
+
+ Object o = new @Nesting(ANONYMOUS) Object() { // An anonymous annotated class
+ public String toString() {
+ return "I have no name!";
+ }
+ };
+
+ Class<?>[] classes = {
+ MemberClass1.class,
+ MemberClass2.class,
+ LocalClass.class,
+ Win$$AtVegas.class,
+ o.getClass(),
+ TestAnonClassNames.class,
+ };
+
+ for(Class<?> clazz : classes) {
+ String name = clazz.getName();
+ System.out.format("%s is %s%n",
+ clazz.getName(),
+ clazz.getAnnotation(Nesting.class).value());
+ testClassName(name);
+ }
+ }
+
+ /**
+ * Perform annotation processing on the class file name and verify
+ * the existence of different flavors of class names when the
+ * input classes are modeled as elements.
+ */
+ static void testClassName(String className) {
+ JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
+ List<String> classNames = new ArrayList<>();
+ classNames.add(className);
+
+ List<String> options = new ArrayList<>();
+ options.add("-proc:only");
+ options.add("-classpath");
+ options.add(System.getProperty("test.classes"));
+
+ JavaCompiler.CompilationTask compileTask =
+ javaCompiler.getTask(null, // Output
+ null, // File manager
+ null, // Diagnostics
+ options,
+ classNames,
+ null); // Sources
+ List<Processor> processors = new ArrayList<>();
+ processors.add(new ClassNameProber());
+ compileTask.setProcessors(processors);
+ Boolean goodResult = compileTask.call();
+ if (!goodResult) {
+ throw new RuntimeException("Errors found during compile.");
+ }
+ }
+}
+
+@Retention(RUNTIME)
+@interface Nesting {
+ NestingKind value();
+}
+
+/**
+ * Probe at the various kinds of names of a type element.
+ */
+@SupportedAnnotationTypes("*")
+class ClassNameProber extends AbstractProcessor {
+ public ClassNameProber(){super();}
+
+ private boolean classesFound=false;
+
+ public boolean process(Set<? extends TypeElement> annotations,
+ RoundEnvironment roundEnv) {
+ if (!roundEnv.processingOver()) {
+ for(TypeElement typeElt : typesIn(roundEnv.getRootElements())) {
+ classesFound = true;
+
+ // Verify different names are non-null; an NPE will
+ // result in failed compile status being reported.
+ NestingKind nestingKind = typeElt.getNestingKind();
+ System.out.printf("\tSimple name: ''%s''\tQualified Name: ''%s''\tKind ''%s''\tNesting ''%s''%n",
+ typeElt.getSimpleName().toString(),
+ typeElt.getQualifiedName().toString(),
+ typeElt.getKind().toString(),
+ nestingKind.toString());
+
+ if (typeElt.getAnnotation(Nesting.class).value() != nestingKind) {
+ throw new RuntimeException("Mismatch of expected and reported nesting kind.");
+ }
+ }
+
+ }
+
+ if (!classesFound) {
+ throw new RuntimeException("Error: no classes processed.");
+ }
+ return true;
+ }
+
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/element/TestAnonSourceNames.java Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.io.*;
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+import java.util.*;
+import com.sun.source.tree.*;
+import com.sun.source.util.*;
+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 boolean process(Set<? extends TypeElement> annotations,
+ RoundEnvironment roundEnv) {
+ if (!roundEnv.processingOver()) {
+ Trees trees = Trees.instance(processingEnv);
+
+ for(Element rootElement : roundEnv.getRootElements()) {
+ TreePath treePath = trees.getPath(rootElement);
+
+ (new ClassTreeScanner(trees)).
+ scan(trees.getTree(rootElement),
+ treePath.getCompilationUnit());
+ }
+ }
+ return true;
+ }
+
+ class ClassTreeScanner extends TreeScanner<Void, CompilationUnitTree> {
+ private Trees trees;
+
+ public ClassTreeScanner(Trees trees) {
+ super();
+ this.trees = trees;
+ }
+ @Override
+ public Void visitClass(ClassTree node, CompilationUnitTree cu) {
+ Element element = trees.getElement(trees.getPath(cu, node));
+ if (element == null) {
+ processingEnv.getMessager().printMessage(ERROR,
+ "No element retreived for node named ''" +
+ node.getSimpleName() + "''.");
+ } else {
+
+ System.out.println("\nVisiting class ``" + element.getSimpleName() +
+ "'' of kind " + element.getKind());
+ if (element instanceof TypeElement) {
+ TypeElement typeElement = (TypeElement) element;
+ String s = typeElement.getQualifiedName().toString();
+ System.out.println("\tqualified name:" + s);
+ } else {
+ throw new RuntimeException("TypeElement not gotten from ClassTree.");
+ }
+ }
+ return super.visitClass(node, cu);
+ }
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/tree/TestAnnotatedAnonClass.java Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+
+/*
+ * This file is not a regular test, but is processed by ./TreePosTest.java,
+ * which verifies the position info in the javac tree.
+ * To run the test standalone, compile TreePosTest, then run TreePosTest
+ * on this file.
+ * @bug 6931927
+ * @summary position issues with synthesized anonymous class
+ */
+class TestAnnotatedAnonClass {
+ void m() {
+ Object o = new @Deprecated Object() { };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/tree/TreePosTest.java Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,762 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.event.CaretEvent;
+import javax.swing.event.CaretListener;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.DefaultHighlighter;
+import javax.swing.text.Highlighter;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticListener;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.tree.JCTree.JCNewClass;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import com.sun.tools.javac.tree.TreeInfo;
+import com.sun.tools.javac.tree.TreeScanner;
+
+import static com.sun.tools.javac.util.Position.NOPOS;
+
+/**
+ * Utility and test program to check validity of tree positions for tree nodes.
+ * The program can be run standalone, or as a jtreg test. In standalone mode,
+ * errors can be displayed in a gui viewer. For info on command line args,
+ * run program with no args.
+ *
+ * <p>
+ * jtreg: Note that by using the -r switch in the test description below, this test
+ * will process all java files in the langtools/test directory, thus implicitly
+ * covering any new language features that may be tested in this test suite.
+ */
+
+/*
+ * @test
+ * @bug 6919889
+ * @summary assorted position errors in compiler syntax trees
+ * @run main TreePosTest -q -r -ef ./tools/javac/typeAnnotations -ef ./tools/javap/typeAnnotations -et ANNOTATED_TYPE .
+ */
+public class TreePosTest {
+ /**
+ * Main entry point.
+ * If test.src is set, program runs in jtreg mode, and will throw an Error
+ * if any errors arise, otherwise System.exit will be used, unless the gui
+ * viewer is being used. In jtreg mode, the default base directory for file
+ * args is the value of ${test.src}. In jtreg mode, the -r option can be
+ * given to change the default base directory to the root test directory.
+ */
+ public static void main(String... args) {
+ String testSrc = System.getProperty("test.src");
+ File baseDir = (testSrc == null) ? null : new File(testSrc);
+ boolean ok = new TreePosTest().run(baseDir, args);
+ if (!ok) {
+ if (testSrc != null) // jtreg mode
+ throw new Error("failed");
+ else
+ System.exit(1);
+ }
+ }
+
+ /**
+ * Run the program. A base directory can be provided for file arguments.
+ * In jtreg mode, the -r option can be given to change the default base
+ * directory to the test root directory. For other options, see usage().
+ * @param baseDir base directory for any file arguments.
+ * @param args command line args
+ * @return true if successful or in gui mode
+ */
+ boolean run(File baseDir, String... args) {
+ if (args.length == 0) {
+ usage(System.out);
+ return true;
+ }
+
+ List<File> files = new ArrayList<File>();
+ for (int i = 0; i < args.length; i++) {
+ String arg = args[i];
+ if (arg.equals("-encoding") && i + 1 < args.length)
+ encoding = args[++i];
+ else if (arg.equals("-gui"))
+ gui = true;
+ else if (arg.equals("-q"))
+ quiet = true;
+ else if (arg.equals("-v"))
+ verbose = true;
+ else if (arg.equals("-t") && i + 1 < args.length)
+ tags.add(args[++i]);
+ else if (arg.equals("-ef") && i + 1 < args.length)
+ excludeFiles.add(new File(baseDir, args[++i]));
+ else if (arg.equals("-et") && i + 1 < args.length)
+ excludeTags.add(args[++i]);
+ else if (arg.equals("-r")) {
+ if (excludeFiles.size() > 0)
+ throw new Error("-r must be used before -ef");
+ File d = baseDir;
+ while (!new File(d, "TEST.ROOT").exists()) {
+ d = d.getParentFile();
+ if (d == null)
+ throw new Error("cannot find TEST.ROOT");
+ }
+ baseDir = d;
+ }
+ else if (arg.startsWith("-"))
+ throw new Error("unknown option: " + arg);
+ else {
+ while (i < args.length)
+ files.add(new File(baseDir, args[i++]));
+ }
+ }
+
+ for (File file: files) {
+ if (file.exists())
+ test(file);
+ else
+ error("File not found: " + file);
+ }
+
+ if (fileCount != 1)
+ System.err.println(fileCount + " files read");
+ if (errors > 0)
+ System.err.println(errors + " errors");
+
+ return (gui || errors == 0);
+ }
+
+ /**
+ * Print command line help.
+ * @param out output stream
+ */
+ void usage(PrintStream out) {
+ out.println("Usage:");
+ out.println(" java TreePosTest options... files...");
+ out.println("");
+ out.println("where options include:");
+ out.println("-gui Display returns in a GUI viewer");
+ out.println("-q Quiet: don't report on inapplicable files");
+ out.println("-v Verbose: report on files as they are being read");
+ out.println("-t tag Limit checks to tree nodes with this tag");
+ out.println(" Can be repeated if desired");
+ out.println("-ef file Exclude file or directory");
+ out.println("-et tag Exclude tree nodes with given tag name");
+ out.println("");
+ out.println("files may be directories or files");
+ out.println("directories will be scanned recursively");
+ out.println("non java files, or java files which cannot be parsed, will be ignored");
+ out.println("");
+ }
+
+ /**
+ * Test a file. If the file is a directory, it will be recursively scanned
+ * for java files.
+ * @param file the file or directory to test
+ */
+ void test(File file) {
+ if (excludeFiles.contains(file)) {
+ if (!quiet)
+ error("File " + file + " excluded");
+ return;
+ }
+
+ if (file.isDirectory()) {
+ for (File f: file.listFiles()) {
+ test(f);
+ }
+ return;
+ }
+
+ if (file.isFile() && file.getName().endsWith(".java")) {
+ try {
+ if (verbose)
+ System.err.println(file);
+ fileCount++;
+ PosTester p = new PosTester();
+ p.test(read(file));
+ } catch (ParseException e) {
+ if (!quiet) {
+ error("Error parsing " + file + "\n" + e.getMessage());
+ }
+ } catch (IOException e) {
+ error("Error reading " + file + ": " + e);
+ }
+ return;
+ }
+
+ if (!quiet)
+ error("File " + file + " ignored");
+ }
+
+ /**
+ * Read a file.
+ * @param file the file to be read
+ * @return the tree for the content of the file
+ * @throws IOException if any IO errors occur
+ * @throws TreePosTest.ParseException if any errors occur while parsing the file
+ */
+ JCCompilationUnit read(File file) throws IOException, ParseException {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ Reporter r = new Reporter(pw);
+ JavacTool tool = JavacTool.create();
+ Charset cs = (encoding == null ? null : Charset.forName(encoding));
+ StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null);
+ Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(file);
+ JavacTask task = tool.getTask(pw, fm, r, Collections.<String>emptyList(), null, files);
+ Iterable<? extends CompilationUnitTree> trees = task.parse();
+ pw.flush();
+ if (r.errors > 0)
+ throw new ParseException(sw.toString());
+ Iterator<? extends CompilationUnitTree> iter = trees.iterator();
+ if (!iter.hasNext())
+ throw new Error("no trees found");
+ JCCompilationUnit t = (JCCompilationUnit) iter.next();
+ if (iter.hasNext())
+ throw new Error("too many trees found");
+ return t;
+ }
+
+ /**
+ * Report an error. When the program is complete, the program will either
+ * exit or throw an Error if any errors have been reported.
+ * @param msg the error message
+ */
+ void error(String msg) {
+ System.err.println(msg);
+ errors++;
+ }
+
+ /** Number of files that have been analyzed. */
+ int fileCount;
+ /** Number of errors reported. */
+ int errors;
+ /** Flag: don't report irrelevant files. */
+ boolean quiet;
+ /** Flag: report files as they are processed. */
+ boolean verbose;
+ /** Flag: show errors in GUI viewer. */
+ boolean gui;
+ /** Option: encoding for test files. */
+ String encoding;
+ /** The GUI viewer for errors. */
+ Viewer viewer;
+ /** The set of tags for tree nodes to be analyzed; if empty, all tree nodes
+ * are analyzed. */
+ Set<String> tags = new HashSet<String>();
+ /** Set of files and directories to be excluded from analysis. */
+ Set<File> excludeFiles = new HashSet<File>();
+ /** Set of tag names to be excluded from analysis. */
+ Set<String> excludeTags = new HashSet<String>();
+ /** Table of printable names for tree tag values. */
+ TagNames tagNames = new TagNames();
+
+ /**
+ * Main class for testing assertions concerning tree positions for tree nodes.
+ */
+ private class PosTester extends TreeScanner {
+ void test(JCCompilationUnit tree) {
+ sourcefile = tree.sourcefile;
+ endPosTable = tree.endPositions;
+ encl = new Info();
+ tree.accept(this);
+ }
+
+ @Override
+ public void scan(JCTree tree) {
+ if (tree == null)
+ return;
+
+ Info self = new Info(tree, endPosTable);
+ if (check(encl, self)) {
+ // Modifiers nodes are present throughout the tree even where
+ // there is no corresponding source text.
+ // Redundant semicolons in a class definition can cause empty
+ // initializer blocks with no positions.
+ if ((self.tag == JCTree.MODIFIERS || self.tag == JCTree.BLOCK)
+ && self.pos == NOPOS) {
+ // If pos is NOPOS, so should be the start and end positions
+ check("start == NOPOS", encl, self, self.start == NOPOS);
+ check("end == NOPOS", encl, self, self.end == NOPOS);
+ } else {
+ // For this node, start , pos, and endpos should be all defined
+ check("start != NOPOS", encl, self, self.start != NOPOS);
+ check("pos != NOPOS", encl, self, self.pos != NOPOS);
+ check("end != NOPOS", encl, self, self.end != NOPOS);
+ // The following should normally be ordered
+ // encl.start <= start <= pos <= end <= encl.end
+ // In addition, the position of the enclosing node should be
+ // within this node.
+ // The primary exceptions are for array type nodes, because of the
+ // need to support legacy syntax:
+ // e.g. int a[]; int[] b[]; int f()[] { return null; }
+ // and because of inconsistent nesting of left and right of
+ // array declarations:
+ // e.g. int[][] a = new int[2][];
+ check("encl.start <= start", encl, self, encl.start <= self.start);
+ check("start <= pos", encl, self, self.start <= self.pos);
+ if (!(self.tag == JCTree.TYPEARRAY
+ && (encl.tag == JCTree.VARDEF || encl.tag == JCTree.TYPEARRAY))) {
+ check("encl.pos <= start || end <= encl.pos",
+ encl, self, encl.pos <= self.start || self.end <= encl.pos);
+ }
+ check("pos <= end", encl, self, self.pos <= self.end);
+ if (!(self.tag == JCTree.TYPEARRAY && encl.tag == JCTree.TYPEARRAY)) {
+ check("end <= encl.end", encl, self, self.end <= encl.end);
+ }
+ }
+ }
+
+ Info prevEncl = encl;
+ encl = self;
+ tree.accept(this);
+ encl = prevEncl;
+ }
+
+ @Override
+ public void visitVarDef(JCVariableDecl tree) {
+ // enum member declarations are desugared in the parser and have
+ // ill-defined semantics for tree positions, so for now, we
+ // skip the synthesized bits and just check parts which came from
+ // the original source text
+ if ((tree.mods.flags & Flags.ENUM) != 0) {
+ scan(tree.mods);
+ if (tree.init != null) {
+ if (tree.init.getTag() == JCTree.NEWCLASS) {
+ JCNewClass init = (JCNewClass) tree.init;
+ if (init.args != null && init.args.nonEmpty()) {
+ scan(init.args);
+ }
+ if (init.def != null && init.def.defs != null) {
+ scan(init.def.defs);
+ }
+ }
+ }
+ } else
+ super.visitVarDef(tree);
+ }
+
+ boolean check(Info encl, Info self) {
+ if (excludeTags.size() > 0) {
+ if (encl != null && excludeTags.contains(tagNames.get(encl.tag))
+ || excludeTags.contains(tagNames.get(self.tag)))
+ return false;
+ }
+ return tags.size() == 0 || tags.contains(tagNames.get(self.tag));
+ }
+
+ void check(String label, Info encl, Info self, boolean ok) {
+ if (!ok) {
+ if (gui) {
+ if (viewer == null)
+ viewer = new Viewer();
+ viewer.addEntry(sourcefile, label, encl, self);
+ }
+
+ String s = self.tree.toString();
+ String msg = sourcefile.getName() + ": " + label + ": " +
+ "encl:" + encl + " this:" + self + "\n" +
+ s.substring(0, Math.min(80, s.length())).replaceAll("[\r\n]+", " ");
+ error(msg);
+ }
+ }
+
+ JavaFileObject sourcefile;
+ Map<JCTree, Integer> endPosTable;
+ Info encl;
+
+ }
+
+ /**
+ * Utility class providing easy access to position and other info for a tree node.
+ */
+ private class Info {
+ Info() {
+ tree = null;
+ tag = JCTree.ERRONEOUS;
+ start = 0;
+ pos = 0;
+ end = Integer.MAX_VALUE;
+ }
+
+ Info(JCTree tree, Map<JCTree, Integer> endPosTable) {
+ this.tree = tree;
+ tag = tree.getTag();
+ start = TreeInfo.getStartPos(tree);
+ pos = tree.pos;
+ end = TreeInfo.getEndPos(tree, endPosTable);
+ }
+
+ @Override
+ public String toString() {
+ return tagNames.get(tree.getTag()) + "[start:" + start + ",pos:" + pos + ",end:" + end + "]";
+ }
+
+ final JCTree tree;
+ final int tag;
+ final int start;
+ final int pos;
+ final int end;
+ }
+
+ /**
+ * Names for tree tags.
+ * javac does not provide an API to convert tag values to strings, so this class uses
+ * reflection to determine names of public static final int values in JCTree.
+ */
+ private static class TagNames {
+ String get(int tag) {
+ if (map == null) {
+ map = new HashMap<Integer, String>();
+ Class c = JCTree.class;
+ for (Field f : c.getDeclaredFields()) {
+ if (f.getType().equals(int.class)) {
+ int mods = f.getModifiers();
+ if (Modifier.isPublic(mods) && Modifier.isStatic(mods) && Modifier.isFinal(mods)) {
+ try {
+ map.put(f.getInt(null), f.getName());
+ } catch (IllegalAccessException e) {
+ }
+ }
+ }
+ }
+ }
+ String name = map.get(tag);
+ return (name == null) ? "??" : name;
+ }
+
+ private Map<Integer, String> map;
+ }
+
+ /**
+ * Thrown when errors are found parsing a java file.
+ */
+ private static class ParseException extends Exception {
+ ParseException(String msg) {
+ super(msg);
+ }
+ }
+
+ /**
+ * DiagnosticListener to report diagnostics and count any errors that occur.
+ */
+ private static class Reporter implements DiagnosticListener<JavaFileObject> {
+ Reporter(PrintWriter out) {
+ this.out = out;
+ }
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ out.println(diagnostic);
+ switch (diagnostic.getKind()) {
+ case ERROR:
+ errors++;
+ }
+ }
+ int errors;
+ PrintWriter out;
+ }
+
+ /**
+ * GUI viewer for issues found by TreePosTester. The viewer provides a drop
+ * down list for selecting error conditions, a header area providing details
+ * about an error, and a text area with the ranges of text highlighted as
+ * appropriate.
+ */
+ private class Viewer extends JFrame {
+ /**
+ * Create a viewer.
+ */
+ Viewer() {
+ initGUI();
+ }
+
+ /**
+ * Add another entry to the list of errors.
+ * @param file The file containing the error
+ * @param check The condition that was being tested, and which failed
+ * @param encl the enclosing tree node
+ * @param self the tree node containing the error
+ */
+ void addEntry(JavaFileObject file, String check, Info encl, Info self) {
+ Entry e = new Entry(file, check, encl, self);
+ DefaultComboBoxModel m = (DefaultComboBoxModel) entries.getModel();
+ m.addElement(e);
+ if (m.getSize() == 1)
+ entries.setSelectedItem(e);
+ }
+
+ /**
+ * Initialize the GUI window.
+ */
+ private void initGUI() {
+ JPanel head = new JPanel(new GridBagLayout());
+ GridBagConstraints lc = new GridBagConstraints();
+ GridBagConstraints fc = new GridBagConstraints();
+ fc.anchor = GridBagConstraints.WEST;
+ fc.fill = GridBagConstraints.HORIZONTAL;
+ fc.gridwidth = GridBagConstraints.REMAINDER;
+
+ entries = new JComboBox();
+ entries.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ showEntry((Entry) entries.getSelectedItem());
+ }
+ });
+ fc.insets.bottom = 10;
+ head.add(entries, fc);
+ fc.insets.bottom = 0;
+ head.add(new JLabel("check:"), lc);
+ head.add(checkField = createTextField(80), fc);
+ fc.fill = GridBagConstraints.NONE;
+ head.add(setBackground(new JLabel("encl:"), enclColor), lc);
+ head.add(enclPanel = new InfoPanel(), fc);
+ head.add(setBackground(new JLabel("self:"), selfColor), lc);
+ head.add(selfPanel = new InfoPanel(), fc);
+ add(head, BorderLayout.NORTH);
+
+ body = new JTextArea();
+ body.setFont(Font.decode(Font.MONOSPACED));
+ body.addCaretListener(new CaretListener() {
+ public void caretUpdate(CaretEvent e) {
+ int dot = e.getDot();
+ int mark = e.getMark();
+ if (dot == mark)
+ statusText.setText("dot: " + dot);
+ else
+ statusText.setText("dot: " + dot + ", mark:" + mark);
+ }
+ });
+ JScrollPane p = new JScrollPane(body,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ p.setPreferredSize(new Dimension(640, 480));
+ add(p, BorderLayout.CENTER);
+
+ statusText = createTextField(80);
+ add(statusText, BorderLayout.SOUTH);
+
+ pack();
+ setLocationRelativeTo(null); // centered on screen
+ setVisible(true);
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ }
+
+ /** Show an entry that has been selected. */
+ private void showEntry(Entry e) {
+ try {
+ // update simple fields
+ setTitle(e.file.getName());
+ checkField.setText(e.check);
+ enclPanel.setInfo(e.encl);
+ selfPanel.setInfo(e.self);
+ // show file text with highlights
+ body.setText(e.file.getCharContent(true).toString());
+ Highlighter highlighter = body.getHighlighter();
+ highlighter.removeAllHighlights();
+ addHighlight(highlighter, e.encl, enclColor);
+ addHighlight(highlighter, e.self, selfColor);
+ scroll(body, getMinPos(enclPanel.info, selfPanel.info));
+ } catch (IOException ex) {
+ body.setText("Cannot read " + e.file.getName() + ": " + e);
+ }
+ }
+
+ /** Create a test field. */
+ private JTextField createTextField(int width) {
+ JTextField f = new JTextField(width);
+ f.setEditable(false);
+ f.setBorder(null);
+ return f;
+ }
+
+ /** Add a highlighted region based on the positions in an Info object. */
+ private void addHighlight(Highlighter h, Info info, Color c) {
+ int start = info.start;
+ int end = info.end;
+ if (start == -1 && end == -1)
+ return;
+ if (start == -1)
+ start = end;
+ if (end == -1)
+ end = start;
+ try {
+ h.addHighlight(info.start, info.end,
+ new DefaultHighlighter.DefaultHighlightPainter(c));
+ if (info.pos != -1) {
+ Color c2 = new Color(c.getRed(), c.getGreen(), c.getBlue(), (int)(.4f * 255)); // 40%
+ h.addHighlight(info.pos, info.pos + 1,
+ new DefaultHighlighter.DefaultHighlightPainter(c2));
+ }
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /** Get the minimum valid position in a set of info objects. */
+ private int getMinPos(Info... values) {
+ int i = Integer.MAX_VALUE;
+ for (Info info: values) {
+ if (info.start >= 0) i = Math.min(i, info.start);
+ if (info.pos >= 0) i = Math.min(i, info.pos);
+ if (info.end >= 0) i = Math.min(i, info.end);
+ }
+ return (i == Integer.MAX_VALUE) ? 0 : i;
+ }
+
+ /** Set the background on a component. */
+ private JComponent setBackground(JComponent comp, Color c) {
+ comp.setOpaque(true);
+ comp.setBackground(c);
+ return comp;
+ }
+
+ /** Scroll a text area to display a given position near the middle of the visible area. */
+ private void scroll(final JTextArea t, final int pos) {
+ // Using invokeLater appears to give text a chance to sort itself out
+ // before the scroll happens; otherwise scrollRectToVisible doesn't work.
+ // Maybe there's a better way to sync with the text...
+ EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ try {
+ Rectangle r = t.modelToView(pos);
+ JScrollPane p = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, t);
+ r.y = Math.max(0, r.y - p.getHeight() * 2 / 5);
+ r.height += p.getHeight() * 4 / 5;
+ t.scrollRectToVisible(r);
+ } catch (BadLocationException ignore) {
+ }
+ }
+ });
+ }
+
+ private JComboBox entries;
+ private JTextField checkField;
+ private InfoPanel enclPanel;
+ private InfoPanel selfPanel;
+ private JTextArea body;
+ private JTextField statusText;
+
+ private Color selfColor = new Color(0.f, 1.f, 0.f, 0.2f); // 20% green
+ private Color enclColor = new Color(1.f, 0.f, 0.f, 0.2f); // 20% red
+
+ /** Panel to display an Info object. */
+ private class InfoPanel extends JPanel {
+ InfoPanel() {
+ add(tagName = createTextField(20));
+ add(new JLabel("start:"));
+ add(addListener(start = createTextField(6)));
+ add(new JLabel("pos:"));
+ add(addListener(pos = createTextField(6)));
+ add(new JLabel("end:"));
+ add(addListener(end = createTextField(6)));
+ }
+
+ void setInfo(Info info) {
+ this.info = info;
+ tagName.setText(tagNames.get(info.tag));
+ start.setText(String.valueOf(info.start));
+ pos.setText(String.valueOf(info.pos));
+ end.setText(String.valueOf(info.end));
+ }
+
+ JTextField addListener(final JTextField f) {
+ f.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ body.setCaretPosition(Integer.valueOf(f.getText()));
+ body.getCaret().setVisible(true);
+ }
+ });
+ return f;
+ }
+
+ Info info;
+ JTextField tagName;
+ JTextField start;
+ JTextField pos;
+ JTextField end;
+ }
+
+ /** Object to record information about an error to be displayed. */
+ private class Entry {
+ Entry(JavaFileObject file, String check, Info encl, Info self) {
+ this.file = file;
+ this.check = check;
+ this.encl = encl;
+ this.self= self;
+ }
+
+ @Override
+ public String toString() {
+ return file.getName() + " " + check + " " + getMinPos(encl, self);
+ }
+
+ final JavaFileObject file;
+ final String check;
+ final Info encl;
+ final Info self;
+ }
+ }
+}
+
--- a/langtools/test/tools/javac/treepostests/TreePosTest.java Wed Mar 17 12:48:21 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,762 +0,0 @@
-/*
- * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.EventQueue;
-import java.awt.Font;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Rectangle;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.swing.DefaultComboBoxModel;
-import javax.swing.JComboBox;
-import javax.swing.JComponent;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
-import javax.swing.JTextField;
-import javax.swing.SwingUtilities;
-import javax.swing.event.CaretEvent;
-import javax.swing.event.CaretListener;
-import javax.swing.text.BadLocationException;
-import javax.swing.text.DefaultHighlighter;
-import javax.swing.text.Highlighter;
-import javax.tools.Diagnostic;
-import javax.tools.DiagnosticListener;
-import javax.tools.JavaFileObject;
-import javax.tools.StandardJavaFileManager;
-
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.util.JavacTask;
-import com.sun.tools.javac.api.JavacTool;
-import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
-import com.sun.tools.javac.tree.JCTree.JCNewClass;
-import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
-import com.sun.tools.javac.tree.TreeInfo;
-import com.sun.tools.javac.tree.TreeScanner;
-
-import static com.sun.tools.javac.util.Position.NOPOS;
-
-/**
- * Utility and test program to check validity of tree positions for tree nodes.
- * The program can be run standalone, or as a jtreg test. In standalone mode,
- * errors can be displayed in a gui viewer. For info on command line args,
- * run program with no args.
- *
- * <p>
- * jtreg: Note that by using the -r switch in the test description below, this test
- * will process all java files in the langtools/test directory, thus implicitly
- * covering any new language features that may be tested in this test suite.
- */
-
-/*
- * @test
- * @bug 6919889
- * @summary assorted position errors in compiler syntax trees
- * @run main TreePosTest -q -r -ef ./tools/javac/typeAnnotations -ef ./tools/javap/typeAnnotations -et ANNOTATED_TYPE .
- */
-public class TreePosTest {
- /**
- * Main entry point.
- * If test.src is set, program runs in jtreg mode, and will throw an Error
- * if any errors arise, otherwise System.exit will be used, unless the gui
- * viewer is being used. In jtreg mode, the default base directory for file
- * args is the value of ${test.src}. In jtreg mode, the -r option can be
- * given to change the default base directory to the root test directory.
- */
- public static void main(String... args) {
- String testSrc = System.getProperty("test.src");
- File baseDir = (testSrc == null) ? null : new File(testSrc);
- boolean ok = new TreePosTest().run(baseDir, args);
- if (!ok) {
- if (testSrc != null) // jtreg mode
- throw new Error("failed");
- else
- System.exit(1);
- }
- }
-
- /**
- * Run the program. A base directory can be provided for file arguments.
- * In jtreg mode, the -r option can be given to change the default base
- * directory to the test root directory. For other options, see usage().
- * @param baseDir base directory for any file arguments.
- * @param args command line args
- * @return true if successful or in gui mode
- */
- boolean run(File baseDir, String... args) {
- if (args.length == 0) {
- usage(System.out);
- return true;
- }
-
- List<File> files = new ArrayList<File>();
- for (int i = 0; i < args.length; i++) {
- String arg = args[i];
- if (arg.equals("-encoding") && i + 1 < args.length)
- encoding = args[++i];
- else if (arg.equals("-gui"))
- gui = true;
- else if (arg.equals("-q"))
- quiet = true;
- else if (arg.equals("-v"))
- verbose = true;
- else if (arg.equals("-t") && i + 1 < args.length)
- tags.add(args[++i]);
- else if (arg.equals("-ef") && i + 1 < args.length)
- excludeFiles.add(new File(baseDir, args[++i]));
- else if (arg.equals("-et") && i + 1 < args.length)
- excludeTags.add(args[++i]);
- else if (arg.equals("-r")) {
- if (excludeFiles.size() > 0)
- throw new Error("-r must be used before -ef");
- File d = baseDir;
- while (!new File(d, "TEST.ROOT").exists()) {
- d = d.getParentFile();
- if (d == null)
- throw new Error("cannot find TEST.ROOT");
- }
- baseDir = d;
- }
- else if (arg.startsWith("-"))
- throw new Error("unknown option: " + arg);
- else {
- while (i < args.length)
- files.add(new File(baseDir, args[i++]));
- }
- }
-
- for (File file: files) {
- if (file.exists())
- test(file);
- else
- error("File not found: " + file);
- }
-
- if (fileCount != 1)
- System.err.println(fileCount + " files read");
- if (errors > 0)
- System.err.println(errors + " errors");
-
- return (gui || errors == 0);
- }
-
- /**
- * Print command line help.
- * @param out output stream
- */
- void usage(PrintStream out) {
- out.println("Usage:");
- out.println(" java TreePosTest options... files...");
- out.println("");
- out.println("where options include:");
- out.println("-gui Display returns in a GUI viewer");
- out.println("-q Quiet: don't report on inapplicable files");
- out.println("-v Verbose: report on files as they are being read");
- out.println("-t tag Limit checks to tree nodes with this tag");
- out.println(" Can be repeated if desired");
- out.println("-ef file Exclude file or directory");
- out.println("-et tag Exclude tree nodes with given tag name");
- out.println("");
- out.println("files may be directories or files");
- out.println("directories will be scanned recursively");
- out.println("non java files, or java files which cannot be parsed, will be ignored");
- out.println("");
- }
-
- /**
- * Test a file. If the file is a directory, it will be recursively scanned
- * for java files.
- * @param file the file or directory to test
- */
- void test(File file) {
- if (excludeFiles.contains(file)) {
- if (!quiet)
- error("File " + file + " excluded");
- return;
- }
-
- if (file.isDirectory()) {
- for (File f: file.listFiles()) {
- test(f);
- }
- return;
- }
-
- if (file.isFile() && file.getName().endsWith(".java")) {
- try {
- if (verbose)
- System.err.println(file);
- fileCount++;
- PosTester p = new PosTester();
- p.test(read(file));
- } catch (ParseException e) {
- if (!quiet) {
- error("Error parsing " + file + "\n" + e.getMessage());
- }
- } catch (IOException e) {
- error("Error reading " + file + ": " + e);
- }
- return;
- }
-
- if (!quiet)
- error("File " + file + " ignored");
- }
-
- /**
- * Read a file.
- * @param file the file to be read
- * @return the tree for the content of the file
- * @throws IOException if any IO errors occur
- * @throws TreePosTest.ParseException if any errors occur while parsing the file
- */
- JCCompilationUnit read(File file) throws IOException, ParseException {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- Reporter r = new Reporter(pw);
- JavacTool tool = JavacTool.create();
- Charset cs = (encoding == null ? null : Charset.forName(encoding));
- StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null);
- Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(file);
- JavacTask task = tool.getTask(pw, fm, r, Collections.<String>emptyList(), null, files);
- Iterable<? extends CompilationUnitTree> trees = task.parse();
- pw.flush();
- if (r.errors > 0)
- throw new ParseException(sw.toString());
- Iterator<? extends CompilationUnitTree> iter = trees.iterator();
- if (!iter.hasNext())
- throw new Error("no trees found");
- JCCompilationUnit t = (JCCompilationUnit) iter.next();
- if (iter.hasNext())
- throw new Error("too many trees found");
- return t;
- }
-
- /**
- * Report an error. When the program is complete, the program will either
- * exit or throw an Error if any errors have been reported.
- * @param msg the error message
- */
- void error(String msg) {
- System.err.println(msg);
- errors++;
- }
-
- /** Number of files that have been analyzed. */
- int fileCount;
- /** Number of errors reported. */
- int errors;
- /** Flag: don't report irrelevant files. */
- boolean quiet;
- /** Flag: report files as they are processed. */
- boolean verbose;
- /** Flag: show errors in GUI viewer. */
- boolean gui;
- /** Option: encoding for test files. */
- String encoding;
- /** The GUI viewer for errors. */
- Viewer viewer;
- /** The set of tags for tree nodes to be analyzed; if empty, all tree nodes
- * are analyzed. */
- Set<String> tags = new HashSet<String>();
- /** Set of files and directories to be excluded from analysis. */
- Set<File> excludeFiles = new HashSet<File>();
- /** Set of tag names to be excluded from analysis. */
- Set<String> excludeTags = new HashSet<String>();
- /** Table of printable names for tree tag values. */
- TagNames tagNames = new TagNames();
-
- /**
- * Main class for testing assertions concerning tree positions for tree nodes.
- */
- private class PosTester extends TreeScanner {
- void test(JCCompilationUnit tree) {
- sourcefile = tree.sourcefile;
- endPosTable = tree.endPositions;
- encl = new Info();
- tree.accept(this);
- }
-
- @Override
- public void scan(JCTree tree) {
- if (tree == null)
- return;
-
- Info self = new Info(tree, endPosTable);
- if (check(encl, self)) {
- // Modifiers nodes are present throughout the tree even where
- // there is no corresponding source text.
- // Redundant semicolons in a class definition can cause empty
- // initializer blocks with no positions.
- if ((self.tag == JCTree.MODIFIERS || self.tag == JCTree.BLOCK)
- && self.pos == NOPOS) {
- // If pos is NOPOS, so should be the start and end positions
- check("start == NOPOS", encl, self, self.start == NOPOS);
- check("end == NOPOS", encl, self, self.end == NOPOS);
- } else {
- // For this node, start , pos, and endpos should be all defined
- check("start != NOPOS", encl, self, self.start != NOPOS);
- check("pos != NOPOS", encl, self, self.pos != NOPOS);
- check("end != NOPOS", encl, self, self.end != NOPOS);
- // The following should normally be ordered
- // encl.start <= start <= pos <= end <= encl.end
- // In addition, the position of the enclosing node should be
- // within this node.
- // The primary exceptions are for array type nodes, because of the
- // need to support legacy syntax:
- // e.g. int a[]; int[] b[]; int f()[] { return null; }
- // and because of inconsistent nesting of left and right of
- // array declarations:
- // e.g. int[][] a = new int[2][];
- check("encl.start <= start", encl, self, encl.start <= self.start);
- check("start <= pos", encl, self, self.start <= self.pos);
- if (!(self.tag == JCTree.TYPEARRAY
- && (encl.tag == JCTree.VARDEF || encl.tag == JCTree.TYPEARRAY))) {
- check("encl.pos <= start || end <= encl.pos",
- encl, self, encl.pos <= self.start || self.end <= encl.pos);
- }
- check("pos <= end", encl, self, self.pos <= self.end);
- if (!(self.tag == JCTree.TYPEARRAY && encl.tag == JCTree.TYPEARRAY)) {
- check("end <= encl.end", encl, self, self.end <= encl.end);
- }
- }
- }
-
- Info prevEncl = encl;
- encl = self;
- tree.accept(this);
- encl = prevEncl;
- }
-
- @Override
- public void visitVarDef(JCVariableDecl tree) {
- // enum member declarations are desugared in the parser and have
- // ill-defined semantics for tree positions, so for now, we
- // skip the synthesized bits and just check parts which came from
- // the original source text
- if ((tree.mods.flags & Flags.ENUM) != 0) {
- scan(tree.mods);
- if (tree.init != null) {
- if (tree.init.getTag() == JCTree.NEWCLASS) {
- JCNewClass init = (JCNewClass) tree.init;
- if (init.args != null && init.args.nonEmpty()) {
- scan(init.args);
- }
- if (init.def != null && init.def.defs != null) {
- scan(init.def.defs);
- }
- }
- }
- } else
- super.visitVarDef(tree);
- }
-
- boolean check(Info encl, Info self) {
- if (excludeTags.size() > 0) {
- if (encl != null && excludeTags.contains(tagNames.get(encl.tag))
- || excludeTags.contains(tagNames.get(self.tag)))
- return false;
- }
- return tags.size() == 0 || tags.contains(tagNames.get(self.tag));
- }
-
- void check(String label, Info encl, Info self, boolean ok) {
- if (!ok) {
- if (gui) {
- if (viewer == null)
- viewer = new Viewer();
- viewer.addEntry(sourcefile, label, encl, self);
- }
-
- String s = self.tree.toString();
- String msg = sourcefile.getName() + ": " + label + ": " +
- "encl:" + encl + " this:" + self + "\n" +
- s.substring(0, Math.min(80, s.length())).replaceAll("[\r\n]+", " ");
- error(msg);
- }
- }
-
- JavaFileObject sourcefile;
- Map<JCTree, Integer> endPosTable;
- Info encl;
-
- }
-
- /**
- * Utility class providing easy access to position and other info for a tree node.
- */
- private class Info {
- Info() {
- tree = null;
- tag = JCTree.ERRONEOUS;
- start = 0;
- pos = 0;
- end = Integer.MAX_VALUE;
- }
-
- Info(JCTree tree, Map<JCTree, Integer> endPosTable) {
- this.tree = tree;
- tag = tree.getTag();
- start = TreeInfo.getStartPos(tree);
- pos = tree.pos;
- end = TreeInfo.getEndPos(tree, endPosTable);
- }
-
- @Override
- public String toString() {
- return tagNames.get(tree.getTag()) + "[start:" + start + ",pos:" + pos + ",end:" + end + "]";
- }
-
- final JCTree tree;
- final int tag;
- final int start;
- final int pos;
- final int end;
- }
-
- /**
- * Names for tree tags.
- * javac does not provide an API to convert tag values to strings, so this class uses
- * reflection to determine names of public static final int values in JCTree.
- */
- private static class TagNames {
- String get(int tag) {
- if (map == null) {
- map = new HashMap<Integer, String>();
- Class c = JCTree.class;
- for (Field f : c.getDeclaredFields()) {
- if (f.getType().equals(int.class)) {
- int mods = f.getModifiers();
- if (Modifier.isPublic(mods) && Modifier.isStatic(mods) && Modifier.isFinal(mods)) {
- try {
- map.put(f.getInt(null), f.getName());
- } catch (IllegalAccessException e) {
- }
- }
- }
- }
- }
- String name = map.get(tag);
- return (name == null) ? "??" : name;
- }
-
- private Map<Integer, String> map;
- }
-
- /**
- * Thrown when errors are found parsing a java file.
- */
- private static class ParseException extends Exception {
- ParseException(String msg) {
- super(msg);
- }
- }
-
- /**
- * DiagnosticListener to report diagnostics and count any errors that occur.
- */
- private static class Reporter implements DiagnosticListener<JavaFileObject> {
- Reporter(PrintWriter out) {
- this.out = out;
- }
-
- public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
- out.println(diagnostic);
- switch (diagnostic.getKind()) {
- case ERROR:
- errors++;
- }
- }
- int errors;
- PrintWriter out;
- }
-
- /**
- * GUI viewer for issues found by TreePosTester. The viewer provides a drop
- * down list for selecting error conditions, a header area providing details
- * about an error, and a text area with the ranges of text highlighted as
- * appropriate.
- */
- private class Viewer extends JFrame {
- /**
- * Create a viewer.
- */
- Viewer() {
- initGUI();
- }
-
- /**
- * Add another entry to the list of errors.
- * @param file The file containing the error
- * @param check The condition that was being tested, and which failed
- * @param encl the enclosing tree node
- * @param self the tree node containing the error
- */
- void addEntry(JavaFileObject file, String check, Info encl, Info self) {
- Entry e = new Entry(file, check, encl, self);
- DefaultComboBoxModel m = (DefaultComboBoxModel) entries.getModel();
- m.addElement(e);
- if (m.getSize() == 1)
- entries.setSelectedItem(e);
- }
-
- /**
- * Initialize the GUI window.
- */
- private void initGUI() {
- JPanel head = new JPanel(new GridBagLayout());
- GridBagConstraints lc = new GridBagConstraints();
- GridBagConstraints fc = new GridBagConstraints();
- fc.anchor = GridBagConstraints.WEST;
- fc.fill = GridBagConstraints.HORIZONTAL;
- fc.gridwidth = GridBagConstraints.REMAINDER;
-
- entries = new JComboBox();
- entries.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- showEntry((Entry) entries.getSelectedItem());
- }
- });
- fc.insets.bottom = 10;
- head.add(entries, fc);
- fc.insets.bottom = 0;
- head.add(new JLabel("check:"), lc);
- head.add(checkField = createTextField(80), fc);
- fc.fill = GridBagConstraints.NONE;
- head.add(setBackground(new JLabel("encl:"), enclColor), lc);
- head.add(enclPanel = new InfoPanel(), fc);
- head.add(setBackground(new JLabel("self:"), selfColor), lc);
- head.add(selfPanel = new InfoPanel(), fc);
- add(head, BorderLayout.NORTH);
-
- body = new JTextArea();
- body.setFont(Font.decode(Font.MONOSPACED));
- body.addCaretListener(new CaretListener() {
- public void caretUpdate(CaretEvent e) {
- int dot = e.getDot();
- int mark = e.getMark();
- if (dot == mark)
- statusText.setText("dot: " + dot);
- else
- statusText.setText("dot: " + dot + ", mark:" + mark);
- }
- });
- JScrollPane p = new JScrollPane(body,
- JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
- JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
- p.setPreferredSize(new Dimension(640, 480));
- add(p, BorderLayout.CENTER);
-
- statusText = createTextField(80);
- add(statusText, BorderLayout.SOUTH);
-
- pack();
- setLocationRelativeTo(null); // centered on screen
- setVisible(true);
- setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- }
-
- /** Show an entry that has been selected. */
- private void showEntry(Entry e) {
- try {
- // update simple fields
- setTitle(e.file.getName());
- checkField.setText(e.check);
- enclPanel.setInfo(e.encl);
- selfPanel.setInfo(e.self);
- // show file text with highlights
- body.setText(e.file.getCharContent(true).toString());
- Highlighter highlighter = body.getHighlighter();
- highlighter.removeAllHighlights();
- addHighlight(highlighter, e.encl, enclColor);
- addHighlight(highlighter, e.self, selfColor);
- scroll(body, getMinPos(enclPanel.info, selfPanel.info));
- } catch (IOException ex) {
- body.setText("Cannot read " + e.file.getName() + ": " + e);
- }
- }
-
- /** Create a test field. */
- private JTextField createTextField(int width) {
- JTextField f = new JTextField(width);
- f.setEditable(false);
- f.setBorder(null);
- return f;
- }
-
- /** Add a highlighted region based on the positions in an Info object. */
- private void addHighlight(Highlighter h, Info info, Color c) {
- int start = info.start;
- int end = info.end;
- if (start == -1 && end == -1)
- return;
- if (start == -1)
- start = end;
- if (end == -1)
- end = start;
- try {
- h.addHighlight(info.start, info.end,
- new DefaultHighlighter.DefaultHighlightPainter(c));
- if (info.pos != -1) {
- Color c2 = new Color(c.getRed(), c.getGreen(), c.getBlue(), (int)(.4f * 255)); // 40%
- h.addHighlight(info.pos, info.pos + 1,
- new DefaultHighlighter.DefaultHighlightPainter(c2));
- }
- } catch (BadLocationException e) {
- e.printStackTrace();
- }
- }
-
- /** Get the minimum valid position in a set of info objects. */
- private int getMinPos(Info... values) {
- int i = Integer.MAX_VALUE;
- for (Info info: values) {
- if (info.start >= 0) i = Math.min(i, info.start);
- if (info.pos >= 0) i = Math.min(i, info.pos);
- if (info.end >= 0) i = Math.min(i, info.end);
- }
- return (i == Integer.MAX_VALUE) ? 0 : i;
- }
-
- /** Set the background on a component. */
- private JComponent setBackground(JComponent comp, Color c) {
- comp.setOpaque(true);
- comp.setBackground(c);
- return comp;
- }
-
- /** Scroll a text area to display a given position near the middle of the visible area. */
- private void scroll(final JTextArea t, final int pos) {
- // Using invokeLater appears to give text a chance to sort itself out
- // before the scroll happens; otherwise scrollRectToVisible doesn't work.
- // Maybe there's a better way to sync with the text...
- EventQueue.invokeLater(new Runnable() {
- public void run() {
- try {
- Rectangle r = t.modelToView(pos);
- JScrollPane p = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, t);
- r.y = Math.max(0, r.y - p.getHeight() * 2 / 5);
- r.height += p.getHeight() * 4 / 5;
- t.scrollRectToVisible(r);
- } catch (BadLocationException ignore) {
- }
- }
- });
- }
-
- private JComboBox entries;
- private JTextField checkField;
- private InfoPanel enclPanel;
- private InfoPanel selfPanel;
- private JTextArea body;
- private JTextField statusText;
-
- private Color selfColor = new Color(0.f, 1.f, 0.f, 0.2f); // 20% green
- private Color enclColor = new Color(1.f, 0.f, 0.f, 0.2f); // 20% red
-
- /** Panel to display an Info object. */
- private class InfoPanel extends JPanel {
- InfoPanel() {
- add(tagName = createTextField(20));
- add(new JLabel("start:"));
- add(addListener(start = createTextField(6)));
- add(new JLabel("pos:"));
- add(addListener(pos = createTextField(6)));
- add(new JLabel("end:"));
- add(addListener(end = createTextField(6)));
- }
-
- void setInfo(Info info) {
- this.info = info;
- tagName.setText(tagNames.get(info.tag));
- start.setText(String.valueOf(info.start));
- pos.setText(String.valueOf(info.pos));
- end.setText(String.valueOf(info.end));
- }
-
- JTextField addListener(final JTextField f) {
- f.addMouseListener(new MouseAdapter() {
- @Override
- public void mouseClicked(MouseEvent e) {
- body.setCaretPosition(Integer.valueOf(f.getText()));
- body.getCaret().setVisible(true);
- }
- });
- return f;
- }
-
- Info info;
- JTextField tagName;
- JTextField start;
- JTextField pos;
- JTextField end;
- }
-
- /** Object to record information about an error to be displayed. */
- private class Entry {
- Entry(JavaFileObject file, String check, Info encl, Info self) {
- this.file = file;
- this.check = check;
- this.encl = encl;
- this.self= self;
- }
-
- @Override
- public String toString() {
- return file.getName() + " " + check + " " + getMinPos(encl, self);
- }
-
- final JavaFileObject file;
- final String check;
- final Info encl;
- final Info self;
- }
- }
-}
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javah/T6893943.java Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6893943
+ * @summary exit code from javah with no args is 0
+ */
+
+import java.io.*;
+import java.util.*;
+
+public class T6893943 {
+ public static void main(String... args) throws Exception {
+ new T6893943().run();
+ }
+
+ void run() throws Exception {
+ testSimpleAPI();
+ testCommand();
+ }
+
+ void testSimpleAPI() throws Exception {
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.err));
+ int rc = com.sun.tools.javah.Main.run(new String[] { }, pw);
+ expect("testSimpleAPI", rc, 1);
+ }
+
+ void testCommand() throws Exception {
+ File javaHome = new File(System.getProperty("java.home"));
+ if (javaHome.getName().equals("jre"))
+ javaHome = javaHome.getParentFile();
+
+ List<String> command = new ArrayList<String>();
+ command.add(new File(new File(javaHome, "bin"), "javah").getPath());
+ command.add("-J-Xbootclasspath:" + System.getProperty("sun.boot.class.path"));
+ //System.err.println("command: " + command);
+
+ ProcessBuilder pb = new ProcessBuilder(command);
+ pb.redirectErrorStream(true);
+ Process p = pb.start();
+ p.getOutputStream().close();
+ String line;
+ BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ while ((line = in.readLine()) != null)
+ System.err.println("javah: " + line);
+ int rc = p.waitFor();
+ expect("testCommand", rc, 1);
+ }
+
+ void expect(String name, int actual, int expect) throws Exception {
+ if (actual != expect)
+ throw new Exception(name + ": unexpected exit: " + actual + ", expected: " + expect);
+ }
+}
--- a/make/jprt.properties Wed Mar 17 12:48:21 2010 +0300
+++ b/make/jprt.properties Wed Mar 17 14:19:07 2010 -0700
@@ -1,5 +1,5 @@
#
-# Copyright 2006-2009 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2006-2010 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -27,15 +27,15 @@
jprt.tools.default.release=jdk1.7.0
# Specific platform list
-jprt.build.platforms=\
-solaris_sparc_5.10,\
-solaris_sparcv9_5.10,\
-solaris_i586_5.10,\
-solaris_x64_5.10,\
-linux_i586_2.6,\
-linux_x64_2.6,\
-windows_i586,\
-windows_x64
+jprt.build.platforms= \
+ solaris_sparc_5.10, \
+ solaris_sparcv9_5.10, \
+ solaris_i586_5.10, \
+ solaris_x64_5.10, \
+ linux_i586_2.6, \
+ linux_x64_2.6, \
+ windows_i586_5.0, \
+ windows_x64_5.2
# The different build flavors we want
jprt.build.flavors=product,fastdebug
@@ -51,6 +51,44 @@
jprt.solaris_sparcv9.build.platform.match32=solaris_sparc_5.10
jprt.solaris_x64.build.platform.match32=solaris_i586_5.10
-# Standard list of jprt test targets for this workspace
-jprt.test.targets=*-*-*-jvm98
+# Shortened list of vm tests
+jprt.test.targets= \
+ *-product-*-jvm98, \
+ *-product-*-scimark, \
+ *-product-*-runThese, \
+ *-product-*-GCBasher_default, \
+ *-product-*-GCOld_default, \
+ *-product-*-jbb_default
+# Test targets in test/Makefile
+jprt.make.rule.test.targets= \
+ *-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
+
+# Not Ready Yet:
+# *-product-*-langtools_all
+# *-product-*-jdk_awt
+# *-product-*-jdk_rmi
+# *-product-*-jdk_swing
+
+# Directories to be excluded from source bundles
+jprt.bundle.exclude.src.dirs=build dist webrev
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/Makefile Wed Mar 17 14:19:07 2010 -0700
@@ -0,0 +1,89 @@
+#
+# Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+#
+# Makefile to run tests from multiple sibling directories
+#
+
+# Root of the forest that was built
+TOPDIR=..
+
+# This makefile depends on the availability of sibling directories.
+LANGTOOLS_DIR=$(TOPDIR)/langtools
+JDK_DIR=$(TOPDIR)/jdk
+
+# Macro to run a test target in a subdir
+define SUBDIR_TEST # subdirectory target
+if [ -d $1 ] ; then \
+ if [ -r $1/test/Makefile ] ; then \
+ echo "$(MAKE) -C $1/test $2" ; \
+ $(MAKE) -C $1/test $2 ; \
+ else \
+ echo "ERROR: File does not exist: $1/test/Makefile"; \
+ fi; \
+else \
+ echo "WARNING: No testing done, directory does not exist: $1"; \
+fi
+endef
+
+# Test target list for langtools repository
+LANGTOOLS_TEST_LIST = langtools_all
+
+# Test target list for jdk repository
+JDK_TEST_LIST = \
+ jdk_awt \
+ jdk_beans jdk_beans1 jdk_beans2 jdk_beans3 \
+ jdk_io \
+ jdk_lang \
+ jdk_management jdk_management1 jdk_management2 \
+ jdk_math \
+ jdk_misc \
+ jdk_net \
+ jdk_nio jdk_nio1 jdk_nio2 jdk_nio3 \
+ jdk_rmi \
+ jdk_security jdk_security1 jdk_security2 jdk_security3 \
+ jdk_swing \
+ jdk_text \
+ jdk_tools jdk_tools1 jdk_tools2 \
+ jdk_util
+
+# Default test target (everything)
+all: $(JDK_TEST_LIST) $(LANGTOOLS_TEST_LIST)
+
+# Test targets
+$(LANGTOOLS_TEST_LIST):
+ @$(call SUBDIR_TEST, $(LANGTOOLS_DIR), all)
+$(JDK_TEST_LIST):
+ @$(call SUBDIR_TEST, $(JDK_DIR), $@)
+
+clean:
+
+################################################################
+
+# Phony targets (e.g. these are not filenames)
+.PHONY: all clean $(JDK_TEST_LIST) $(LANGTOOLS_TEST_LIST)
+
+################################################################
+