提交 2419285b 编写于 作者: M mduigou

Merge

...@@ -108,3 +108,4 @@ bdc069d3f9101f89ec3f81c2950ee2d68fa846d3 jdk7-b130 ...@@ -108,3 +108,4 @@ bdc069d3f9101f89ec3f81c2950ee2d68fa846d3 jdk7-b130
8ac52c85f9e91336dc00b52ef90b42eecf3230b3 jdk7-b131 8ac52c85f9e91336dc00b52ef90b42eecf3230b3 jdk7-b131
6bbc7a4734952ae7604578f270e1566639fa8752 jdk7-b132 6bbc7a4734952ae7604578f270e1566639fa8752 jdk7-b132
5e5f68a01d12a4432172f384d5201f3a05254493 jdk7-b133 5e5f68a01d12a4432172f384d5201f3a05254493 jdk7-b133
554adcfb615e63e62af530b1c10fcf7813a75b26 jdk7-b134
...@@ -118,8 +118,11 @@ DEMO_ALL_NATIVE_SOURCES += $(filter %.h,$(DEMO_ALL_FILES)) ...@@ -118,8 +118,11 @@ DEMO_ALL_NATIVE_SOURCES += $(filter %.h,$(DEMO_ALL_FILES))
DEMO_ALL_NATIVE_SOURCES += $(filter %.hpp,$(DEMO_ALL_FILES)) DEMO_ALL_NATIVE_SOURCES += $(filter %.hpp,$(DEMO_ALL_FILES))
# If we have java sources, then define the jar file we will create # If we have java sources, then define the jar file we will create
ifndef DEMO_JAR_NAME
DEMO_JAR_NAME = $(DEMONAME).jar
endif
ifneq ($(strip $(DEMO_JAVA_SOURCES)),) ifneq ($(strip $(DEMO_JAVA_SOURCES)),)
DEMO_JAR = $(DEMO_DESTDIR)/$(DEMONAME).jar DEMO_JAR = $(DEMO_DESTDIR)/$(DEMO_JAR_NAME)
endif endif
# If we have native sources, define the native library we will create # If we have native sources, define the native library we will create
...@@ -252,6 +255,17 @@ $(DEMO_JAR): \ ...@@ -252,6 +255,17 @@ $(DEMO_JAR): \
$(MKDIR) -p $(DEMO_JAR_IMAGE) $(MKDIR) -p $(DEMO_JAR_IMAGE)
$(JAVAC_CMD) -d $(DEMO_JAR_IMAGE) -sourcepath $(DEMO_BUILD_SRCDIR) \ $(JAVAC_CMD) -d $(DEMO_JAR_IMAGE) -sourcepath $(DEMO_BUILD_SRCDIR) \
@$(DEMO_JAVAC_INPUT) @$(DEMO_JAVAC_INPUT)
ifeq ($(DEMO_INCL_SRC),true)
$(CP) $(DEMO_JAVA_SOURCES:%=$(DEMO_BUILD_SRCDIR)/%) $(DEMO_JAR_IMAGE)
endif
ifeq ($(DEMO_ONLY_SRC),true)
$(RM) -r $(DEMO_JAR_IMAGE)
$(MKDIR) -p $(DEMO_JAR_IMAGE)
$(CP) -r $(DEMO_BUILD_SRCDIR)/* $(DEMO_JAR_IMAGE)
ifneq ($(DEMO_TOPFILES),)
$(CP) $(DEMO_ROOT)/$(DEMO_TOPFILES) $(DEMO_JAR_IMAGE)
endif
endif
$(BOOT_JAR_CMD) -cfm $@ $(DEMO_MANIFEST) \ $(BOOT_JAR_CMD) -cfm $@ $(DEMO_MANIFEST) \
-C $(DEMO_JAR_IMAGE) . \ -C $(DEMO_JAR_IMAGE) . \
$(BOOT_JAR_JFLAGS) $(BOOT_JAR_JFLAGS)
...@@ -324,9 +338,9 @@ bundles: $(DEMO_BUILD_SRCZIP) ...@@ -324,9 +338,9 @@ bundles: $(DEMO_BUILD_SRCZIP)
ifdef DEMO_IS_APPLET ifdef DEMO_IS_APPLET
@$(ECHO) "Expanding jar file into demos area at $(DEMO_DESTDIR)" @$(ECHO) "Expanding jar file into demos area at $(DEMO_DESTDIR)"
( $(CD) $(DEMO_DESTDIR) && \ ( $(CD) $(DEMO_DESTDIR) && \
$(BOOT_JAR_CMD) -xfv $(DEMONAME).jar \ $(BOOT_JAR_CMD) -xfv $(DEMO_JAR_NAME) \
$(BOOT_JAR_JFLAGS) && \ $(BOOT_JAR_JFLAGS) && \
$(RM) -r META-INF $(DEMONAME).jar && \ $(RM) -r META-INF $(DEMO_JAR_NAME) && \
$(java-vm-cleanup) ) $(java-vm-cleanup) )
@( $(CD) $(DEMO_DESTDIR) && $(java-vm-cleanup) ) @( $(CD) $(DEMO_DESTDIR) && $(java-vm-cleanup) )
@$(ECHO) "Expanding source into demos area at $(DEMO_DESTDIR)" @$(ECHO) "Expanding source into demos area at $(DEMO_DESTDIR)"
......
...@@ -153,6 +153,9 @@ ifeq ($(PLATFORM), windows) ...@@ -153,6 +153,9 @@ ifeq ($(PLATFORM), windows)
ifndef COMPILER_VERSION ifndef COMPILER_VERSION
COMPILER_VERSION := $(error COMPILER_VERSION cannot be empty here) COMPILER_VERSION := $(error COMPILER_VERSION cannot be empty here)
endif endif
ifneq ($(COMPILER_VERSION),VS2010)
COMPILER_VERSION := $(error COMPILER_VERSION must be VS2010)
endif
# Shared library generation flag # Shared library generation flag
SHARED_LIBRARY_FLAG = -LD SHARED_LIBRARY_FLAG = -LD
......
...@@ -148,7 +148,7 @@ ifeq ($(SYSTEM_UNAME), SunOS) ...@@ -148,7 +148,7 @@ ifeq ($(SYSTEM_UNAME), SunOS)
# Suffix for file bundles used in previous release # Suffix for file bundles used in previous release
BUNDLE_FILE_SUFFIX=.tar BUNDLE_FILE_SUFFIX=.tar
# How much RAM does this machine have: # How much RAM does this machine have:
MB_OF_MEMORY=$(shell /etc/prtconf | fgrep 'Memory size:' | expand | cut -d' ' -f3) MB_OF_MEMORY=$(shell /usr/sbin/prtconf | fgrep 'Memory size:' | expand | cut -d' ' -f3)
endif endif
# Platform settings specific to Linux # Platform settings specific to Linux
......
...@@ -37,6 +37,7 @@ DEMO_TOPFILES = ./README.txt ...@@ -37,6 +37,7 @@ DEMO_TOPFILES = ./README.txt
DEMO_MAINCLASS = $(DEMONAME) DEMO_MAINCLASS = $(DEMONAME)
DEMO_MANIFEST_ATTR = SplashScreen-Image: resources/images/splash.png DEMO_MANIFEST_ATTR = SplashScreen-Image: resources/images/splash.png
DEMO_DESTDIR = $(DEMODIR)/jfc/$(DEMONAME) DEMO_DESTDIR = $(DEMODIR)/jfc/$(DEMONAME)
DEMO_INCL_SRC = true
# #
# Demo jar building rules. # Demo jar building rules.
......
...@@ -32,6 +32,8 @@ DEMO_ROOT = $(SHARE_SRC)/classes ...@@ -32,6 +32,8 @@ DEMO_ROOT = $(SHARE_SRC)/classes
DEMO_PKGDIR = com/sun/tools/example DEMO_PKGDIR = com/sun/tools/example
DEMO_TOPFILES = ./com/sun/tools/example/README DEMO_TOPFILES = ./com/sun/tools/example/README
DEMO_DESTDIR = $(DEMODIR)/jpda DEMO_DESTDIR = $(DEMODIR)/jpda
DEMO_JAR_NAME = examples.jar
DEMO_ONLY_SRC = true
# #
# Demo jar building rules. # Demo jar building rules.
......
Manifest-Version: 1.0 Manifest-Version: 1.0
Specification-Title: Java Platform API Specification Specification-Title: Java Platform API Specification
Specification-Version: 1.6 Specification-Version: 1.7
Specification-Vendor: Oracle Specification-Vendor: Oracle
Implementation-Title: Java Runtime Environment Implementation-Title: Java Runtime Environment
Implementation-Version: @@RELEASE@@ Implementation-Version: @@RELEASE@@
......
...@@ -61,6 +61,9 @@ ...@@ -61,6 +61,9 @@
* interfaces. * interfaces.
*/ */
/* we always print to stderr */
#define USE_STDERR JNI_TRUE
static jboolean printVersion = JNI_FALSE; /* print and exit */ static jboolean printVersion = JNI_FALSE; /* print and exit */
static jboolean showVersion = JNI_FALSE; /* print but continue */ static jboolean showVersion = JNI_FALSE; /* print but continue */
static jboolean printUsage = JNI_FALSE; /* print and exit*/ static jboolean printUsage = JNI_FALSE; /* print and exit*/
...@@ -1136,36 +1139,18 @@ InitializeJVM(JavaVM **pvm, JNIEnv **penv, InvocationFunctions *ifn) ...@@ -1136,36 +1139,18 @@ InitializeJVM(JavaVM **pvm, JNIEnv **penv, InvocationFunctions *ifn)
return; \ return; \
} }
static jstring platformEncoding = NULL; static jclass helperClass = NULL;
static jstring getPlatformEncoding(JNIEnv *env) {
if (platformEncoding == NULL) {
jstring propname = (*env)->NewStringUTF(env, "sun.jnu.encoding");
if (propname) {
jclass cls;
jmethodID mid;
NULL_CHECK0 (cls = FindBootStrapClass(env, "java/lang/System"));
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
env, cls,
"getProperty",
"(Ljava/lang/String;)Ljava/lang/String;"));
platformEncoding = (*env)->CallStaticObjectMethod (
env, cls, mid, propname);
}
}
return platformEncoding;
}
static jboolean isEncodingSupported(JNIEnv *env, jstring enc) { static jclass
jclass cls; GetLauncherHelperClass(JNIEnv *env) {
jmethodID mid; if (helperClass == NULL) {
NULL_CHECK0 (cls = FindBootStrapClass(env, "java/nio/charset/Charset")); NULL_CHECK0(helperClass = FindBootStrapClass(env,
NULL_CHECK0 (mid = (*env)->GetStaticMethodID( "sun/launcher/LauncherHelper"));
env, cls, }
"isSupported", return helperClass;
"(Ljava/lang/String;)Z"));
return (*env)->CallStaticBooleanMethod(env, cls, mid, enc);
} }
static jmethodID makePlatformStringMID = NULL;
/* /*
* Returns a new Java string object for the specified platform string. * Returns a new Java string object for the specified platform string.
*/ */
...@@ -1173,36 +1158,23 @@ static jstring ...@@ -1173,36 +1158,23 @@ static jstring
NewPlatformString(JNIEnv *env, char *s) NewPlatformString(JNIEnv *env, char *s)
{ {
int len = (int)JLI_StrLen(s); int len = (int)JLI_StrLen(s);
jclass cls;
jmethodID mid;
jbyteArray ary; jbyteArray ary;
jstring enc; jclass cls = GetLauncherHelperClass(env);
NULL_CHECK0(cls);
if (s == NULL) if (s == NULL)
return 0; return 0;
enc = getPlatformEncoding(env);
ary = (*env)->NewByteArray(env, len); ary = (*env)->NewByteArray(env, len);
if (ary != 0) { if (ary != 0) {
jstring str = 0; jstring str = 0;
(*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s); (*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s);
if (!(*env)->ExceptionOccurred(env)) { if (!(*env)->ExceptionOccurred(env)) {
NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String")); if (makePlatformStringMID == NULL) {
if (isEncodingSupported(env, enc) == JNI_TRUE) { NULL_CHECK0(makePlatformStringMID = (*env)->GetStaticMethodID(env,
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>", cls, "makePlatformString", "(Z[B)Ljava/lang/String;"));
"([BLjava/lang/String;)V"));
str = (*env)->NewObject(env, cls, mid, ary, enc);
} else {
/*If the encoding specified in sun.jnu.encoding is not
endorsed by "Charset.isSupported" we have to fall back
to use String(byte[]) explicitly here without specifying
the encoding name, in which the StringCoding class will
pickup the iso-8859-1 as the fallback converter for us.
*/
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"([B)V"));
str = (*env)->NewObject(env, cls, mid, ary);
} }
str = (*env)->CallStaticObjectMethod(env, cls,
makePlatformStringMID, USE_STDERR, ary);
(*env)->DeleteLocalRef(env, ary); (*env)->DeleteLocalRef(env, ary);
return str; return str;
} }
...@@ -1239,20 +1211,28 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc) ...@@ -1239,20 +1211,28 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
static jclass static jclass
LoadMainClass(JNIEnv *env, int mode, char *name) LoadMainClass(JNIEnv *env, int mode, char *name)
{ {
jclass cls;
jmethodID mid; jmethodID mid;
jstring str; jstring str;
jobject result; jobject result;
jlong start, end; jlong start, end;
jclass cls = GetLauncherHelperClass(env);
NULL_CHECK0(cls);
if (JLI_IsTraceLauncher()) { if (JLI_IsTraceLauncher()) {
start = CounterGet(); start = CounterGet();
} }
NULL_CHECK0(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper")); NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,
NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls, "checkAndLoadMain", "checkAndLoadMain",
"(ZILjava/lang/String;)Ljava/lang/Class;")); "(ZILjava/lang/String;)Ljava/lang/Class;"));
str = (*env)->NewStringUTF(env, name);
result = (*env)->CallStaticObjectMethod(env, cls, mid, JNI_TRUE, mode, str); switch (mode) {
case LM_CLASS:
str = NewPlatformString(env, name);
break;
default:
str = (*env)->NewStringUTF(env, name);
break;
}
result = (*env)->CallStaticObjectMethod(env, cls, mid, USE_STDERR, mode, str);
if (JLI_IsTraceLauncher()) { if (JLI_IsTraceLauncher()) {
end = CounterGet(); end = CounterGet();
...@@ -1478,15 +1458,15 @@ PrintJavaVersion(JNIEnv *env, jboolean extraLF) ...@@ -1478,15 +1458,15 @@ PrintJavaVersion(JNIEnv *env, jboolean extraLF)
static void static void
ShowSettings(JNIEnv *env, char *optString) ShowSettings(JNIEnv *env, char *optString)
{ {
jclass cls;
jmethodID showSettingsID; jmethodID showSettingsID;
jstring joptString; jstring joptString;
NULL_CHECK(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper")); jclass cls = GetLauncherHelperClass(env);
NULL_CHECK(cls);
NULL_CHECK(showSettingsID = (*env)->GetStaticMethodID(env, cls, NULL_CHECK(showSettingsID = (*env)->GetStaticMethodID(env, cls,
"showSettings", "(ZLjava/lang/String;JJJZ)V")); "showSettings", "(ZLjava/lang/String;JJJZ)V"));
joptString = (*env)->NewStringUTF(env, optString); joptString = (*env)->NewStringUTF(env, optString);
(*env)->CallStaticVoidMethod(env, cls, showSettingsID, (*env)->CallStaticVoidMethod(env, cls, showSettingsID,
JNI_TRUE, USE_STDERR,
joptString, joptString,
(jlong)initialHeapSize, (jlong)initialHeapSize,
(jlong)maxHeapSize, (jlong)maxHeapSize,
...@@ -1500,18 +1480,15 @@ ShowSettings(JNIEnv *env, char *optString) ...@@ -1500,18 +1480,15 @@ ShowSettings(JNIEnv *env, char *optString)
static void static void
PrintUsage(JNIEnv* env, jboolean doXUsage) PrintUsage(JNIEnv* env, jboolean doXUsage)
{ {
jclass cls;
jmethodID initHelp, vmSelect, vmSynonym, vmErgo, printHelp, printXUsageMessage; jmethodID initHelp, vmSelect, vmSynonym, vmErgo, printHelp, printXUsageMessage;
jstring jprogname, vm1, vm2; jstring jprogname, vm1, vm2;
int i; int i;
jclass cls = GetLauncherHelperClass(env);
NULL_CHECK(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper")); NULL_CHECK(cls);
if (doXUsage) { if (doXUsage) {
NULL_CHECK(printXUsageMessage = (*env)->GetStaticMethodID(env, cls, NULL_CHECK(printXUsageMessage = (*env)->GetStaticMethodID(env, cls,
"printXUsageMessage", "(Z)V")); "printXUsageMessage", "(Z)V"));
(*env)->CallStaticVoidMethod(env, cls, printXUsageMessage, JNI_TRUE); (*env)->CallStaticVoidMethod(env, cls, printXUsageMessage, USE_STDERR);
} else { } else {
NULL_CHECK(initHelp = (*env)->GetStaticMethodID(env, cls, NULL_CHECK(initHelp = (*env)->GetStaticMethodID(env, cls,
"initHelpMessage", "(Ljava/lang/String;)V")); "initHelpMessage", "(Ljava/lang/String;)V"));
...@@ -1570,7 +1547,7 @@ PrintUsage(JNIEnv* env, jboolean doXUsage) ...@@ -1570,7 +1547,7 @@ PrintUsage(JNIEnv* env, jboolean doXUsage)
} }
/* Complete the usage message and print to stderr*/ /* Complete the usage message and print to stderr*/
(*env)->CallStaticVoidMethod(env, cls, printHelp, JNI_TRUE); (*env)->CallStaticVoidMethod(env, cls, printHelp, USE_STDERR);
} }
return; return;
} }
......
...@@ -743,24 +743,24 @@ class BandStructure { ...@@ -743,24 +743,24 @@ class BandStructure {
private void dumpBand() throws IOException { private void dumpBand() throws IOException {
assert(optDumpBands); assert(optDumpBands);
PrintStream ps = new PrintStream(getDumpStream(this, ".txt")); try (PrintStream ps = new PrintStream(getDumpStream(this, ".txt"))) {
String irr = (bandCoding == regularCoding) ? "" : " irregular"; String irr = (bandCoding == regularCoding) ? "" : " irregular";
ps.print("# length="+length+ ps.print("# length="+length+
" size="+outputSize()+ " size="+outputSize()+
irr+" coding="+bandCoding); irr+" coding="+bandCoding);
if (metaCoding != noMetaCoding) { if (metaCoding != noMetaCoding) {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
for (int i = 0; i < metaCoding.length; i++) { for (int i = 0; i < metaCoding.length; i++) {
if (i == 1) sb.append(" /"); if (i == 1) sb.append(" /");
sb.append(" ").append(metaCoding[i] & 0xFF); sb.append(" ").append(metaCoding[i] & 0xFF);
}
ps.print(" //header: "+sb);
} }
ps.print(" //header: "+sb); printArrayTo(ps, values, 0, length);
}
try (OutputStream ds = getDumpStream(this, ".bnd")) {
bandCoding.writeArrayTo(ds, values, 0, length);
} }
printArrayTo(ps, values, 0, length);
ps.close();
OutputStream ds = getDumpStream(this, ".bnd");
bandCoding.writeArrayTo(ds, values, 0, length);
ds.close();
} }
/** Disburse one value. */ /** Disburse one value. */
...@@ -829,12 +829,12 @@ class BandStructure { ...@@ -829,12 +829,12 @@ class BandStructure {
private void dumpBand() throws IOException { private void dumpBand() throws IOException {
assert(optDumpBands); assert(optDumpBands);
OutputStream ds = getDumpStream(this, ".bnd"); try (OutputStream ds = getDumpStream(this, ".bnd")) {
if (bytesForDump != null) if (bytesForDump != null)
bytesForDump.writeTo(ds); bytesForDump.writeTo(ds);
else else
bytes.writeTo(ds); bytes.writeTo(ds);
ds.close(); }
} }
public void readDataFrom(InputStream in) throws IOException { public void readDataFrom(InputStream in) throws IOException {
......
...@@ -150,12 +150,12 @@ class Driver { ...@@ -150,12 +150,12 @@ class Driver {
// See if there is any other action to take. // See if there is any other action to take.
if ("--config-file=".equals(state)) { if ("--config-file=".equals(state)) {
String propFile = av.remove(0); String propFile = av.remove(0);
InputStream propIn = new FileInputStream(propFile);
Properties fileProps = new Properties(); Properties fileProps = new Properties();
fileProps.load(new BufferedInputStream(propIn)); try (InputStream propIn = new FileInputStream(propFile)) {
fileProps.load(propIn);
}
if (engProps.get(verboseProp) != null) if (engProps.get(verboseProp) != null)
fileProps.list(System.out); fileProps.list(System.out);
propIn.close();
for (Map.Entry<Object,Object> me : fileProps.entrySet()) { for (Map.Entry<Object,Object> me : fileProps.entrySet()) {
engProps.put((String) me.getKey(), (String) me.getValue()); engProps.put((String) me.getKey(), (String) me.getValue());
} }
...@@ -348,10 +348,10 @@ class Driver { ...@@ -348,10 +348,10 @@ class Driver {
else else
fileOut = new FileOutputStream(outfile); fileOut = new FileOutputStream(outfile);
fileOut = new BufferedOutputStream(fileOut); fileOut = new BufferedOutputStream(fileOut);
JarOutputStream out = new JarOutputStream(fileOut); try (JarOutputStream out = new JarOutputStream(fileOut)) {
junpack.unpack(in, out); junpack.unpack(in, out);
//in.close(); // p200 closes in but not out // p200 closes in but not out
out.close(); }
// At this point, we have a good jarfile (or newfile, if -r) // At this point, we have a good jarfile (or newfile, if -r)
} }
...@@ -411,8 +411,7 @@ class Driver { ...@@ -411,8 +411,7 @@ class Driver {
long filelen = new File(jarfile).length(); long filelen = new File(jarfile).length();
if (filelen <= 0) return ""; if (filelen <= 0) return "";
long skiplen = Math.max(0, filelen - tail.length); long skiplen = Math.max(0, filelen - tail.length);
InputStream in = new FileInputStream(new File(jarfile)); try (InputStream in = new FileInputStream(new File(jarfile))) {
try {
in.skip(skiplen); in.skip(skiplen);
in.read(tail); in.read(tail);
for (int i = tail.length-4; i >= 0; i--) { for (int i = tail.length-4; i >= 0; i--) {
...@@ -426,8 +425,6 @@ class Driver { ...@@ -426,8 +425,6 @@ class Driver {
} }
} }
return ""; return "";
} finally {
in.close();
} }
} }
......
...@@ -241,9 +241,9 @@ class NativeUnpack { ...@@ -241,9 +241,9 @@ class NativeUnpack {
void run(File inFile, JarOutputStream jstream) throws IOException { void run(File inFile, JarOutputStream jstream) throws IOException {
// %%% maybe memory-map the file, and pass it straight into unpacker // %%% maybe memory-map the file, and pass it straight into unpacker
ByteBuffer mappedFile = null; ByteBuffer mappedFile = null;
FileInputStream fis = new FileInputStream(inFile); try (FileInputStream fis = new FileInputStream(inFile)) {
run(fis, jstream, mappedFile); run(fis, jstream, mappedFile);
fis.close(); }
// Note: caller is responsible to finish with jstream. // Note: caller is responsible to finish with jstream.
} }
......
...@@ -540,9 +540,9 @@ class PackageReader extends BandStructure { ...@@ -540,9 +540,9 @@ class PackageReader extends BandStructure {
Index index = initCPIndex(tag, cpMap); Index index = initCPIndex(tag, cpMap);
if (optDumpBands) { if (optDumpBands) {
PrintStream ps = new PrintStream(getDumpStream(index, ".idx")); try (PrintStream ps = new PrintStream(getDumpStream(index, ".idx"))) {
printArrayTo(ps, index.cpMap, 0, index.cpMap.length); printArrayTo(ps, index.cpMap, 0, index.cpMap.length);
ps.close(); }
} }
} }
...@@ -828,26 +828,27 @@ class PackageReader extends BandStructure { ...@@ -828,26 +828,27 @@ class PackageReader extends BandStructure {
attr_definition_headers.readFrom(in); attr_definition_headers.readFrom(in);
attr_definition_name.readFrom(in); attr_definition_name.readFrom(in);
attr_definition_layout.readFrom(in); attr_definition_layout.readFrom(in);
PrintStream dump = !optDumpBands ? null try (PrintStream dump = !optDumpBands ? null
: new PrintStream(getDumpStream(attr_definition_headers, ".def")); : new PrintStream(getDumpStream(attr_definition_headers, ".def")))
for (int i = 0; i < numAttrDefs; i++) { {
int header = attr_definition_headers.getByte(); for (int i = 0; i < numAttrDefs; i++) {
Utf8Entry name = (Utf8Entry) attr_definition_name.getRef(); int header = attr_definition_headers.getByte();
Utf8Entry layout = (Utf8Entry) attr_definition_layout.getRef(); Utf8Entry name = (Utf8Entry) attr_definition_name.getRef();
int ctype = (header & ADH_CONTEXT_MASK); Utf8Entry layout = (Utf8Entry) attr_definition_layout.getRef();
int index = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB; int ctype = (header & ADH_CONTEXT_MASK);
Attribute.Layout def = new Attribute.Layout(ctype, int index = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB;
name.stringValue(), Attribute.Layout def = new Attribute.Layout(ctype,
layout.stringValue()); name.stringValue(),
// Check layout string for Java 6 extensions. layout.stringValue());
String pvLayout = def.layoutForPackageMajver(getPackageMajver()); // Check layout string for Java 6 extensions.
if (!pvLayout.equals(def.layout())) { String pvLayout = def.layoutForPackageMajver(getPackageMajver());
throw new IOException("Bad attribute layout in version 150 archive: "+def.layout()); if (!pvLayout.equals(def.layout())) {
throw new IOException("Bad attribute layout in version 150 archive: "+def.layout());
}
this.setAttributeLayoutIndex(def, index);
if (dump != null) dump.println(index+" "+def);
} }
this.setAttributeLayoutIndex(def, index);
if (dump != null) dump.println(index+" "+def);
} }
if (dump != null) dump.close();
attr_definition_headers.doneDisbursing(); attr_definition_headers.doneDisbursing();
attr_definition_name.doneDisbursing(); attr_definition_name.doneDisbursing();
attr_definition_layout.doneDisbursing(); attr_definition_layout.doneDisbursing();
......
...@@ -458,9 +458,9 @@ class PackageWriter extends BandStructure { ...@@ -458,9 +458,9 @@ class PackageWriter extends BandStructure {
Utils.log.info("Writing "+cpMap.length+" "+ConstantPool.tagName(tag)+" entries..."); Utils.log.info("Writing "+cpMap.length+" "+ConstantPool.tagName(tag)+" entries...");
if (optDumpBands) { if (optDumpBands) {
PrintStream ps = new PrintStream(getDumpStream(index, ".idx")); try (PrintStream ps = new PrintStream(getDumpStream(index, ".idx"))) {
printArrayTo(ps, cpMap, 0, cpMap.length); printArrayTo(ps, cpMap, 0, cpMap.length);
ps.close(); }
} }
switch (tag) { switch (tag) {
...@@ -923,33 +923,34 @@ class PackageWriter extends BandStructure { ...@@ -923,33 +923,34 @@ class PackageWriter extends BandStructure {
} }
}); });
attrDefsWritten = new Attribute.Layout[numAttrDefs]; attrDefsWritten = new Attribute.Layout[numAttrDefs];
PrintStream dump = !optDumpBands ? null try (PrintStream dump = !optDumpBands ? null
: new PrintStream(getDumpStream(attr_definition_headers, ".def")); : new PrintStream(getDumpStream(attr_definition_headers, ".def")))
int[] indexForDebug = Arrays.copyOf(attrIndexLimit, ATTR_CONTEXT_LIMIT); {
for (int i = 0; i < defs.length; i++) { int[] indexForDebug = Arrays.copyOf(attrIndexLimit, ATTR_CONTEXT_LIMIT);
int header = ((Integer)defs[i][0]).intValue(); for (int i = 0; i < defs.length; i++) {
Attribute.Layout def = (Attribute.Layout) defs[i][1]; int header = ((Integer)defs[i][0]).intValue();
attrDefsWritten[i] = def; Attribute.Layout def = (Attribute.Layout) defs[i][1];
assert((header & ADH_CONTEXT_MASK) == def.ctype()); attrDefsWritten[i] = def;
attr_definition_headers.putByte(header); assert((header & ADH_CONTEXT_MASK) == def.ctype());
attr_definition_name.putRef(ConstantPool.getUtf8Entry(def.name())); attr_definition_headers.putByte(header);
String layout = def.layoutForPackageMajver(getPackageMajver()); attr_definition_name.putRef(ConstantPool.getUtf8Entry(def.name()));
attr_definition_layout.putRef(ConstantPool.getUtf8Entry(layout)); String layout = def.layoutForPackageMajver(getPackageMajver());
// Check that we are transmitting that correct attribute index: attr_definition_layout.putRef(ConstantPool.getUtf8Entry(layout));
boolean debug = false; // Check that we are transmitting that correct attribute index:
assert(debug = true); boolean debug = false;
if (debug) { assert(debug = true);
int hdrIndex = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB; if (debug) {
if (hdrIndex < 0) hdrIndex = indexForDebug[def.ctype()]++; int hdrIndex = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB;
int realIndex = (attrIndexTable.get(def)).intValue(); if (hdrIndex < 0) hdrIndex = indexForDebug[def.ctype()]++;
assert(hdrIndex == realIndex); int realIndex = (attrIndexTable.get(def)).intValue();
} assert(hdrIndex == realIndex);
if (dump != null) { }
int index = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB; if (dump != null) {
dump.println(index+" "+def); int index = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB;
dump.println(index+" "+def);
}
} }
} }
if (dump != null) dump.close();
} }
void writeAttrCounts() throws IOException { void writeAttrCounts() throws IOException {
......
...@@ -122,26 +122,23 @@ final class PropMap implements SortedMap<Object, Object> { ...@@ -122,26 +122,23 @@ final class PropMap implements SortedMap<Object, Object> {
// Define certain attribute layouts by default. // Define certain attribute layouts by default.
// Do this after the previous props are put in place, // Do this after the previous props are put in place,
// to allow override if necessary. // to allow override if necessary.
InputStream propStr = null; String propFile = "intrinsic.properties";
try {
String propFile = "intrinsic.properties"; try (InputStream propStr = PackerImpl.class.getResourceAsStream(propFile)) {
propStr = PackerImpl.class.getResourceAsStream(propFile); if (propStr == null) {
props.load(new BufferedInputStream(propStr)); throw new RuntimeException(propFile + " cannot be loaded");
for (Map.Entry<Object, Object> e : props.entrySet()) {
String key = (String) e.getKey();
String val = (String) e.getValue();
if (key.startsWith("attribute.")) {
e.setValue(Attribute.normalizeLayoutString(val));
}
} }
props.load(propStr);
} catch (IOException ee) { } catch (IOException ee) {
throw new RuntimeException(ee); throw new RuntimeException(ee);
} finally { }
try {
if (propStr != null) { for (Map.Entry<Object, Object> e : props.entrySet()) {
propStr.close(); String key = (String) e.getKey();
} String val = (String) e.getValue();
} catch (IOException ignore) {} if (key.startsWith("attribute.")) {
e.setValue(Attribute.normalizeLayoutString(val));
}
} }
defaultProps = (new HashMap<>(props)); // shrink to fit defaultProps = (new HashMap<>(props)); // shrink to fit
......
...@@ -161,8 +161,9 @@ public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker { ...@@ -161,8 +161,9 @@ public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker {
} }
// Use the stream-based implementation. // Use the stream-based implementation.
// %%% Reconsider if native unpacker learns to memory-map the file. // %%% Reconsider if native unpacker learns to memory-map the file.
FileInputStream instr = new FileInputStream(in); try (FileInputStream instr = new FileInputStream(in)) {
unpack(instr, out); unpack(instr, out);
}
if (props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) { if (props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) {
in.delete(); in.delete();
} }
......
...@@ -268,18 +268,18 @@ class Utils { ...@@ -268,18 +268,18 @@ class Utils {
// 4947205 : Peformance is slow when using pack-effort=0 // 4947205 : Peformance is slow when using pack-effort=0
out = new BufferedOutputStream(out); out = new BufferedOutputStream(out);
out = new NonCloser(out); // protect from JarOutputStream.close() out = new NonCloser(out); // protect from JarOutputStream.close()
JarOutputStream jout = new JarOutputStream(out); try (JarOutputStream jout = new JarOutputStream(out)) {
copyJarFile(in, jout); copyJarFile(in, jout);
jout.close(); }
} }
static void copyJarFile(JarFile in, OutputStream out) throws IOException { static void copyJarFile(JarFile in, OutputStream out) throws IOException {
// 4947205 : Peformance is slow when using pack-effort=0 // 4947205 : Peformance is slow when using pack-effort=0
out = new BufferedOutputStream(out); out = new BufferedOutputStream(out);
out = new NonCloser(out); // protect from JarOutputStream.close() out = new NonCloser(out); // protect from JarOutputStream.close()
JarOutputStream jout = new JarOutputStream(out); try (JarOutputStream jout = new JarOutputStream(out)) {
copyJarFile(in, jout); copyJarFile(in, jout);
jout.close(); }
} }
// Wrapper to prevent closing of client-supplied stream. // Wrapper to prevent closing of client-supplied stream.
static private static private
......
...@@ -1712,10 +1712,10 @@ public final class Files { ...@@ -1712,10 +1712,10 @@ public final class Files {
* @return the {@code path} parameter * @return the {@code path} parameter
* *
* @throws UnsupportedOperationException * @throws UnsupportedOperationException
* if the attribute view is not available or it does not support * if the attribute view is not available
* updating the attribute
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if the attribute value is of the correct type but has an * if the attribute name is not specified, or is not recognized, or
* the attribute value is of the correct type but has an
* inappropriate value * inappropriate value
* @throws ClassCastException * @throws ClassCastException
* if the attribute value is not of the expected type or is a * if the attribute value is not of the expected type or is a
...@@ -1776,9 +1776,12 @@ public final class Files { ...@@ -1776,9 +1776,12 @@ public final class Files {
* @param options * @param options
* options indicating how symbolic links are handled * options indicating how symbolic links are handled
* *
* @return the attribute value or {@code null} if the attribute view * @return the attribute value
* is not available or it does not support reading the attribute
* *
* @throws UnsupportedOperationException
* if the attribute view is not available
* @throws IllegalArgumentException
* if the attribute name is not specified or is not recognized
* @throws IOException * @throws IOException
* if an I/O error occurs * if an I/O error occurs
* @throws SecurityException * @throws SecurityException
...@@ -1794,8 +1797,9 @@ public final class Files { ...@@ -1794,8 +1797,9 @@ public final class Files {
{ {
// only one attribute should be read // only one attribute should be read
if (attribute.indexOf('*') >= 0 || attribute.indexOf(',') >= 0) if (attribute.indexOf('*') >= 0 || attribute.indexOf(',') >= 0)
return null; throw new IllegalArgumentException(attribute);
Map<String,Object> map = readAttributes(path, attribute, options); Map<String,Object> map = readAttributes(path, attribute, options);
assert map.size() == 1;
String name; String name;
int pos = attribute.indexOf(':'); int pos = attribute.indexOf(':');
if (pos == -1) { if (pos == -1) {
...@@ -1868,9 +1872,14 @@ public final class Files { ...@@ -1868,9 +1872,14 @@ public final class Files {
* @param options * @param options
* options indicating how symbolic links are handled * options indicating how symbolic links are handled
* *
* @return a map of the attributes returned; may be empty. The map's keys * @return a map of the attributes returned; The map's keys are the
* are the attribute names, its values are the attribute values * attribute names, its values are the attribute values
* *
* @throws UnsupportedOperationException
* if the attribute view is not available
* @throws IllegalArgumentException
* if no attributes are specified or an unrecognized attributes is
* specified
* @throws IOException * @throws IOException
* if an I/O error occurs * if an I/O error occurs
* @throws SecurityException * @throws SecurityException
......
...@@ -228,6 +228,9 @@ public interface Path ...@@ -228,6 +228,9 @@ public interface Path
* not have a root component and the given path has a root component then * not have a root component and the given path has a root component then
* this path does not start with the given path. * this path does not start with the given path.
* *
* <p> If the given path is associated with a different {@code FileSystem}
* to this path then {@code false} is returned.
*
* @param other * @param other
* the given path * the given path
* *
...@@ -270,6 +273,9 @@ public interface Path ...@@ -270,6 +273,9 @@ public interface Path
* does not have a root component and the given path has a root component * does not have a root component and the given path has a root component
* then this path does not end with the given path. * then this path does not end with the given path.
* *
* <p> If the given path is associated with a different {@code FileSystem}
* to this path then {@code false} is returned.
*
* @param other * @param other
* the given path * the given path
* *
...@@ -283,7 +289,10 @@ public interface Path ...@@ -283,7 +289,10 @@ public interface Path
* the given path string, in exactly the manner specified by the {@link * the given path string, in exactly the manner specified by the {@link
* #endsWith(Path) endsWith(Path)} method. On UNIX for example, the path * #endsWith(Path) endsWith(Path)} method. On UNIX for example, the path
* "{@code foo/bar}" ends with "{@code foo/bar}" and "{@code bar}". It does * "{@code foo/bar}" ends with "{@code foo/bar}" and "{@code bar}". It does
* not end with "{@code r}" or "{@code /bar}". * not end with "{@code r}" or "{@code /bar}". Note that trailing separators
* are not taken into account, and so invoking this method on the {@code
* Path}"{@code foo/bar}" with the {@code String} "{@code bar/}" returns
* {@code true}.
* *
* @param other * @param other
* the given path string * the given path string
...@@ -724,12 +733,18 @@ public interface Path ...@@ -724,12 +733,18 @@ public interface Path
* provider, platform specific. This method does not access the file system * provider, platform specific. This method does not access the file system
* and neither file is required to exist. * and neither file is required to exist.
* *
* <p> This method may not be used to compare paths that are associated
* with different file system providers.
*
* @param other the path compared to this path. * @param other the path compared to this path.
* *
* @return zero if the argument is {@link #equals equal} to this path, a * @return zero if the argument is {@link #equals equal} to this path, a
* value less than zero if this path is lexicographically less than * value less than zero if this path is lexicographically less than
* the argument, or a value greater than zero if this path is * the argument, or a value greater than zero if this path is
* lexicographically greater than the argument * lexicographically greater than the argument
*
* @throws ClassCastException
* if the paths are associated with different providers
*/ */
@Override @Override
int compareTo(Path other); int compareTo(Path other);
...@@ -738,7 +753,7 @@ public interface Path ...@@ -738,7 +753,7 @@ public interface Path
* Tests this path for equality with the given object. * Tests this path for equality with the given object.
* *
* <p> If the given object is not a Path, or is a Path associated with a * <p> If the given object is not a Path, or is a Path associated with a
* different provider, then this method immediately returns {@code false}. * different {@code FileSystem}, then this method returns {@code false}.
* *
* <p> Whether or not two path are equal depends on the file system * <p> Whether or not two path are equal depends on the file system
* implementation. In some cases the paths are compared without regard * implementation. In some cases the paths are compared without regard
......
...@@ -146,5 +146,5 @@ public interface WatchKey { ...@@ -146,5 +146,5 @@ public interface WatchKey {
* *
* @return the object for which this watch key was created * @return the object for which this watch key was created
*/ */
//T watchable(); Watchable watchable();
} }
...@@ -216,12 +216,14 @@ public final class FileTime ...@@ -216,12 +216,14 @@ public final class FileTime
* "2009-02-13T23:31:30Z"}, and {@code FileTime.fromMillis(1234567890123L).toString()} * "2009-02-13T23:31:30Z"}, and {@code FileTime.fromMillis(1234567890123L).toString()}
* yields {@code "2009-02-13T23:31:30.123Z"}. * yields {@code "2009-02-13T23:31:30.123Z"}.
* *
* <p> A {@code FileTime} is primarly intended to represent the value of a * <p> A {@code FileTime} is primarily intended to represent the value of a
* file's time stamp. Where used to represent <i>extreme values</i>, where * file's time stamp. Where used to represent <i>extreme values</i>, where
* the year is less than "{@code 0001}" or greater than "{@code 9999}" then * the year is less than "{@code 0001}" or greater than "{@code 9999}" then
* the year may be expanded to more than four digits and may be * this method deviates from ISO 8601 in the same manner as the
* negative-signed. If more than four digits then leading zeros are not * <a href="http://www.w3.org/TR/xmlschema-2/#deviantformats">XML Schema
* present. The year before "{@code 0001}" is "{@code -0001}". * language</a>. That is, the year may be expanded to more than four digits
* and may be negative-signed. If more than four digits then leading zeros
* are not present. The year before "{@code 0001}" is "{@code -0001}".
* *
* @return the string representation of this file time * @return the string representation of this file time
*/ */
......
...@@ -1037,6 +1037,11 @@ public abstract class FileSystemProvider { ...@@ -1037,6 +1037,11 @@ public abstract class FileSystemProvider {
* @return a map of the attributes returned; may be empty. The map's keys * @return a map of the attributes returned; may be empty. The map's keys
* are the attribute names, its values are the attribute values * are the attribute names, its values are the attribute values
* *
* @throws UnsupportedOperationException
* if the attribute view is not available
* @throws IllegalArgumentException
* if no attributes are specified or an unrecognized attributes is
* specified
* @throws IOException * @throws IOException
* If an I/O error occurs * If an I/O error occurs
* @throws SecurityException * @throws SecurityException
...@@ -1064,10 +1069,10 @@ public abstract class FileSystemProvider { ...@@ -1064,10 +1069,10 @@ public abstract class FileSystemProvider {
* options indicating how symbolic links are handled * options indicating how symbolic links are handled
* *
* @throws UnsupportedOperationException * @throws UnsupportedOperationException
* if the attribute view is not available or it does not support * if the attribute view is not available
* updating the attribute
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if the attribute value is of the correct type but has an * if the attribute name is not specified, or is not recognized, or
* the attribute value is of the correct type but has an
* inappropriate value * inappropriate value
* @throws ClassCastException * @throws ClassCastException
* If the attribute value is not of the expected type or is a * If the attribute value is not of the expected type or is a
......
...@@ -42,10 +42,12 @@ package sun.launcher; ...@@ -42,10 +42,12 @@ package sun.launcher;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.nio.charset.Charset;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -471,11 +473,11 @@ public enum LauncherHelper { ...@@ -471,11 +473,11 @@ public enum LauncherHelper {
} catch (ClassNotFoundException cnfe) { } catch (ClassNotFoundException cnfe) {
abort(ostream, cnfe, "java.launcher.cls.error1", cn); abort(ostream, cnfe, "java.launcher.cls.error1", cn);
} }
signatureDiagnostic(ostream, c); getMainMethod(ostream, c);
return c; return c;
} }
static void signatureDiagnostic(PrintStream ostream, Class<?> clazz) { static Method getMainMethod(PrintStream ostream, Class<?> clazz) {
String classname = clazz.getName(); String classname = clazz.getName();
Method method = null; Method method = null;
try { try {
...@@ -495,6 +497,31 @@ public enum LauncherHelper { ...@@ -495,6 +497,31 @@ public enum LauncherHelper {
if (method.getReturnType() != java.lang.Void.TYPE) { if (method.getReturnType() != java.lang.Void.TYPE) {
abort(ostream, null, "java.launcher.cls.error3", classname); abort(ostream, null, "java.launcher.cls.error3", classname);
} }
return; return method;
}
private static final String encprop = "sun.jnu.encoding";
private static String encoding = null;
private static boolean isCharsetSupported = false;
/*
* converts a c or a byte array to a platform specific string,
* previously implemented as a native method in the launcher.
*/
static String makePlatformString(boolean printToStderr, byte[] inArray) {
final PrintStream ostream = (printToStderr) ? System.err : System.out;
if (encoding == null) {
encoding = System.getProperty(encprop);
isCharsetSupported = Charset.isSupported(encoding);
}
try {
String out = isCharsetSupported
? new String(inArray, encoding)
: new String(inArray);
return out;
} catch (UnsupportedEncodingException uee) {
abort(ostream, uee, null);
}
return null; // keep the compiler happy
} }
} }
...@@ -57,8 +57,8 @@ abstract class AbstractAclFileAttributeView ...@@ -57,8 +57,8 @@ abstract class AbstractAclFileAttributeView
setAcl((List<AclEntry>)value); setAcl((List<AclEntry>)value);
return; return;
} }
throw new UnsupportedOperationException("'" + name() + ":" + throw new IllegalArgumentException("'" + name() + ":" +
attribute + "' not supported"); attribute + "' not recognized");
} }
@Override @Override
...@@ -81,6 +81,8 @@ abstract class AbstractAclFileAttributeView ...@@ -81,6 +81,8 @@ abstract class AbstractAclFileAttributeView
owner = true; owner = true;
continue; continue;
} }
throw new IllegalArgumentException("'" + name() + ":" +
attribute + "' not recognized");
} }
Map<String,Object> result = new HashMap<>(2); Map<String,Object> result = new HashMap<>(2);
if (acl) if (acl)
......
...@@ -46,6 +46,18 @@ abstract class AbstractBasicFileAttributeView ...@@ -46,6 +46,18 @@ abstract class AbstractBasicFileAttributeView
private static final String IS_SYMBOLIC_LINK_NAME = "isSymbolicLink"; private static final String IS_SYMBOLIC_LINK_NAME = "isSymbolicLink";
private static final String IS_OTHER_NAME = "isOther"; private static final String IS_OTHER_NAME = "isOther";
// the names of the basic attributes
static final Set<String> basicAttributeNames =
Util.newSet(SIZE_NAME,
CREATION_TIME_NAME,
LAST_ACCESS_TIME_NAME,
LAST_MODIFIED_TIME_NAME,
FILE_KEY_NAME,
IS_DIRECTORY_NAME,
IS_REGULAR_FILE_NAME,
IS_SYMBOLIC_LINK_NAME,
IS_OTHER_NAME);
protected AbstractBasicFileAttributeView() { } protected AbstractBasicFileAttributeView() { }
@Override @Override
...@@ -69,24 +81,26 @@ abstract class AbstractBasicFileAttributeView ...@@ -69,24 +81,26 @@ abstract class AbstractBasicFileAttributeView
setTimes(null, null, (FileTime)value); setTimes(null, null, (FileTime)value);
return; return;
} }
throw new UnsupportedOperationException("'" + attribute + throw new IllegalArgumentException("'" + name() + ":" +
"' is unknown or read-only attribute"); attribute + "' not recognized");
} }
/** /**
* Used to build a map of attribute name/values. * Used to build a map of attribute name/values.
*/ */
static class AttributesBuilder { static class AttributesBuilder {
private Set<String> set = new HashSet<>(); private Set<String> names = new HashSet<>();
private Map<String,Object> map = new HashMap<>(); private Map<String,Object> map = new HashMap<>();
private boolean copyAll; private boolean copyAll;
private AttributesBuilder(String[] attributes) { private AttributesBuilder(Set<String> allowed, String[] requested) {
for (String attribute: attributes) { for (String name: requested) {
if (attribute.equals("*")) { if (name.equals("*")) {
copyAll = true; copyAll = true;
} else { } else {
set.add(attribute); if (!allowed.contains(name))
throw new IllegalArgumentException("'" + name + "' not recognized");
names.add(name);
} }
} }
} }
...@@ -94,21 +108,19 @@ abstract class AbstractBasicFileAttributeView ...@@ -94,21 +108,19 @@ abstract class AbstractBasicFileAttributeView
/** /**
* Creates builder to build up a map of the matching attributes * Creates builder to build up a map of the matching attributes
*/ */
static AttributesBuilder create(String[] attributes) { static AttributesBuilder create(Set<String> allowed, String[] requested) {
return new AttributesBuilder(attributes); return new AttributesBuilder(allowed, requested);
} }
/** /**
* Returns true if the attribute should be returned in the map * Returns true if the attribute should be returned in the map
*/ */
boolean match(String attribute) { boolean match(String name) {
if (copyAll) return copyAll || names.contains(name);
return true;
return set.contains(attribute);
} }
void add(String attribute, Object value) { void add(String name, Object value) {
map.put(attribute, value); map.put(name, value);
} }
/** /**
...@@ -124,7 +136,7 @@ abstract class AbstractBasicFileAttributeView ...@@ -124,7 +136,7 @@ abstract class AbstractBasicFileAttributeView
* Invoked by readAttributes or sub-classes to add all matching basic * Invoked by readAttributes or sub-classes to add all matching basic
* attributes to the builder * attributes to the builder
*/ */
final void addBasicAttributesToBuilder(BasicFileAttributes attrs, final void addRequestedBasicAttributes(BasicFileAttributes attrs,
AttributesBuilder builder) AttributesBuilder builder)
{ {
if (builder.match(SIZE_NAME)) if (builder.match(SIZE_NAME))
...@@ -148,9 +160,12 @@ abstract class AbstractBasicFileAttributeView ...@@ -148,9 +160,12 @@ abstract class AbstractBasicFileAttributeView
} }
@Override @Override
public Map<String,Object> readAttributes(String[] attributes) throws IOException { public Map<String,Object> readAttributes(String[] requested)
AttributesBuilder builder = AttributesBuilder.create(attributes); throws IOException
addBasicAttributesToBuilder(readAttributes(), builder); {
AttributesBuilder builder =
AttributesBuilder.create(basicAttributeNames, requested);
addRequestedBasicAttributes(readAttributes(), builder);
return builder.unmodifiableMap(); return builder.unmodifiableMap();
} }
} }
...@@ -29,7 +29,6 @@ import java.nio.file.*; ...@@ -29,7 +29,6 @@ import java.nio.file.*;
import java.nio.file.spi.FileSystemProvider; import java.nio.file.spi.FileSystemProvider;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
import java.util.Collections;
/** /**
* Base implementation class of FileSystemProvider * Base implementation class of FileSystemProvider
...@@ -72,6 +71,8 @@ abstract class AbstractFileSystemProvider extends FileSystemProvider { ...@@ -72,6 +71,8 @@ abstract class AbstractFileSystemProvider extends FileSystemProvider {
throws IOException throws IOException
{ {
String[] s = split(attribute); String[] s = split(attribute);
if (s[0].length() == 0)
throw new IllegalArgumentException(attribute);
DynamicFileAttributeView view = getFileAttributeView(file, s[0], options); DynamicFileAttributeView view = getFileAttributeView(file, s[0], options);
if (view == null) if (view == null)
throw new UnsupportedOperationException("View '" + s[0] + "' not available"); throw new UnsupportedOperationException("View '" + s[0] + "' not available");
...@@ -83,9 +84,11 @@ abstract class AbstractFileSystemProvider extends FileSystemProvider { ...@@ -83,9 +84,11 @@ abstract class AbstractFileSystemProvider extends FileSystemProvider {
throws IOException throws IOException
{ {
String[] s = split(attributes); String[] s = split(attributes);
if (s[0].length() == 0)
throw new IllegalArgumentException(attributes);
DynamicFileAttributeView view = getFileAttributeView(file, s[0], options); DynamicFileAttributeView view = getFileAttributeView(file, s[0], options);
if (view == null) if (view == null)
return Collections.emptyMap(); throw new UnsupportedOperationException("View '" + s[0] + "' not available");
return view.readAttributes(s[1].split(",")); return view.readAttributes(s[1].split(","));
} }
......
...@@ -59,22 +59,6 @@ abstract class AbstractUserDefinedFileAttributeView ...@@ -59,22 +59,6 @@ abstract class AbstractUserDefinedFileAttributeView
return "user"; return "user";
} }
private Object getAttribute(String attribute) throws IOException {
int size;
try {
size = size(attribute);
} catch (IOException e) {
// not found or some other I/O error
if (list().contains(attribute))
throw e;
return null;
}
byte[] buf = new byte[size];
int n = read(attribute, ByteBuffer.wrap(buf));
return (n == size) ? buf : Arrays.copyOf(buf, n);
}
@Override @Override
public final void setAttribute(String attribute, Object value) public final void setAttribute(String attribute, Object value)
throws IOException throws IOException
...@@ -94,12 +78,13 @@ abstract class AbstractUserDefinedFileAttributeView ...@@ -94,12 +78,13 @@ abstract class AbstractUserDefinedFileAttributeView
{ {
// names of attributes to return // names of attributes to return
List<String> names = new ArrayList<>(); List<String> names = new ArrayList<>();
for (String name: attributes) { for (String name: attributes) {
if (name.equals("*")) { if (name.equals("*")) {
names = list(); names = list();
break; break;
} else { } else {
if (name.length() == 0)
throw new IllegalArgumentException();
names.add(name); names.add(name);
} }
} }
...@@ -107,11 +92,12 @@ abstract class AbstractUserDefinedFileAttributeView ...@@ -107,11 +92,12 @@ abstract class AbstractUserDefinedFileAttributeView
// read each value and return in map // read each value and return in map
Map<String,Object> result = new HashMap<>(); Map<String,Object> result = new HashMap<>();
for (String name: names) { for (String name: names) {
Object value = getAttribute(name); int size = size(name);
if (value != null) byte[] buf = new byte[size];
result.put(name, value); int n = read(name, ByteBuffer.wrap(buf));
byte[] value = (n == size) ? buf : Arrays.copyOf(buf, n);
result.put(name, value);
} }
return result; return result;
} }
} }
...@@ -81,7 +81,8 @@ abstract class AbstractWatchKey implements WatchKey { ...@@ -81,7 +81,8 @@ abstract class AbstractWatchKey implements WatchKey {
/** /**
* Return the original watchable (Path) * Return the original watchable (Path)
*/ */
Path watchable() { @Override
public Path watchable() {
return dir; return dir;
} }
......
...@@ -63,10 +63,10 @@ final class FileOwnerAttributeViewImpl ...@@ -63,10 +63,10 @@ final class FileOwnerAttributeViewImpl
{ {
if (attribute.equals(OWNER_NAME)) { if (attribute.equals(OWNER_NAME)) {
setOwner((UserPrincipal)value); setOwner((UserPrincipal)value);
return; } else {
throw new IllegalArgumentException("'" + name() + ":" +
attribute + "' not recognized");
} }
throw new UnsupportedOperationException("'" + name() + ":" +
attribute + "' not supported");
} }
@Override @Override
...@@ -75,6 +75,9 @@ final class FileOwnerAttributeViewImpl ...@@ -75,6 +75,9 @@ final class FileOwnerAttributeViewImpl
for (String attribute: attributes) { for (String attribute: attributes) {
if (attribute.equals("*") || attribute.equals(OWNER_NAME)) { if (attribute.equals("*") || attribute.equals(OWNER_NAME)) {
result.put(OWNER_NAME, getOwner()); result.put(OWNER_NAME, getOwner());
} else {
throw new IllegalArgumentException("'" + name() + ":" +
attribute + "' not recognized");
} }
} }
return result; return result;
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
package sun.nio.fs; package sun.nio.fs;
import java.util.*;
/** /**
* Utility methods * Utility methods
*/ */
...@@ -54,6 +56,28 @@ class Util { ...@@ -54,6 +56,28 @@ class Util {
} }
result[n] = s.substring(last, s.length()); result[n] = s.substring(last, s.length());
return result; return result;
}
/**
* Returns a Set containing the given elements.
*/
static <E> Set<E> newSet(E... elements) {
HashSet<E> set = new HashSet<>();
for (E e: elements) {
set.add(e);
}
return set;
}
/**
* Returns a Set containing all the elements of the given Set plus
* the given elements.
*/
static <E> Set<E> newSet(Set<E> other, E... elements) {
HashSet<E> set = new HashSet<>(other);
for (E e: elements) {
set.add(e);
}
return set;
} }
} }
...@@ -33,8 +33,7 @@ import java.nio.file.*; ...@@ -33,8 +33,7 @@ import java.nio.file.*;
import static java.nio.file.StandardWatchEventKind.*; import static java.nio.file.StandardWatchEventKind.*;
import static java.nio.file.LinkOption.*; import static java.nio.file.LinkOption.*;
import java.nio.file.attribute.*; import java.nio.file.attribute.*;
import java.io.*; import java.io.IOException;
import java.util.*;
/** /**
* Example to watch a directory (or tree) for changes to files. * Example to watch a directory (or tree) for changes to files.
...@@ -43,9 +42,9 @@ import java.util.*; ...@@ -43,9 +42,9 @@ import java.util.*;
public class WatchDir { public class WatchDir {
private final WatchService watcher; private final WatchService watcher;
private final Map<WatchKey,Path> keys;
private final boolean recursive; private final boolean recursive;
private boolean trace = false; private boolean trace = false;
private int count;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
static <T> WatchEvent<T> cast(WatchEvent<?> event) { static <T> WatchEvent<T> cast(WatchEvent<?> event) {
...@@ -57,17 +56,9 @@ public class WatchDir { ...@@ -57,17 +56,9 @@ public class WatchDir {
*/ */
private void register(Path dir) throws IOException { private void register(Path dir) throws IOException {
WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
if (trace) { count++;
Path prev = keys.get(key); if (trace)
if (prev == null) { System.out.format("register: %s\n", dir);
System.out.format("register: %s\n", dir);
} else {
if (!dir.equals(prev)) {
System.out.format("update: %s -> %s\n", prev, dir);
}
}
}
keys.put(key, dir);
} }
/** /**
...@@ -92,7 +83,6 @@ public class WatchDir { ...@@ -92,7 +83,6 @@ public class WatchDir {
*/ */
WatchDir(Path dir, boolean recursive) throws IOException { WatchDir(Path dir, boolean recursive) throws IOException {
this.watcher = FileSystems.getDefault().newWatchService(); this.watcher = FileSystems.getDefault().newWatchService();
this.keys = new HashMap<WatchKey,Path>();
this.recursive = recursive; this.recursive = recursive;
if (recursive) { if (recursive) {
...@@ -121,12 +111,6 @@ public class WatchDir { ...@@ -121,12 +111,6 @@ public class WatchDir {
return; return;
} }
Path dir = keys.get(key);
if (dir == null) {
System.err.println("WatchKey not recognized!!");
continue;
}
for (WatchEvent<?> event: key.pollEvents()) { for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind kind = event.kind(); WatchEvent.Kind kind = event.kind();
...@@ -138,7 +122,7 @@ public class WatchDir { ...@@ -138,7 +122,7 @@ public class WatchDir {
// Context for directory entry event is the file name of entry // Context for directory entry event is the file name of entry
WatchEvent<Path> ev = cast(event); WatchEvent<Path> ev = cast(event);
Path name = ev.context(); Path name = ev.context();
Path child = dir.resolve(name); Path child = ((Path)key.watchable()).resolve(name);
// print out event // print out event
System.out.format("%s: %s\n", event.kind().name(), child); System.out.format("%s: %s\n", event.kind().name(), child);
...@@ -156,15 +140,13 @@ public class WatchDir { ...@@ -156,15 +140,13 @@ public class WatchDir {
} }
} }
// reset key and remove from set if directory no longer accessible // reset key
boolean valid = key.reset(); boolean valid = key.reset();
if (!valid) { if (!valid) {
keys.remove(key); // directory no longer accessible
count--;
// all directories are inaccessible if (count == 0)
if (keys.isEmpty()) {
break; break;
}
} }
} }
} }
......
...@@ -27,6 +27,7 @@ package sun.nio.fs; ...@@ -27,6 +27,7 @@ package sun.nio.fs;
import java.nio.file.attribute.*; import java.nio.file.attribute.*;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.io.IOException; import java.io.IOException;
import sun.misc.Unsafe; import sun.misc.Unsafe;
...@@ -57,6 +58,10 @@ class LinuxDosFileAttributeView ...@@ -57,6 +58,10 @@ class LinuxDosFileAttributeView
private static final int DOS_XATTR_SYSTEM = 0x04; private static final int DOS_XATTR_SYSTEM = 0x04;
private static final int DOS_XATTR_ARCHIVE = 0x20; private static final int DOS_XATTR_ARCHIVE = 0x20;
// the names of the DOS attributes (includes basic)
private static final Set<String> dosAttributeNames =
Util.newSet(basicAttributeNames, READONLY_NAME, ARCHIVE_NAME, SYSTEM_NAME, HIDDEN_NAME);
LinuxDosFileAttributeView(UnixPath file, boolean followLinks) { LinuxDosFileAttributeView(UnixPath file, boolean followLinks) {
super(file, followLinks); super(file, followLinks);
} }
...@@ -93,9 +98,10 @@ class LinuxDosFileAttributeView ...@@ -93,9 +98,10 @@ class LinuxDosFileAttributeView
public Map<String,Object> readAttributes(String[] attributes) public Map<String,Object> readAttributes(String[] attributes)
throws IOException throws IOException
{ {
AttributesBuilder builder = AttributesBuilder.create(attributes); AttributesBuilder builder =
AttributesBuilder.create(dosAttributeNames, attributes);
DosFileAttributes attrs = readAttributes(); DosFileAttributes attrs = readAttributes();
addBasicAttributesToBuilder(attrs, builder); addRequestedBasicAttributes(attrs, builder);
if (builder.match(READONLY_NAME)) if (builder.match(READONLY_NAME))
builder.add(READONLY_NAME, attrs.isReadOnly()); builder.add(READONLY_NAME, attrs.isReadOnly());
if (builder.match(ARCHIVE_NAME)) if (builder.match(ARCHIVE_NAME))
......
...@@ -28,8 +28,6 @@ package sun.nio.fs; ...@@ -28,8 +28,6 @@ package sun.nio.fs;
import java.nio.file.*; import java.nio.file.*;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.security.AccessController;
import sun.security.action.GetPropertyAction;
import static sun.nio.fs.LinuxNativeDispatcher.*; import static sun.nio.fs.LinuxNativeDispatcher.*;
/** /**
...@@ -37,42 +35,16 @@ import static sun.nio.fs.LinuxNativeDispatcher.*; ...@@ -37,42 +35,16 @@ import static sun.nio.fs.LinuxNativeDispatcher.*;
*/ */
class LinuxFileSystem extends UnixFileSystem { class LinuxFileSystem extends UnixFileSystem {
private final boolean hasInotify;
LinuxFileSystem(UnixFileSystemProvider provider, String dir) { LinuxFileSystem(UnixFileSystemProvider provider, String dir) {
super(provider, dir); super(provider, dir);
// assume X.Y[-Z] format
String osversion = AccessController
.doPrivileged(new GetPropertyAction("os.version"));
String[] vers = Util.split(osversion, '.');
assert vers.length >= 2;
int majorVersion = Integer.parseInt(vers[0]);
int minorVersion = Integer.parseInt(vers[1]);
int microVersion = 0;
if (vers.length > 2) {
String[] microVers = Util.split(vers[2], '-');
microVersion = (microVers.length > 0) ?
Integer.parseInt(microVers[0]) : 0;
}
// inotify available since 2.6.13
this.hasInotify = ((majorVersion > 2) ||
(majorVersion == 2 && minorVersion > 6) ||
((majorVersion == 2) && (minorVersion == 6) && (microVersion >= 13)));
} }
@Override @Override
public WatchService newWatchService() public WatchService newWatchService()
throws IOException throws IOException
{ {
if (hasInotify) { // assume 2.6.13 or newer
return new LinuxWatchService(this); return new LinuxWatchService(this);
} else {
// use polling implementation on older kernels
return new PollingWatchService();
}
} }
......
...@@ -123,6 +123,10 @@ class UnixFileAttributeViews { ...@@ -123,6 +123,10 @@ class UnixFileAttributeViews {
private static final String OWNER_NAME = "owner"; private static final String OWNER_NAME = "owner";
private static final String GROUP_NAME = "group"; private static final String GROUP_NAME = "group";
// the names of the posix attributes (incudes basic)
static final Set<String> posixAttributeNames =
Util.newSet(basicAttributeNames, PERMISSIONS_NAME, OWNER_NAME, GROUP_NAME);
Posix(UnixPath file, boolean followLinks) { Posix(UnixPath file, boolean followLinks) {
super(file, followLinks); super(file, followLinks);
} }
...@@ -172,9 +176,10 @@ class UnixFileAttributeViews { ...@@ -172,9 +176,10 @@ class UnixFileAttributeViews {
* Invoked by readAttributes or sub-classes to add all matching posix * Invoked by readAttributes or sub-classes to add all matching posix
* attributes to the builder * attributes to the builder
*/ */
final void addPosixAttributesToBuilder(PosixFileAttributes attrs, final void addRequestedPosixAttributes(PosixFileAttributes attrs,
AttributesBuilder builder) AttributesBuilder builder)
{ {
addRequestedBasicAttributes(attrs, builder);
if (builder.match(PERMISSIONS_NAME)) if (builder.match(PERMISSIONS_NAME))
builder.add(PERMISSIONS_NAME, attrs.permissions()); builder.add(PERMISSIONS_NAME, attrs.permissions());
if (builder.match(OWNER_NAME)) if (builder.match(OWNER_NAME))
...@@ -184,13 +189,13 @@ class UnixFileAttributeViews { ...@@ -184,13 +189,13 @@ class UnixFileAttributeViews {
} }
@Override @Override
public Map<String,Object> readAttributes(String[] attributes) public Map<String,Object> readAttributes(String[] requested)
throws IOException throws IOException
{ {
AttributesBuilder builder = AttributesBuilder.create(attributes); AttributesBuilder builder =
AttributesBuilder.create(posixAttributeNames, requested);
PosixFileAttributes attrs = readAttributes(); PosixFileAttributes attrs = readAttributes();
addBasicAttributesToBuilder(attrs, builder); addRequestedPosixAttributes(attrs, builder);
addPosixAttributesToBuilder(attrs, builder);
return builder.unmodifiableMap(); return builder.unmodifiableMap();
} }
...@@ -287,6 +292,12 @@ class UnixFileAttributeViews { ...@@ -287,6 +292,12 @@ class UnixFileAttributeViews {
private static final String GID_NAME = "gid"; private static final String GID_NAME = "gid";
private static final String CTIME_NAME = "ctime"; private static final String CTIME_NAME = "ctime";
// the names of the unix attributes (including posix)
static final Set<String> unixAttributeNames =
Util.newSet(posixAttributeNames,
MODE_NAME, INO_NAME, DEV_NAME, RDEV_NAME,
NLINK_NAME, UID_NAME, GID_NAME, CTIME_NAME);
Unix(UnixPath file, boolean followLinks) { Unix(UnixPath file, boolean followLinks) {
super(file, followLinks); super(file, followLinks);
} }
...@@ -316,13 +327,13 @@ class UnixFileAttributeViews { ...@@ -316,13 +327,13 @@ class UnixFileAttributeViews {
} }
@Override @Override
public Map<String,Object> readAttributes(String[] attributes) public Map<String,Object> readAttributes(String[] requested)
throws IOException throws IOException
{ {
AttributesBuilder builder = AttributesBuilder.create(attributes); AttributesBuilder builder =
AttributesBuilder.create(unixAttributeNames, requested);
UnixFileAttributes attrs = readAttributes(); UnixFileAttributes attrs = readAttributes();
addBasicAttributesToBuilder(attrs, builder); addRequestedPosixAttributes(attrs, builder);
addPosixAttributesToBuilder(attrs, builder);
if (builder.match(MODE_NAME)) if (builder.match(MODE_NAME))
builder.add(MODE_NAME, attrs.mode()); builder.add(MODE_NAME, attrs.mode());
if (builder.match(INO_NAME)) if (builder.match(INO_NAME))
......
...@@ -606,7 +606,9 @@ class UnixPath ...@@ -606,7 +606,9 @@ class UnixPath
@Override @Override
public boolean startsWith(Path other) { public boolean startsWith(Path other) {
UnixPath that = toUnixPath(other); if (!(Objects.requireNonNull(other) instanceof UnixPath))
return false;
UnixPath that = (UnixPath)other;
// other path is longer // other path is longer
if (that.path.length > path.length) if (that.path.length > path.length)
...@@ -655,7 +657,9 @@ class UnixPath ...@@ -655,7 +657,9 @@ class UnixPath
@Override @Override
public boolean endsWith(Path other) { public boolean endsWith(Path other) {
UnixPath that = toUnixPath(other); if (!(Objects.requireNonNull(other) instanceof UnixPath))
return false;
UnixPath that = (UnixPath)other;
int thisLen = path.length; int thisLen = path.length;
int thatLen = that.path.length; int thatLen = that.path.length;
......
...@@ -157,6 +157,11 @@ class WindowsFileAttributeViews { ...@@ -157,6 +157,11 @@ class WindowsFileAttributeViews {
private static final String HIDDEN_NAME = "hidden"; private static final String HIDDEN_NAME = "hidden";
private static final String ATTRIBUTES_NAME = "attributes"; private static final String ATTRIBUTES_NAME = "attributes";
// the names of the DOS attribtues (includes basic)
static final Set<String> dosAttributeNames =
Util.newSet(basicAttributeNames,
READONLY_NAME, ARCHIVE_NAME, SYSTEM_NAME, HIDDEN_NAME, ATTRIBUTES_NAME);
Dos(WindowsPath file, boolean followLinks) { Dos(WindowsPath file, boolean followLinks) {
super(file, followLinks); super(file, followLinks);
} }
...@@ -193,9 +198,10 @@ class WindowsFileAttributeViews { ...@@ -193,9 +198,10 @@ class WindowsFileAttributeViews {
public Map<String,Object> readAttributes(String[] attributes) public Map<String,Object> readAttributes(String[] attributes)
throws IOException throws IOException
{ {
AttributesBuilder builder = AttributesBuilder.create(attributes); AttributesBuilder builder =
AttributesBuilder.create(dosAttributeNames, attributes);
WindowsFileAttributes attrs = readAttributes(); WindowsFileAttributes attrs = readAttributes();
addBasicAttributesToBuilder(attrs, builder); addRequestedBasicAttributes(attrs, builder);
if (builder.match(READONLY_NAME)) if (builder.match(READONLY_NAME))
builder.add(READONLY_NAME, attrs.isReadOnly()); builder.add(READONLY_NAME, attrs.isReadOnly());
if (builder.match(ARCHIVE_NAME)) if (builder.match(ARCHIVE_NAME))
......
...@@ -646,7 +646,9 @@ class WindowsPath extends AbstractPath { ...@@ -646,7 +646,9 @@ class WindowsPath extends AbstractPath {
@Override @Override
public boolean startsWith(Path obj) { public boolean startsWith(Path obj) {
WindowsPath other = toWindowsPath(obj); if (!(Objects.requireNonNull(obj) instanceof WindowsPath))
return false;
WindowsPath other = (WindowsPath)obj;
// if this path has a root component the given path's root must match // if this path has a root component the given path's root must match
if (!this.root.equalsIgnoreCase(other.root)) { if (!this.root.equalsIgnoreCase(other.root)) {
...@@ -675,7 +677,9 @@ class WindowsPath extends AbstractPath { ...@@ -675,7 +677,9 @@ class WindowsPath extends AbstractPath {
@Override @Override
public boolean endsWith(Path obj) { public boolean endsWith(Path obj) {
WindowsPath other = toWindowsPath(obj); if (!(Objects.requireNonNull(obj) instanceof WindowsPath))
return false;
WindowsPath other = (WindowsPath)obj;
// other path is longer // other path is longer
if (other.path.length() > this.path.length()) { if (other.path.length() > this.path.length()) {
......
/* /*
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -173,24 +173,45 @@ JNIEXPORT jbyteArray JNICALL Java_sun_tools_attach_WindowsVirtualMachine_generat ...@@ -173,24 +173,45 @@ JNIEXPORT jbyteArray JNICALL Java_sun_tools_attach_WindowsVirtualMachine_generat
JNIEXPORT jlong JNICALL Java_sun_tools_attach_WindowsVirtualMachine_openProcess JNIEXPORT jlong JNICALL Java_sun_tools_attach_WindowsVirtualMachine_openProcess
(JNIEnv *env, jclass cls, jint pid) (JNIEnv *env, jclass cls, jint pid)
{ {
HANDLE hProcess; HANDLE hProcess = NULL;
/* if (pid == (jint) GetCurrentProcessId()) {
* Attempt to open process. If it fails then we try to enable the /* process is attaching to itself; get a pseudo handle instead */
* SE_DEBUG_NAME privilege and retry. hProcess = GetCurrentProcess();
*/ /* duplicate the pseudo handle so it can be used in more contexts */
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid); if (DuplicateHandle(hProcess, hProcess, hProcess, &hProcess,
if (hProcess == NULL && GetLastError() == ERROR_ACCESS_DENIED) { PROCESS_ALL_ACCESS, FALSE, 0) == 0) {
hProcess = doPrivilegedOpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid); /*
* Could not duplicate the handle which isn't a good sign,
* but we'll try again with OpenProcess() below.
*/
hProcess = NULL;
}
} }
if (hProcess == NULL) { if (hProcess == NULL) {
if (GetLastError() == ERROR_INVALID_PARAMETER) { /*
JNU_ThrowIOException(env, "no such process"); * Attempt to open process. If it fails then we try to enable the
} else { * SE_DEBUG_NAME privilege and retry.
JNU_ThrowIOExceptionWithLastError(env, "OpenProcess failed"); */
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
if (hProcess == NULL && GetLastError() == ERROR_ACCESS_DENIED) {
hProcess = doPrivilegedOpenProcess(PROCESS_ALL_ACCESS, FALSE,
(DWORD)pid);
}
if (hProcess == NULL) {
if (GetLastError() == ERROR_INVALID_PARAMETER) {
JNU_ThrowIOException(env, "no such process");
} else {
char err_mesg[255];
/* include the last error in the default detail message */
sprintf(err_mesg, "OpenProcess(pid=%d) failed; LastError=0x%x",
(int)pid, (int)GetLastError());
JNU_ThrowIOExceptionWithLastError(env, err_mesg);
}
return (jlong)0;
} }
return (jlong)0;
} }
/* /*
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
*/ */
/* @test /* @test
* @bug 4313887 6838333 * @bug 4313887 6838333 7017446
* @summary Unit test for java.nio.file.Files * @summary Unit test for java.nio.file.Files
* @library .. * @library ..
*/ */
...@@ -94,12 +94,6 @@ public class FileAttributes { ...@@ -94,12 +94,6 @@ public class FileAttributes {
assertTrue(map.size() == 2); assertTrue(map.size() == 2);
checkEqual(attrs.size(), map.get("size")); checkEqual(attrs.size(), map.get("size"));
checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime")); checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
map = Files.readAttributes(file,
"basic:lastModifiedTime,lastAccessTime,ShouldNotExist");
assertTrue(map.size() == 2);
checkEqual(attrs.lastModifiedTime(), map.get("lastModifiedTime"));
checkEqual(attrs.lastAccessTime(), map.get("lastAccessTime"));
} }
// Exercise getAttribute/setAttribute/readAttributes on posix attributes // Exercise getAttribute/setAttribute/readAttributes on posix attributes
...@@ -132,7 +126,7 @@ public class FileAttributes { ...@@ -132,7 +126,7 @@ public class FileAttributes {
assertTrue(map.size() >= 12); assertTrue(map.size() >= 12);
checkEqual(attrs.permissions(), map.get("permissions")); // check one checkEqual(attrs.permissions(), map.get("permissions")); // check one
map = Files.readAttributes(file, "posix:size,owner,ShouldNotExist"); map = Files.readAttributes(file, "posix:size,owner");
assertTrue(map.size() == 2); assertTrue(map.size() == 2);
checkEqual(attrs.size(), map.get("size")); checkEqual(attrs.size(), map.get("size"));
checkEqual(attrs.owner(), map.get("owner")); checkEqual(attrs.owner(), map.get("owner"));
...@@ -155,7 +149,7 @@ public class FileAttributes { ...@@ -155,7 +149,7 @@ public class FileAttributes {
map = Files.readAttributes(file, "unix:*"); map = Files.readAttributes(file, "unix:*");
assertTrue(map.size() >= 20); assertTrue(map.size() >= 20);
map = Files.readAttributes(file, "unix:size,uid,gid,ShouldNotExist"); map = Files.readAttributes(file, "unix:size,uid,gid");
assertTrue(map.size() == 3); assertTrue(map.size() == 3);
checkEqual(map.get("size"), checkEqual(map.get("size"),
Files.readAttributes(file, BasicFileAttributes.class).size()); Files.readAttributes(file, BasicFileAttributes.class).size());
...@@ -206,14 +200,65 @@ public class FileAttributes { ...@@ -206,14 +200,65 @@ public class FileAttributes {
assertTrue(map.size() >= 13); assertTrue(map.size() >= 13);
checkEqual(attrs.isReadOnly(), map.get("readonly")); // check one checkEqual(attrs.isReadOnly(), map.get("readonly")); // check one
map = Files.readAttributes(file, "dos:size,hidden,ShouldNotExist"); map = Files.readAttributes(file, "dos:size,hidden");
assertTrue(map.size() == 2); assertTrue(map.size() == 2);
checkEqual(attrs.size(), map.get("size")); checkEqual(attrs.size(), map.get("size"));
checkEqual(attrs.isHidden(), map.get("hidden")); checkEqual(attrs.isHidden(), map.get("hidden"));
} }
static void checkBadSet(Path file, String attribute, Object value)
throws IOException
{
try {
Files.setAttribute(file, attribute, 0);
throw new RuntimeException("IllegalArgumentException expected");
} catch (IllegalArgumentException ignore) { }
}
static void checkBadGet(Path file, String attribute) throws IOException {
try {
Files.getAttribute(file, attribute);
throw new RuntimeException("IllegalArgumentException expected");
} catch (IllegalArgumentException ignore) { }
}
static void checkBadRead(Path file, String attribute) throws IOException {
try {
Files.readAttributes(file, attribute);
throw new RuntimeException("IllegalArgumentException expected");
} catch (IllegalArgumentException ignore) { }
}
static void miscTests(Path file) throws IOException { static void miscTests(Path file) throws IOException {
// NPE tests // unsupported views
try {
Files.setAttribute(file, "foo:bar", 0);
throw new RuntimeException("UnsupportedOperationException expected");
} catch (UnsupportedOperationException ignore) { }
try {
Files.getAttribute(file, "foo:bar");
throw new RuntimeException("UnsupportedOperationException expected");
} catch (UnsupportedOperationException ignore) { }
try {
Files.readAttributes(file, "foo:*");
throw new RuntimeException("UnsupportedOperationException expected");
} catch (UnsupportedOperationException ignore) { }
// bad args
checkBadSet(file, "", 0);
checkBadSet(file, "basic:", 0);
checkBadSet(file, "basic:foobar", 0);
checkBadGet(file, "");
checkBadGet(file, "basic:");
checkBadGet(file, "basic:foobar");
checkBadGet(file, "basic:size,lastModifiedTime");
checkBadGet(file, "basic:*");
checkBadRead(file, "");
checkBadRead(file, "basic:");
checkBadRead(file, "basic:foobar");
checkBadRead(file, "basic:size,foobar");
// nulls
try { try {
Files.getAttribute(file, null); Files.getAttribute(file, null);
throw new RuntimeException("NullPointerException expected"); throw new RuntimeException("NullPointerException expected");
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
*/ */
/* @test /* @test
* @bug 4313887 6838333 * @bug 4313887 6838333 7017446
* @summary Unit test for java.nio.file.WatchService * @summary Unit test for java.nio.file.WatchService
* @library .. * @library ..
* @run main/timeout=120 Basic * @run main/timeout=120 Basic
...@@ -44,6 +44,8 @@ public class Basic { ...@@ -44,6 +44,8 @@ public class Basic {
static void checkKey(WatchKey key, Path dir) { static void checkKey(WatchKey key, Path dir) {
if (!key.isValid()) if (!key.isValid())
throw new RuntimeException("Key is not valid"); throw new RuntimeException("Key is not valid");
if (key.watchable() != dir)
throw new RuntimeException("Unexpected watchable");
} }
static void takeExpectedKey(WatchService watcher, WatchKey expected) { static void takeExpectedKey(WatchService watcher, WatchKey expected) {
......
...@@ -141,9 +141,6 @@ public class Basic { ...@@ -141,9 +141,6 @@ public class Basic {
map = Files.readAttributes(file, "user:*"); map = Files.readAttributes(file, "user:*");
if (!Arrays.equals(valueAsBytes, (byte[])map.get(ATTR_NAME))) if (!Arrays.equals(valueAsBytes, (byte[])map.get(ATTR_NAME)))
throw new RuntimeException("Unexpected attribute value"); throw new RuntimeException("Unexpected attribute value");
map = Files.readAttributes(file, "user:DoesNotExist");
if (!map.isEmpty())
throw new RuntimeException("Map expected to be empty");
} }
static void miscTests(final Path file) throws IOException { static void miscTests(final Path file) throws IOException {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册