Merge jdk7-b71
authorxdono
Tue, 01 Sep 2009 13:03:09 -0700
changeset 1623b3f3240135f0
parent 1622 e0b26d347302
parent 1618 b71a03c75515
child 1624 ce3fde68c495
Merge
src/share/classes/sun/nio/ch/AbstractFuture.java
     1.1 --- a/.hgignore	Mon Aug 24 17:26:09 2009 -0700
     1.2 +++ b/.hgignore	Tue Sep 01 13:03:09 2009 -0700
     1.3 @@ -1,3 +1,6 @@
     1.4  ^build/
     1.5  ^dist/
     1.6  ^nbproject/private/
     1.7 +^make/netbeans/.*/nbproject/private/
     1.8 +^make/netbeans/.*/build/
     1.9 +^make/netbeans/.*/dist/
     2.1 --- a/make/java/nio/FILES_java.gmk	Mon Aug 24 17:26:09 2009 -0700
     2.2 +++ b/make/java/nio/FILES_java.gmk	Tue Sep 01 13:03:09 2009 -0700
     2.3 @@ -160,7 +160,6 @@
     2.4  	\
     2.5  	sun/nio/ByteBuffered.java \
     2.6  	\
     2.7 -	sun/nio/ch/AbstractFuture.java \
     2.8          sun/nio/ch/AbstractPollArrayWrapper.java \
     2.9  	sun/nio/ch/AllocatedNativeObject.java \
    2.10  	sun/nio/ch/AsynchronousChannelGroupImpl.java \
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/make/netbeans/jdwpgen/build.xml	Tue Sep 01 13:03:09 2009 -0700
     3.3 @@ -0,0 +1,74 @@
     3.4 +<?xml version="1.0" encoding="UTF-8"?>
     3.5 +<!-- You may freely edit this file. See commented blocks below for -->
     3.6 +<!-- some examples of how to customize the build. -->
     3.7 +<!-- (If you delete it and reopen the project it will be recreated.) -->
     3.8 +<!-- By default, only the Clean and Build commands use this build script. -->
     3.9 +<!-- Commands such as Run, Debug, and Test only use this build script if -->
    3.10 +<!-- the Compile on Save feature is turned off for the project. -->
    3.11 +<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
    3.12 +<!-- in the project's Project Properties dialog box.-->
    3.13 +<project name="jdwpgen" default="default" basedir=".">
    3.14 +    <description>Builds, tests, and runs the project jdwpgen.</description>
    3.15 +    <import file="nbproject/build-impl.xml"/>
    3.16 +    <!--
    3.17 +
    3.18 +    There exist several targets which are by default empty and which can be 
    3.19 +    used for execution of your tasks. These targets are usually executed 
    3.20 +    before and after some main targets. They are: 
    3.21 +
    3.22 +      -pre-init:                 called before initialization of project properties
    3.23 +      -post-init:                called after initialization of project properties
    3.24 +      -pre-compile:              called before javac compilation
    3.25 +      -post-compile:             called after javac compilation
    3.26 +      -pre-compile-single:       called before javac compilation of single file
    3.27 +      -post-compile-single:      called after javac compilation of single file
    3.28 +      -pre-compile-test:         called before javac compilation of JUnit tests
    3.29 +      -post-compile-test:        called after javac compilation of JUnit tests
    3.30 +      -pre-compile-test-single:  called before javac compilation of single JUnit test
    3.31 +      -post-compile-test-single: called after javac compilation of single JUunit test
    3.32 +      -pre-jar:                  called before JAR building
    3.33 +      -post-jar:                 called after JAR building
    3.34 +      -post-clean:               called after cleaning build products
    3.35 +
    3.36 +    (Targets beginning with '-' are not intended to be called on their own.)
    3.37 +
    3.38 +    Example of inserting an obfuscator after compilation could look like this:
    3.39 +
    3.40 +        <target name="-post-compile">
    3.41 +            <obfuscate>
    3.42 +                <fileset dir="${build.classes.dir}"/>
    3.43 +            </obfuscate>
    3.44 +        </target>
    3.45 +
    3.46 +    For list of available properties check the imported 
    3.47 +    nbproject/build-impl.xml file. 
    3.48 +
    3.49 +
    3.50 +    Another way to customize the build is by overriding existing main targets.
    3.51 +    The targets of interest are: 
    3.52 +
    3.53 +      -init-macrodef-javac:     defines macro for javac compilation
    3.54 +      -init-macrodef-junit:     defines macro for junit execution
    3.55 +      -init-macrodef-debug:     defines macro for class debugging
    3.56 +      -init-macrodef-java:      defines macro for class execution
    3.57 +      -do-jar-with-manifest:    JAR building (if you are using a manifest)
    3.58 +      -do-jar-without-manifest: JAR building (if you are not using a manifest)
    3.59 +      run:                      execution of project 
    3.60 +      -javadoc-build:           Javadoc generation
    3.61 +      test-report:              JUnit report generation
    3.62 +
    3.63 +    An example of overriding the target for project execution could look like this:
    3.64 +
    3.65 +        <target name="run" depends="jdwpgen-impl.jar">
    3.66 +            <exec dir="bin" executable="launcher.exe">
    3.67 +                <arg file="${dist.jar}"/>
    3.68 +            </exec>
    3.69 +        </target>
    3.70 +
    3.71 +    Notice that the overridden target depends on the jar target and not only on 
    3.72 +    the compile target as the regular run target does. Again, for a list of available 
    3.73 +    properties which you can use, check the target you are overriding in the
    3.74 +    nbproject/build-impl.xml file. 
    3.75 +
    3.76 +    -->
    3.77 +</project>
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/make/netbeans/jdwpgen/nbproject/build-impl.xml	Tue Sep 01 13:03:09 2009 -0700
     4.3 @@ -0,0 +1,642 @@
     4.4 +<?xml version="1.0" encoding="UTF-8"?>
     4.5 +<!--
     4.6 +*** GENERATED FROM project.xml - DO NOT EDIT  ***
     4.7 +***         EDIT ../build.xml INSTEAD         ***
     4.8 +
     4.9 +For the purpose of easier reading the script
    4.10 +is divided into following sections:
    4.11 +
    4.12 +  - initialization
    4.13 +  - compilation
    4.14 +  - jar
    4.15 +  - execution
    4.16 +  - debugging
    4.17 +  - javadoc
    4.18 +  - junit compilation
    4.19 +  - junit execution
    4.20 +  - junit debugging
    4.21 +  - applet
    4.22 +  - cleanup
    4.23 +
    4.24 +        -->
    4.25 +<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="jdwpgen-impl">
    4.26 +    <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
    4.27 +    <!-- 
    4.28 +                ======================
    4.29 +                INITIALIZATION SECTION 
    4.30 +                ======================
    4.31 +            -->
    4.32 +    <target name="-pre-init">
    4.33 +        <!-- Empty placeholder for easier customization. -->
    4.34 +        <!-- You can override this target in the ../build.xml file. -->
    4.35 +    </target>
    4.36 +    <target depends="-pre-init" name="-init-private">
    4.37 +        <property file="nbproject/private/config.properties"/>
    4.38 +        <property file="nbproject/private/configs/${config}.properties"/>
    4.39 +        <property file="nbproject/private/private.properties"/>
    4.40 +    </target>
    4.41 +    <target depends="-pre-init,-init-private" name="-init-user">
    4.42 +        <property file="${user.properties.file}"/>
    4.43 +        <!-- The two properties below are usually overridden -->
    4.44 +        <!-- by the active platform. Just a fallback. -->
    4.45 +        <property name="default.javac.source" value="1.4"/>
    4.46 +        <property name="default.javac.target" value="1.4"/>
    4.47 +    </target>
    4.48 +    <target depends="-pre-init,-init-private,-init-user" name="-init-project">
    4.49 +        <property file="nbproject/configs/${config}.properties"/>
    4.50 +        <property file="nbproject/project.properties"/>
    4.51 +    </target>
    4.52 +    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
    4.53 +        <available file="${manifest.file}" property="manifest.available"/>
    4.54 +        <condition property="manifest.available+main.class">
    4.55 +            <and>
    4.56 +                <isset property="manifest.available"/>
    4.57 +                <isset property="main.class"/>
    4.58 +                <not>
    4.59 +                    <equals arg1="${main.class}" arg2="" trim="true"/>
    4.60 +                </not>
    4.61 +            </and>
    4.62 +        </condition>
    4.63 +        <condition property="manifest.available+main.class+mkdist.available">
    4.64 +            <and>
    4.65 +                <istrue value="${manifest.available+main.class}"/>
    4.66 +                <isset property="libs.CopyLibs.classpath"/>
    4.67 +            </and>
    4.68 +        </condition>
    4.69 +        <condition property="have.tests">
    4.70 +            <or>
    4.71 +                <available file="${test.src.dir}"/>
    4.72 +            </or>
    4.73 +        </condition>
    4.74 +        <condition property="have.sources">
    4.75 +            <or>
    4.76 +                <available file="${src.src.dir}"/>
    4.77 +            </or>
    4.78 +        </condition>
    4.79 +        <condition property="netbeans.home+have.tests">
    4.80 +            <and>
    4.81 +                <isset property="netbeans.home"/>
    4.82 +                <isset property="have.tests"/>
    4.83 +            </and>
    4.84 +        </condition>
    4.85 +        <condition property="no.javadoc.preview">
    4.86 +            <and>
    4.87 +                <isset property="javadoc.preview"/>
    4.88 +                <isfalse value="${javadoc.preview}"/>
    4.89 +            </and>
    4.90 +        </condition>
    4.91 +        <property name="run.jvmargs" value=""/>
    4.92 +        <property name="javac.compilerargs" value=""/>
    4.93 +        <property name="work.dir" value="${basedir}"/>
    4.94 +        <condition property="no.deps">
    4.95 +            <and>
    4.96 +                <istrue value="${no.dependencies}"/>
    4.97 +            </and>
    4.98 +        </condition>
    4.99 +        <property name="javac.debug" value="true"/>
   4.100 +        <property name="javadoc.preview" value="true"/>
   4.101 +        <property name="application.args" value=""/>
   4.102 +        <property name="source.encoding" value="${file.encoding}"/>
   4.103 +        <condition property="javadoc.encoding.used" value="${javadoc.encoding}">
   4.104 +            <and>
   4.105 +                <isset property="javadoc.encoding"/>
   4.106 +                <not>
   4.107 +                    <equals arg1="${javadoc.encoding}" arg2=""/>
   4.108 +                </not>
   4.109 +            </and>
   4.110 +        </condition>
   4.111 +        <property name="javadoc.encoding.used" value="${source.encoding}"/>
   4.112 +        <property name="includes" value="**"/>
   4.113 +        <property name="excludes" value=""/>
   4.114 +        <property name="do.depend" value="false"/>
   4.115 +        <condition property="do.depend.true">
   4.116 +            <istrue value="${do.depend}"/>
   4.117 +        </condition>
   4.118 +        <condition else="" property="javac.compilerargs.jaxws" value="-Djava.endorsed.dirs='${jaxws.endorsed.dir}'">
   4.119 +            <and>
   4.120 +                <isset property="jaxws.endorsed.dir"/>
   4.121 +                <available file="nbproject/jaxws-build.xml"/>
   4.122 +            </and>
   4.123 +        </condition>
   4.124 +    </target>
   4.125 +    <target name="-post-init">
   4.126 +        <!-- Empty placeholder for easier customization. -->
   4.127 +        <!-- You can override this target in the ../build.xml file. -->
   4.128 +    </target>
   4.129 +    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
   4.130 +        <fail unless="src.src.dir">Must set src.src.dir</fail>
   4.131 +        <fail unless="test.src.dir">Must set test.src.dir</fail>
   4.132 +        <fail unless="build.dir">Must set build.dir</fail>
   4.133 +        <fail unless="dist.dir">Must set dist.dir</fail>
   4.134 +        <fail unless="build.classes.dir">Must set build.classes.dir</fail>
   4.135 +        <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
   4.136 +        <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
   4.137 +        <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
   4.138 +        <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
   4.139 +        <fail unless="dist.jar">Must set dist.jar</fail>
   4.140 +    </target>
   4.141 +    <target name="-init-macrodef-property">
   4.142 +        <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
   4.143 +            <attribute name="name"/>
   4.144 +            <attribute name="value"/>
   4.145 +            <sequential>
   4.146 +                <property name="@{name}" value="${@{value}}"/>
   4.147 +            </sequential>
   4.148 +        </macrodef>
   4.149 +    </target>
   4.150 +    <target name="-init-macrodef-javac">
   4.151 +        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
   4.152 +            <attribute default="${src.src.dir}" name="srcdir"/>
   4.153 +            <attribute default="${build.classes.dir}" name="destdir"/>
   4.154 +            <attribute default="${javac.classpath}" name="classpath"/>
   4.155 +            <attribute default="${includes}" name="includes"/>
   4.156 +            <attribute default="${excludes}" name="excludes"/>
   4.157 +            <attribute default="${javac.debug}" name="debug"/>
   4.158 +            <attribute default="/does/not/exist" name="sourcepath"/>
   4.159 +            <element name="customize" optional="true"/>
   4.160 +            <sequential>
   4.161 +                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}">
   4.162 +                    <classpath>
   4.163 +                        <path path="@{classpath}"/>
   4.164 +                    </classpath>
   4.165 +                    <compilerarg line="${javac.compilerargs} ${javac.compilerargs.jaxws}"/>
   4.166 +                    <customize/>
   4.167 +                </javac>
   4.168 +            </sequential>
   4.169 +        </macrodef>
   4.170 +        <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
   4.171 +            <attribute default="${src.src.dir}" name="srcdir"/>
   4.172 +            <attribute default="${build.classes.dir}" name="destdir"/>
   4.173 +            <attribute default="${javac.classpath}" name="classpath"/>
   4.174 +            <sequential>
   4.175 +                <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
   4.176 +                    <classpath>
   4.177 +                        <path path="@{classpath}"/>
   4.178 +                    </classpath>
   4.179 +                </depend>
   4.180 +            </sequential>
   4.181 +        </macrodef>
   4.182 +        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
   4.183 +            <attribute default="${build.classes.dir}" name="destdir"/>
   4.184 +            <sequential>
   4.185 +                <fail unless="javac.includes">Must set javac.includes</fail>
   4.186 +                <pathconvert pathsep="," property="javac.includes.binary">
   4.187 +                    <path>
   4.188 +                        <filelist dir="@{destdir}" files="${javac.includes}"/>
   4.189 +                    </path>
   4.190 +                    <globmapper from="*.java" to="*.class"/>
   4.191 +                </pathconvert>
   4.192 +                <delete>
   4.193 +                    <files includes="${javac.includes.binary}"/>
   4.194 +                </delete>
   4.195 +            </sequential>
   4.196 +        </macrodef>
   4.197 +    </target>
   4.198 +    <target name="-init-macrodef-junit">
   4.199 +        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
   4.200 +            <attribute default="${includes}" name="includes"/>
   4.201 +            <attribute default="${excludes}" name="excludes"/>
   4.202 +            <attribute default="**" name="testincludes"/>
   4.203 +            <sequential>
   4.204 +                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true">
   4.205 +                    <batchtest todir="${build.test.results.dir}">
   4.206 +                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
   4.207 +                            <filename name="@{testincludes}"/>
   4.208 +                        </fileset>
   4.209 +                    </batchtest>
   4.210 +                    <classpath>
   4.211 +                        <path path="${run.test.classpath}"/>
   4.212 +                    </classpath>
   4.213 +                    <syspropertyset>
   4.214 +                        <propertyref prefix="test-sys-prop."/>
   4.215 +                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
   4.216 +                    </syspropertyset>
   4.217 +                    <formatter type="brief" usefile="false"/>
   4.218 +                    <formatter type="xml"/>
   4.219 +                    <jvmarg line="${run.jvmargs}"/>
   4.220 +                </junit>
   4.221 +            </sequential>
   4.222 +        </macrodef>
   4.223 +    </target>
   4.224 +    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
   4.225 +        <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
   4.226 +            <attribute default="${main.class}" name="name"/>
   4.227 +            <attribute default="${debug.classpath}" name="classpath"/>
   4.228 +            <attribute default="" name="stopclassname"/>
   4.229 +            <sequential>
   4.230 +                <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
   4.231 +                    <classpath>
   4.232 +                        <path path="@{classpath}"/>
   4.233 +                    </classpath>
   4.234 +                </nbjpdastart>
   4.235 +            </sequential>
   4.236 +        </macrodef>
   4.237 +        <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
   4.238 +            <attribute default="${build.classes.dir}" name="dir"/>
   4.239 +            <sequential>
   4.240 +                <nbjpdareload>
   4.241 +                    <fileset dir="@{dir}" includes="${fix.classes}">
   4.242 +                        <include name="${fix.includes}*.class"/>
   4.243 +                    </fileset>
   4.244 +                </nbjpdareload>
   4.245 +            </sequential>
   4.246 +        </macrodef>
   4.247 +    </target>
   4.248 +    <target name="-init-debug-args">
   4.249 +        <property name="version-output" value="java version &quot;${ant.java.version}"/>
   4.250 +        <condition property="have-jdk-older-than-1.4">
   4.251 +            <or>
   4.252 +                <contains string="${version-output}" substring="java version &quot;1.0"/>
   4.253 +                <contains string="${version-output}" substring="java version &quot;1.1"/>
   4.254 +                <contains string="${version-output}" substring="java version &quot;1.2"/>
   4.255 +                <contains string="${version-output}" substring="java version &quot;1.3"/>
   4.256 +            </or>
   4.257 +        </condition>
   4.258 +        <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
   4.259 +            <istrue value="${have-jdk-older-than-1.4}"/>
   4.260 +        </condition>
   4.261 +        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
   4.262 +            <os family="windows"/>
   4.263 +        </condition>
   4.264 +        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
   4.265 +            <isset property="debug.transport"/>
   4.266 +        </condition>
   4.267 +    </target>
   4.268 +    <target depends="-init-debug-args" name="-init-macrodef-debug">
   4.269 +        <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
   4.270 +            <attribute default="${main.class}" name="classname"/>
   4.271 +            <attribute default="${debug.classpath}" name="classpath"/>
   4.272 +            <element name="customize" optional="true"/>
   4.273 +            <sequential>
   4.274 +                <java classname="@{classname}" dir="${work.dir}" fork="true">
   4.275 +                    <jvmarg line="${debug-args-line}"/>
   4.276 +                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
   4.277 +                    <jvmarg line="${run.jvmargs}"/>
   4.278 +                    <classpath>
   4.279 +                        <path path="@{classpath}"/>
   4.280 +                    </classpath>
   4.281 +                    <syspropertyset>
   4.282 +                        <propertyref prefix="run-sys-prop."/>
   4.283 +                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
   4.284 +                    </syspropertyset>
   4.285 +                    <customize/>
   4.286 +                </java>
   4.287 +            </sequential>
   4.288 +        </macrodef>
   4.289 +    </target>
   4.290 +    <target name="-init-macrodef-java">
   4.291 +        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
   4.292 +            <attribute default="${main.class}" name="classname"/>
   4.293 +            <element name="customize" optional="true"/>
   4.294 +            <sequential>
   4.295 +                <java classname="@{classname}" dir="${work.dir}" fork="true">
   4.296 +                    <jvmarg line="${run.jvmargs}"/>
   4.297 +                    <classpath>
   4.298 +                        <path path="${run.classpath}"/>
   4.299 +                    </classpath>
   4.300 +                    <syspropertyset>
   4.301 +                        <propertyref prefix="run-sys-prop."/>
   4.302 +                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
   4.303 +                    </syspropertyset>
   4.304 +                    <customize/>
   4.305 +                </java>
   4.306 +            </sequential>
   4.307 +        </macrodef>
   4.308 +    </target>
   4.309 +    <target name="-init-presetdef-jar">
   4.310 +        <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
   4.311 +            <jar compress="${jar.compress}" jarfile="${dist.jar}">
   4.312 +                <j2seproject1:fileset dir="${build.classes.dir}"/>
   4.313 +            </jar>
   4.314 +        </presetdef>
   4.315 +    </target>
   4.316 +    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar" name="init"/>
   4.317 +    <!--
   4.318 +                ===================
   4.319 +                COMPILATION SECTION
   4.320 +                ===================
   4.321 +            -->
   4.322 +    <target depends="init" name="deps-jar" unless="no.deps"/>
   4.323 +    <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
   4.324 +    <target depends="init" name="-check-automatic-build">
   4.325 +        <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
   4.326 +    </target>
   4.327 +    <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
   4.328 +        <antcall target="clean"/>
   4.329 +    </target>
   4.330 +    <target depends="init,deps-jar" name="-pre-pre-compile">
   4.331 +        <mkdir dir="${build.classes.dir}"/>
   4.332 +    </target>
   4.333 +    <target name="-pre-compile">
   4.334 +        <!-- Empty placeholder for easier customization. -->
   4.335 +        <!-- You can override this target in the ../build.xml file. -->
   4.336 +    </target>
   4.337 +    <target if="do.depend.true" name="-compile-depend">
   4.338 +        <j2seproject3:depend/>
   4.339 +    </target>
   4.340 +    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-compile-depend" if="have.sources" name="-do-compile">
   4.341 +        <j2seproject3:javac/>
   4.342 +        <copy todir="${build.classes.dir}">
   4.343 +            <fileset dir="${src.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
   4.344 +        </copy>
   4.345 +    </target>
   4.346 +    <target name="-post-compile">
   4.347 +        <!-- Empty placeholder for easier customization. -->
   4.348 +        <!-- You can override this target in the ../build.xml file. -->
   4.349 +    </target>
   4.350 +    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
   4.351 +    <target name="-pre-compile-single">
   4.352 +        <!-- Empty placeholder for easier customization. -->
   4.353 +        <!-- You can override this target in the ../build.xml file. -->
   4.354 +    </target>
   4.355 +    <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
   4.356 +        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
   4.357 +        <j2seproject3:force-recompile/>
   4.358 +        <j2seproject3:javac excludes="" includes="${javac.includes}" sourcepath="${src.src.dir}"/>
   4.359 +    </target>
   4.360 +    <target name="-post-compile-single">
   4.361 +        <!-- Empty placeholder for easier customization. -->
   4.362 +        <!-- You can override this target in the ../build.xml file. -->
   4.363 +    </target>
   4.364 +    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
   4.365 +    <!--
   4.366 +                ====================
   4.367 +                JAR BUILDING SECTION
   4.368 +                ====================
   4.369 +            -->
   4.370 +    <target depends="init" name="-pre-pre-jar">
   4.371 +        <dirname file="${dist.jar}" property="dist.jar.dir"/>
   4.372 +        <mkdir dir="${dist.jar.dir}"/>
   4.373 +    </target>
   4.374 +    <target name="-pre-jar">
   4.375 +        <!-- Empty placeholder for easier customization. -->
   4.376 +        <!-- You can override this target in the ../build.xml file. -->
   4.377 +    </target>
   4.378 +    <target depends="init,compile,-pre-pre-jar,-pre-jar" name="-do-jar-without-manifest" unless="manifest.available">
   4.379 +        <j2seproject1:jar/>
   4.380 +    </target>
   4.381 +    <target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class">
   4.382 +        <j2seproject1:jar manifest="${manifest.file}"/>
   4.383 +    </target>
   4.384 +    <target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">
   4.385 +        <j2seproject1:jar manifest="${manifest.file}">
   4.386 +            <j2seproject1:manifest>
   4.387 +                <j2seproject1:attribute name="Main-Class" value="${main.class}"/>
   4.388 +            </j2seproject1:manifest>
   4.389 +        </j2seproject1:jar>
   4.390 +        <echo>To run this application from the command line without Ant, try:</echo>
   4.391 +        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
   4.392 +        <property location="${dist.jar}" name="dist.jar.resolved"/>
   4.393 +        <pathconvert property="run.classpath.with.dist.jar">
   4.394 +            <path path="${run.classpath}"/>
   4.395 +            <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
   4.396 +        </pathconvert>
   4.397 +        <echo>java -cp "${run.classpath.with.dist.jar}" ${main.class}</echo>
   4.398 +    </target>
   4.399 +    <target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class+mkdist.available" name="-do-jar-with-libraries">
   4.400 +        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
   4.401 +        <pathconvert property="run.classpath.without.build.classes.dir">
   4.402 +            <path path="${run.classpath}"/>
   4.403 +            <map from="${build.classes.dir.resolved}" to=""/>
   4.404 +        </pathconvert>
   4.405 +        <pathconvert pathsep=" " property="jar.classpath">
   4.406 +            <path path="${run.classpath.without.build.classes.dir}"/>
   4.407 +            <chainedmapper>
   4.408 +                <flattenmapper/>
   4.409 +                <globmapper from="*" to="lib/*"/>
   4.410 +            </chainedmapper>
   4.411 +        </pathconvert>
   4.412 +        <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
   4.413 +        <copylibs compress="${jar.compress}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
   4.414 +            <fileset dir="${build.classes.dir}"/>
   4.415 +            <manifest>
   4.416 +                <attribute name="Main-Class" value="${main.class}"/>
   4.417 +                <attribute name="Class-Path" value="${jar.classpath}"/>
   4.418 +            </manifest>
   4.419 +        </copylibs>
   4.420 +        <echo>To run this application from the command line without Ant, try:</echo>
   4.421 +        <property location="${dist.jar}" name="dist.jar.resolved"/>
   4.422 +        <echo>java -jar "${dist.jar.resolved}"</echo>
   4.423 +    </target>
   4.424 +    <target name="-post-jar">
   4.425 +        <!-- Empty placeholder for easier customization. -->
   4.426 +        <!-- You can override this target in the ../build.xml file. -->
   4.427 +    </target>
   4.428 +    <target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-post-jar" description="Build JAR." name="jar"/>
   4.429 +    <!--
   4.430 +                =================
   4.431 +                EXECUTION SECTION
   4.432 +                =================
   4.433 +            -->
   4.434 +    <target depends="init,compile" description="Run a main class." name="run">
   4.435 +        <j2seproject1:java>
   4.436 +            <customize>
   4.437 +                <arg line="${application.args}"/>
   4.438 +            </customize>
   4.439 +        </j2seproject1:java>
   4.440 +    </target>
   4.441 +    <target name="-do-not-recompile">
   4.442 +        <property name="javac.includes.binary" value=""/>
   4.443 +    </target>
   4.444 +    <target depends="init,-do-not-recompile,compile-single" name="run-single">
   4.445 +        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
   4.446 +        <j2seproject1:java classname="${run.class}"/>
   4.447 +    </target>
   4.448 +    <!--
   4.449 +                =================
   4.450 +                DEBUGGING SECTION
   4.451 +                =================
   4.452 +            -->
   4.453 +    <target depends="init" if="netbeans.home" name="-debug-start-debugger">
   4.454 +        <j2seproject1:nbjpdastart name="${debug.class}"/>
   4.455 +    </target>
   4.456 +    <target depends="init,compile" name="-debug-start-debuggee">
   4.457 +        <j2seproject3:debug>
   4.458 +            <customize>
   4.459 +                <arg line="${application.args}"/>
   4.460 +            </customize>
   4.461 +        </j2seproject3:debug>
   4.462 +    </target>
   4.463 +    <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
   4.464 +    <target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
   4.465 +        <j2seproject1:nbjpdastart stopclassname="${main.class}"/>
   4.466 +    </target>
   4.467 +    <target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
   4.468 +    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
   4.469 +        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
   4.470 +        <j2seproject3:debug classname="${debug.class}"/>
   4.471 +    </target>
   4.472 +    <target depends="init,-do-not-recompile,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
   4.473 +    <target depends="init" name="-pre-debug-fix">
   4.474 +        <fail unless="fix.includes">Must set fix.includes</fail>
   4.475 +        <property name="javac.includes" value="${fix.includes}.java"/>
   4.476 +    </target>
   4.477 +    <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
   4.478 +        <j2seproject1:nbjpdareload/>
   4.479 +    </target>
   4.480 +    <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
   4.481 +    <!--
   4.482 +                ===============
   4.483 +                JAVADOC SECTION
   4.484 +                ===============
   4.485 +            -->
   4.486 +    <target depends="init" name="-javadoc-build">
   4.487 +        <mkdir dir="${dist.javadoc.dir}"/>
   4.488 +        <javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
   4.489 +            <classpath>
   4.490 +                <path path="${javac.classpath}"/>
   4.491 +            </classpath>
   4.492 +            <fileset dir="${src.src.dir}" excludes="${excludes}" includes="${includes}">
   4.493 +                <filename name="**/*.java"/>
   4.494 +            </fileset>
   4.495 +        </javadoc>
   4.496 +    </target>
   4.497 +    <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
   4.498 +        <nbbrowse file="${dist.javadoc.dir}/index.html"/>
   4.499 +    </target>
   4.500 +    <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
   4.501 +    <!--
   4.502 +                =========================
   4.503 +                JUNIT COMPILATION SECTION
   4.504 +                =========================
   4.505 +            -->
   4.506 +    <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
   4.507 +        <mkdir dir="${build.test.classes.dir}"/>
   4.508 +    </target>
   4.509 +    <target name="-pre-compile-test">
   4.510 +        <!-- Empty placeholder for easier customization. -->
   4.511 +        <!-- You can override this target in the ../build.xml file. -->
   4.512 +    </target>
   4.513 +    <target if="do.depend.true" name="-compile-test-depend">
   4.514 +        <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
   4.515 +    </target>
   4.516 +    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
   4.517 +        <j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
   4.518 +        <copy todir="${build.test.classes.dir}">
   4.519 +            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
   4.520 +        </copy>
   4.521 +    </target>
   4.522 +    <target name="-post-compile-test">
   4.523 +        <!-- Empty placeholder for easier customization. -->
   4.524 +        <!-- You can override this target in the ../build.xml file. -->
   4.525 +    </target>
   4.526 +    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
   4.527 +    <target name="-pre-compile-test-single">
   4.528 +        <!-- Empty placeholder for easier customization. -->
   4.529 +        <!-- You can override this target in the ../build.xml file. -->
   4.530 +    </target>
   4.531 +    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
   4.532 +        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
   4.533 +        <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
   4.534 +        <j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/>
   4.535 +        <copy todir="${build.test.classes.dir}">
   4.536 +            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
   4.537 +        </copy>
   4.538 +    </target>
   4.539 +    <target name="-post-compile-test-single">
   4.540 +        <!-- Empty placeholder for easier customization. -->
   4.541 +        <!-- You can override this target in the ../build.xml file. -->
   4.542 +    </target>
   4.543 +    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
   4.544 +    <!--
   4.545 +                =======================
   4.546 +                JUNIT EXECUTION SECTION
   4.547 +                =======================
   4.548 +            -->
   4.549 +    <target depends="init" if="have.tests" name="-pre-test-run">
   4.550 +        <mkdir dir="${build.test.results.dir}"/>
   4.551 +    </target>
   4.552 +    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
   4.553 +        <j2seproject3:junit testincludes="**/*Test.java"/>
   4.554 +    </target>
   4.555 +    <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
   4.556 +        <fail if="tests.failed">Some tests failed; see details above.</fail>
   4.557 +    </target>
   4.558 +    <target depends="init" if="have.tests" name="test-report"/>
   4.559 +    <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
   4.560 +    <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
   4.561 +    <target depends="init" if="have.tests" name="-pre-test-run-single">
   4.562 +        <mkdir dir="${build.test.results.dir}"/>
   4.563 +    </target>
   4.564 +    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
   4.565 +        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
   4.566 +        <j2seproject3:junit excludes="" includes="${test.includes}"/>
   4.567 +    </target>
   4.568 +    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
   4.569 +        <fail if="tests.failed">Some tests failed; see details above.</fail>
   4.570 +    </target>
   4.571 +    <target depends="init,-do-not-recompile,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
   4.572 +    <!--
   4.573 +                =======================
   4.574 +                JUNIT DEBUGGING SECTION
   4.575 +                =======================
   4.576 +            -->
   4.577 +    <target depends="init,compile-test" if="have.tests" name="-debug-start-debuggee-test">
   4.578 +        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
   4.579 +        <property location="${build.test.results.dir}/TEST-${test.class}.xml" name="test.report.file"/>
   4.580 +        <delete file="${test.report.file}"/>
   4.581 +        <mkdir dir="${build.test.results.dir}"/>
   4.582 +        <j2seproject3:debug classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" classpath="${ant.home}/lib/ant.jar:${ant.home}/lib/ant-junit.jar:${debug.test.classpath}">
   4.583 +            <customize>
   4.584 +                <syspropertyset>
   4.585 +                    <propertyref prefix="test-sys-prop."/>
   4.586 +                    <mapper from="test-sys-prop.*" to="*" type="glob"/>
   4.587 +                </syspropertyset>
   4.588 +                <arg value="${test.class}"/>
   4.589 +                <arg value="showoutput=true"/>
   4.590 +                <arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter"/>
   4.591 +                <arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,${test.report.file}"/>
   4.592 +            </customize>
   4.593 +        </j2seproject3:debug>
   4.594 +    </target>
   4.595 +    <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
   4.596 +        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
   4.597 +    </target>
   4.598 +    <target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
   4.599 +    <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
   4.600 +        <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
   4.601 +    </target>
   4.602 +    <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
   4.603 +    <!--
   4.604 +                =========================
   4.605 +                APPLET EXECUTION SECTION
   4.606 +                =========================
   4.607 +            -->
   4.608 +    <target depends="init,compile-single" name="run-applet">
   4.609 +        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
   4.610 +        <j2seproject1:java classname="sun.applet.AppletViewer">
   4.611 +            <customize>
   4.612 +                <arg value="${applet.url}"/>
   4.613 +            </customize>
   4.614 +        </j2seproject1:java>
   4.615 +    </target>
   4.616 +    <!--
   4.617 +                =========================
   4.618 +                APPLET DEBUGGING  SECTION
   4.619 +                =========================
   4.620 +            -->
   4.621 +    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
   4.622 +        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
   4.623 +        <j2seproject3:debug classname="sun.applet.AppletViewer">
   4.624 +            <customize>
   4.625 +                <arg value="${applet.url}"/>
   4.626 +            </customize>
   4.627 +        </j2seproject3:debug>
   4.628 +    </target>
   4.629 +    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
   4.630 +    <!--
   4.631 +                ===============
   4.632 +                CLEANUP SECTION
   4.633 +                ===============
   4.634 +            -->
   4.635 +    <target depends="init" name="deps-clean" unless="no.deps"/>
   4.636 +    <target depends="init" name="-do-clean">
   4.637 +        <delete dir="${build.dir}"/>
   4.638 +        <delete dir="${dist.dir}"/>
   4.639 +    </target>
   4.640 +    <target name="-post-clean">
   4.641 +        <!-- Empty placeholder for easier customization. -->
   4.642 +        <!-- You can override this target in the ../build.xml file. -->
   4.643 +    </target>
   4.644 +    <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
   4.645 +</project>
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/make/netbeans/jdwpgen/nbproject/findbugs.settings	Tue Sep 01 13:03:09 2009 -0700
     5.3 @@ -0,0 +1,72 @@
     5.4 +#FindBugs User Preferences
     5.5 +#Mon Jun 15 13:37:16 PDT 2009
     5.6 +detectorAbnormalFinallyBlockReturn=AbnormalFinallyBlockReturn|false
     5.7 +detectorAbstractClassEmptyMethods=AbstractClassEmptyMethods|false
     5.8 +detectorAbstractOverriddenMethod=AbstractOverriddenMethod|false
     5.9 +detectorArrayBasedCollections=ArrayBasedCollections|false
    5.10 +detectorArrayWrappedCallByReference=ArrayWrappedCallByReference|false
    5.11 +detectorBloatedAssignmentScope=BloatedAssignmentScope|false
    5.12 +detectorBloatedSynchronizedBlock=BloatedSynchronizedBlock|false
    5.13 +detectorClassEnvy=ClassEnvy|false
    5.14 +detectorCollectStatistics=CollectStatistics|false
    5.15 +detectorConfusingAutoboxedOverloading=ConfusingAutoboxedOverloading|false
    5.16 +detectorConstantListIndex=ConstantListIndex|false
    5.17 +detectorCopiedOverriddenMethod=CopiedOverriddenMethod|false
    5.18 +detectorCustomBuiltXML=CustomBuiltXML|false
    5.19 +detectorCyclomaticComplexity=CyclomaticComplexity|false
    5.20 +detectorDateComparison=DateComparison|false
    5.21 +detectorDeclaredRuntimeException=DeclaredRuntimeException|false
    5.22 +detectorDeletingWhileIterating=DeletingWhileIterating|false
    5.23 +detectorDubiousListCollection=DubiousListCollection|false
    5.24 +detectorFieldCouldBeLocal=FieldCouldBeLocal|false
    5.25 +detectorFinalParameters=FinalParameters|false
    5.26 +detectorFloatingPointLoops=FloatingPointLoops|false
    5.27 +detectorInefficientStringBuffering=InefficientStringBuffering|false
    5.28 +detectorInheritanceTypeChecking=InheritanceTypeChecking|false
    5.29 +detectorJDBCVendorReliance=JDBCVendorReliance|false
    5.30 +detectorListIndexedIterating=ListIndexedIterating|false
    5.31 +detectorLiteralStringComparison=LiteralStringComparison|false
    5.32 +detectorLocalSynchronizedCollection=LocalSynchronizedCollection|false
    5.33 +detectorLostExceptionStackTrace=LostExceptionStackTrace|false
    5.34 +detectorManualArrayCopy=ManualArrayCopy|false
    5.35 +detectorMethodReturnsConstant=MethodReturnsConstant|false
    5.36 +detectorNeedlessAutoboxing=NeedlessAutoboxing|false
    5.37 +detectorNeedlessCustomSerialization=NeedlessCustomSerialization|false
    5.38 +detectorNeedlessInstanceRetrieval=NeedlessInstanceRetrieval|false
    5.39 +detectorNeedlessMemberCollectionSynchronization=NeedlessMemberCollectionSynchronization|false
    5.40 +detectorNonCollectionMethodUse=NonCollectionMethodUse|false
    5.41 +detectorNonOwnedSynchronization=NonOwnedSynchronization|false
    5.42 +detectorNonRecycleableTaglibs=NonRecycleableTaglibs|false
    5.43 +detectorOrphanedDOMNode=OrphanedDOMNode|false
    5.44 +detectorOverlyConcreteParameter=OverlyConcreteParameter|false
    5.45 +detectorParallelLists=ParallelLists|false
    5.46 +detectorPartiallyConstructedObjectAccess=PartiallyConstructedObjectAccess|false
    5.47 +detectorPossibleIncompleteSerialization=PossibleIncompleteSerialization|false
    5.48 +detectorPossibleMemoryBloat=PossibleMemoryBloat|false
    5.49 +detectorPossiblyRedundantMethodCalls=PossiblyRedundantMethodCalls|false
    5.50 +detectorSQLInLoop=SQLInLoop|false
    5.51 +detectorSection508Compliance=Section508Compliance|false
    5.52 +detectorSillynessPotPourri=SillynessPotPourri|false
    5.53 +detectorSloppyClassReflection=SloppyClassReflection|false
    5.54 +detectorSluggishGui=SluggishGui|false
    5.55 +detectorSpoiledChildInterfaceImplementor=SpoiledChildInterfaceImplementor|false
    5.56 +detectorSpuriousThreadStates=SpuriousThreadStates|false
    5.57 +detectorStaticArrayCreatedInMethod=StaticArrayCreatedInMethod|false
    5.58 +detectorStaticMethodInstanceInvocation=StaticMethodInstanceInvocation|false
    5.59 +detectorSuspiciousComparatorReturnValues=SuspiciousComparatorReturnValues|false
    5.60 +detectorSuspiciousJDKVersionUse=SuspiciousJDKVersionUse|false
    5.61 +detectorSuspiciousWaitOnConcurrentObject=SuspiciousWaitOnConcurrentObject|false
    5.62 +detectorSyncCollectionIterators=SyncCollectionIterators|false
    5.63 +detectorTailRecursion=TailRecursion|false
    5.64 +detectorUnnecessaryStoreBeforeReturn=UnnecessaryStoreBeforeReturn|false
    5.65 +detectorUnrelatedCollectionContents=UnrelatedCollectionContents|false
    5.66 +detectorUnrelatedReturnValues=UnrelatedReturnValues|false
    5.67 +detectorUseAddAll=UseAddAll|false
    5.68 +detectorUseCharacterParameterizedMethod=UseCharacterParameterizedMethod|false
    5.69 +detectorUseEnumCollections=UseEnumCollections|false
    5.70 +detectorUseSplit=UseSplit|false
    5.71 +detectorUseToArray=UseToArray|false
    5.72 +detector_threshold=2
    5.73 +effort=default
    5.74 +filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,I18N,MALICIOUS_CODE,MT_CORRECTNESS,PERFORMANCE,SECURITY,STYLE|false
    5.75 +filter_settings_neg=|
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/make/netbeans/jdwpgen/nbproject/genfiles.properties	Tue Sep 01 13:03:09 2009 -0700
     6.3 @@ -0,0 +1,8 @@
     6.4 +build.xml.data.CRC32=b40e775f
     6.5 +build.xml.script.CRC32=af8dc3cb
     6.6 +build.xml.stylesheet.CRC32=958a1d3e
     6.7 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
     6.8 +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
     6.9 +nbproject/build-impl.xml.data.CRC32=b40e775f
    6.10 +nbproject/build-impl.xml.script.CRC32=624d12c5
    6.11 +nbproject/build-impl.xml.stylesheet.CRC32=65b8de21
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/make/netbeans/jdwpgen/nbproject/project.properties	Tue Sep 01 13:03:09 2009 -0700
     7.3 @@ -0,0 +1,65 @@
     7.4 +application.title=jdwpgen
     7.5 +application.vendor=sun
     7.6 +build.classes.dir=${build.dir}/classes
     7.7 +build.classes.excludes=**/*.java,**/*.form
     7.8 +# This directory is removed when the project is cleaned:
     7.9 +build.dir=build
    7.10 +build.generated.dir=${build.dir}/generated
    7.11 +# Only compile against the classpath explicitly listed here:
    7.12 +build.sysclasspath=ignore
    7.13 +build.test.classes.dir=${build.dir}/test/classes
    7.14 +build.test.results.dir=${build.dir}/test/results
    7.15 +# Uncomment to specify the preferred debugger connection transport:
    7.16 +#debug.transport=dt_socket
    7.17 +debug.classpath=\
    7.18 +    ${run.classpath}
    7.19 +debug.test.classpath=\
    7.20 +    ${run.test.classpath}
    7.21 +# This directory is removed when the project is cleaned:
    7.22 +dist.dir=dist
    7.23 +dist.jar=${dist.dir}/jdwpgen.jar
    7.24 +dist.javadoc.dir=${dist.dir}/javadoc
    7.25 +excludes=
    7.26 +file.reference.tools-jdwpgen=../../tools/src/build/tools/jdwpgen
    7.27 +file.reference.tools-src=../../tools/src
    7.28 +includes=build/tools/jdwpgen/**
    7.29 +jar.compress=false
    7.30 +javac.classpath=
    7.31 +# Space-separated list of extra javac options
    7.32 +javac.compilerargs=-Xlint:all
    7.33 +javac.deprecation=false
    7.34 +javac.source=1.5
    7.35 +javac.target=1.5
    7.36 +javac.test.classpath=\
    7.37 +    ${javac.classpath}:\
    7.38 +    ${build.classes.dir}:\
    7.39 +    ${libs.junit.classpath}:\
    7.40 +    ${libs.junit_4.classpath}
    7.41 +javadoc.additionalparam=
    7.42 +javadoc.author=false
    7.43 +javadoc.encoding=${source.encoding}
    7.44 +javadoc.noindex=true
    7.45 +javadoc.nonavbar=true
    7.46 +javadoc.notree=true
    7.47 +javadoc.private=true
    7.48 +javadoc.splitindex=false
    7.49 +javadoc.use=false
    7.50 +javadoc.version=false
    7.51 +javadoc.windowtitle=
    7.52 +main.class=jdwpgen.Main
    7.53 +manifest.file=manifest.mf
    7.54 +meta.inf.dir=${src.dir}/META-INF
    7.55 +platform.active=default_platform
    7.56 +run.classpath=\
    7.57 +    ${javac.classpath}:\
    7.58 +    ${build.classes.dir}
    7.59 +# Space-separated list of JVM arguments used when running the project
    7.60 +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
    7.61 +# or test-sys-prop.name=value to set system properties for unit tests):
    7.62 +run.jvmargs=
    7.63 +run.test.classpath=\
    7.64 +    ${javac.test.classpath}:\
    7.65 +    ${build.test.classes.dir}
    7.66 +source.encoding=UTF-8
    7.67 +src.src.dir=${file.reference.tools-src}
    7.68 +test.src.dir=test
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/make/netbeans/jdwpgen/nbproject/project.xml	Tue Sep 01 13:03:09 2009 -0700
     8.3 @@ -0,0 +1,16 @@
     8.4 +<?xml version="1.0" encoding="UTF-8"?>
     8.5 +<project xmlns="http://www.netbeans.org/ns/project/1">
     8.6 +    <type>org.netbeans.modules.java.j2seproject</type>
     8.7 +    <configuration>
     8.8 +        <data xmlns="http://www.netbeans.org/ns/j2se-project/3">
     8.9 +            <name>jdwpgen</name>
    8.10 +            <minimum-ant-version>1.6.5</minimum-ant-version>
    8.11 +            <source-roots>
    8.12 +                <root id="src.src.dir"/>
    8.13 +            </source-roots>
    8.14 +            <test-roots>
    8.15 +                <root id="test.src.dir"/>
    8.16 +            </test-roots>
    8.17 +        </data>
    8.18 +    </configuration>
    8.19 +</project>
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/make/netbeans/jdwpgen/nbproject/sqe.properties	Tue Sep 01 13:03:09 2009 -0700
     9.3 @@ -0,0 +1,2 @@
     9.4 +#Path to FindbugsSettingsFile (relative)
     9.5 +findbugs.settings.file=findbugs.settings
    10.1 --- a/make/tools/src/build/tools/jdwpgen/AbstractNamedNode.java	Mon Aug 24 17:26:09 2009 -0700
    10.2 +++ b/make/tools/src/build/tools/jdwpgen/AbstractNamedNode.java	Tue Sep 01 13:03:09 2009 -0700
    10.3 @@ -30,7 +30,7 @@
    10.4  
    10.5  abstract class AbstractNamedNode extends Node {
    10.6  
    10.7 -    NameNode nameNode;
    10.8 +    NameNode nameNode = null;
    10.9      String name;
   10.10  
   10.11      public String name() {
    11.1 --- a/make/tools/src/build/tools/jdwpgen/AltNode.java	Mon Aug 24 17:26:09 2009 -0700
    11.2 +++ b/make/tools/src/build/tools/jdwpgen/AltNode.java	Tue Sep 01 13:03:09 2009 -0700
    11.3 @@ -30,7 +30,7 @@
    11.4  
    11.5  class AltNode extends AbstractGroupNode implements TypeNode {
    11.6  
    11.7 -    SelectNode select;
    11.8 +    SelectNode select = null;
    11.9  
   11.10      void constrain(Context ctx) {
   11.11          super.constrain(ctx);
    12.1 --- a/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java	Mon Aug 24 17:26:09 2009 -0700
    12.2 +++ b/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java	Tue Sep 01 13:03:09 2009 -0700
    12.3 @@ -33,13 +33,7 @@
    12.4      /**
    12.5       * The mapping between a constant and its value.
    12.6       */
    12.7 -    protected static Map<String, String> constantMap;
    12.8 -
    12.9 -    ConstantSetNode(){
   12.10 -        if (constantMap == null) {
   12.11 -            constantMap = new HashMap<String, String>();
   12.12 -        }
   12.13 -    }
   12.14 +    protected static final Map<String, String> constantMap = new HashMap<String, String>();
   12.15  
   12.16      void prune() {
   12.17          List<Node> addons = new ArrayList<Node>();
   12.18 @@ -95,9 +89,6 @@
   12.19      }
   12.20  
   12.21      public static String getConstant(String key){
   12.22 -        if (constantMap == null) {
   12.23 -            return "";
   12.24 -        }
   12.25          String com = constantMap.get(key);
   12.26          if(com == null){
   12.27              return "";
    13.1 --- a/make/tools/src/build/tools/jdwpgen/Main.java	Mon Aug 24 17:26:09 2009 -0700
    13.2 +++ b/make/tools/src/build/tools/jdwpgen/Main.java	Tue Sep 01 13:03:09 2009 -0700
    13.3 @@ -25,13 +25,11 @@
    13.4  
    13.5  package build.tools.jdwpgen;
    13.6  
    13.7 -import java.util.*;
    13.8  import java.io.*;
    13.9  
   13.10  class Main {
   13.11  
   13.12      static String specSource;
   13.13 -    static Map nameMap = new HashMap();
   13.14      static boolean genDebug = true;
   13.15  
   13.16      static void usage() {
   13.17 @@ -43,7 +41,6 @@
   13.18          System.err.println("-doc <doc_output>");
   13.19          System.err.println("-jdi <java_output>");
   13.20          System.err.println("-include <include_file_output>");
   13.21 -        System.exit(1);
   13.22      }
   13.23  
   13.24      public static void main(String args[]) throws IOException {
   13.25 @@ -66,6 +63,7 @@
   13.26                  } else {
   13.27                      System.err.println("Invalid option: " + arg);
   13.28                      usage();
   13.29 +                    return;
   13.30                  }
   13.31              } else {
   13.32                  specSource = arg;
   13.33 @@ -75,6 +73,7 @@
   13.34          if (reader == null) {
   13.35              System.err.println("<spec_input> must be specified");
   13.36              usage();
   13.37 +            return;
   13.38          }
   13.39  
   13.40          Parse parse = new Parse(reader);
    14.1 --- a/make/tools/src/build/tools/jdwpgen/Node.java	Mon Aug 24 17:26:09 2009 -0700
    14.2 +++ b/make/tools/src/build/tools/jdwpgen/Node.java	Tue Sep 01 13:03:09 2009 -0700
    14.3 @@ -36,7 +36,7 @@
    14.4      int lineno;
    14.5      List<String> commentList = new ArrayList<String>();
    14.6      Node parent = null;
    14.7 -    Context context;
    14.8 +    Context context = null;
    14.9  
   14.10      static final int maxStructIndent = 5;
   14.11      static int structIndent = 0; // horrible hack
   14.12 @@ -82,7 +82,7 @@
   14.13      }
   14.14  
   14.15      void indent(PrintWriter writer, int depth) {
   14.16 -        for (int i = depth; i > 0; --i) {
   14.17 +        for (int i = 0; i < depth; i++) {
   14.18              writer.print("    ");
   14.19          }
   14.20      }
   14.21 @@ -195,6 +195,6 @@
   14.22          System.err.println(Main.specSource + ":" + lineno + ": " +
   14.23                             kind + " - " + errmsg);
   14.24          System.err.println();
   14.25 -        System.exit(1);
   14.26 +        throw new RuntimeException("Error: " + errmsg);
   14.27      }
   14.28  }
    15.1 --- a/make/tools/src/build/tools/jdwpgen/Parse.java	Mon Aug 24 17:26:09 2009 -0700
    15.2 +++ b/make/tools/src/build/tools/jdwpgen/Parse.java	Tue Sep 01 13:03:09 2009 -0700
    15.3 @@ -146,8 +146,12 @@
    15.4                              Node node = (Node)proto.getClass().newInstance();
    15.5                              node.set(kind, list, izer.lineno());
    15.6                              return node;
    15.7 -                        } catch (Exception exc) {
    15.8 +                        } catch (InstantiationException exc) {
    15.9                              error(exc.toString());
   15.10 +                            return null;
   15.11 +                        } catch (IllegalAccessException exc) {
   15.12 +                            error(exc.toString());
   15.13 +                            return null;
   15.14                          }
   15.15                      }
   15.16                  } else {
   15.17 @@ -166,6 +170,6 @@
   15.18      void error(String errmsg) {
   15.19          System.err.println(Main.specSource + ":" + izer.lineno() +
   15.20                             ": " + errmsg);
   15.21 -        System.exit(1);
   15.22 +        throw new RuntimeException("Error: " + errmsg);
   15.23      }
   15.24  }
    16.1 --- a/make/tools/src/build/tools/jdwpgen/RepeatNode.java	Mon Aug 24 17:26:09 2009 -0700
    16.2 +++ b/make/tools/src/build/tools/jdwpgen/RepeatNode.java	Tue Sep 01 13:03:09 2009 -0700
    16.3 @@ -30,7 +30,7 @@
    16.4  
    16.5  class RepeatNode extends AbstractTypeNode {
    16.6  
    16.7 -    Node member;
    16.8 +    Node member = null;
    16.9  
   16.10      void constrain(Context ctx) {
   16.11          super.constrain(ctx);
    17.1 --- a/make/tools/src/build/tools/jdwpgen/SelectNode.java	Mon Aug 24 17:26:09 2009 -0700
    17.2 +++ b/make/tools/src/build/tools/jdwpgen/SelectNode.java	Tue Sep 01 13:03:09 2009 -0700
    17.3 @@ -30,7 +30,7 @@
    17.4  
    17.5  class SelectNode extends AbstractGroupNode implements TypeNode {
    17.6  
    17.7 -    AbstractSimpleTypeNode typeNode;
    17.8 +    AbstractSimpleTypeNode typeNode = null;
    17.9  
   17.10      void prune() {
   17.11          super.prune();
    18.1 --- a/src/share/classes/com/sun/security/auth/callback/TextCallbackHandler.java	Mon Aug 24 17:26:09 2009 -0700
    18.2 +++ b/src/share/classes/com/sun/security/auth/callback/TextCallbackHandler.java	Tue Sep 01 13:03:09 2009 -0700
    18.3 @@ -129,7 +129,7 @@
    18.4                  System.err.print(pc.getPrompt());
    18.5                  System.err.flush();
    18.6  
    18.7 -                pc.setPassword(Password.readPassword(System.in));
    18.8 +                pc.setPassword(Password.readPassword(System.in, pc.isEchoOn()));
    18.9  
   18.10              } else if (callbacks[i] instanceof ConfirmationCallback) {
   18.11                  confirmation = (ConfirmationCallback) callbacks[i];
    19.1 --- a/src/share/classes/com/sun/security/sasl/Provider.java	Mon Aug 24 17:26:09 2009 -0700
    19.2 +++ b/src/share/classes/com/sun/security/sasl/Provider.java	Tue Sep 01 13:03:09 2009 -0700
    19.3 @@ -51,7 +51,7 @@
    19.4          " server mechanisms for: DIGEST-MD5, GSSAPI, CRAM-MD5)";
    19.5  
    19.6      public Provider() {
    19.7 -        super("SunSASL", 1.5, info);
    19.8 +        super("SunSASL", 1.7d, info);
    19.9  
   19.10          AccessController.doPrivileged(new PrivilegedAction<Void>() {
   19.11              public Void run() {
    20.1 --- a/src/share/classes/java/lang/EnumConstantNotPresentException.java	Mon Aug 24 17:26:09 2009 -0700
    20.2 +++ b/src/share/classes/java/lang/EnumConstantNotPresentException.java	Tue Sep 01 13:03:09 2009 -0700
    20.3 @@ -28,8 +28,12 @@
    20.4  /**
    20.5   * Thrown when an application tries to access an enum constant by name
    20.6   * and the enum type contains no constant with the specified name.
    20.7 + * This exception can be thrown by the {@linkplain
    20.8 + * java.lang.reflect.AnnotatedElement API used to read annotations
    20.9 + * reflectively}.
   20.10   *
   20.11   * @author  Josh Bloch
   20.12 + * @see     java.lang.reflect.AnnotatedElement
   20.13   * @since   1.5
   20.14   */
   20.15  public class EnumConstantNotPresentException extends RuntimeException {
    21.1 --- a/src/share/classes/java/lang/String.java	Mon Aug 24 17:26:09 2009 -0700
    21.2 +++ b/src/share/classes/java/lang/String.java	Tue Sep 01 13:03:09 2009 -0700
    21.3 @@ -2301,6 +2301,54 @@
    21.4       * @spec JSR-51
    21.5       */
    21.6      public String[] split(String regex, int limit) {
    21.7 +        /* fastpath if the regex is a
    21.8 +           (1)one-char String and this character is not one of the
    21.9 +              RegEx's meta characters ".$|()[{^?*+\\", or
   21.10 +           (2)two-char String and the first char is the backslash and
   21.11 +              the second is not the ascii digit or ascii letter.
   21.12 +        */
   21.13 +        char ch = 0;
   21.14 +        if (((regex.count == 1 &&
   21.15 +             ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
   21.16 +             (regex.length() == 2 &&
   21.17 +              regex.charAt(0) == '\\' &&
   21.18 +              (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
   21.19 +              ((ch-'a')|('z'-ch)) < 0 &&
   21.20 +              ((ch-'A')|('Z'-ch)) < 0)) &&
   21.21 +            (ch < Character.MIN_HIGH_SURROGATE ||
   21.22 +             ch > Character.MAX_LOW_SURROGATE))
   21.23 +        {
   21.24 +            int off = 0;
   21.25 +            int next = 0;
   21.26 +            boolean limited = limit > 0;
   21.27 +            ArrayList<String> list = new ArrayList<String>();
   21.28 +            while ((next = indexOf(ch, off)) != -1) {
   21.29 +                if (!limited || list.size() < limit - 1) {
   21.30 +                    list.add(substring(off, next));
   21.31 +                    off = next + 1;
   21.32 +                } else {    // last one
   21.33 +                    //assert (list.size() == limit - 1);
   21.34 +                    list.add(substring(off, count));
   21.35 +                    off = count;
   21.36 +                    break;
   21.37 +                }
   21.38 +            }
   21.39 +            // If no match was found, return this
   21.40 +            if (off == 0)
   21.41 +                return new String[] { this };
   21.42 +
   21.43 +            // Add remaining segment
   21.44 +            if (!limited || list.size() < limit)
   21.45 +                list.add(substring(off, count));
   21.46 +
   21.47 +            // Construct result
   21.48 +            int resultSize = list.size();
   21.49 +            if (limit == 0)
   21.50 +                while (resultSize > 0 && list.get(resultSize-1).length() == 0)
   21.51 +                    resultSize--;
   21.52 +            String[] result = new String[resultSize];
   21.53 +            return list.subList(0, resultSize).toArray(result);
   21.54 +        }
   21.55          return Pattern.compile(regex).split(this, limit);
   21.56      }
   21.57  
    22.1 --- a/src/share/classes/java/lang/TypeNotPresentException.java	Mon Aug 24 17:26:09 2009 -0700
    22.2 +++ b/src/share/classes/java/lang/TypeNotPresentException.java	Tue Sep 01 13:03:09 2009 -0700
    22.3 @@ -35,8 +35,12 @@
    22.4   * <p>Note that this exception may be used when undefined type variables
    22.5   * are accessed as well as when types (e.g., classes, interfaces or
    22.6   * annotation types) are loaded.
    22.7 + * In particular, this exception can be thrown by the {@linkplain
    22.8 + * java.lang.reflect.AnnotatedElement API used to read annotations
    22.9 + * reflectively}.
   22.10   *
   22.11   * @author  Josh Bloch
   22.12 + * @see     java.lang.reflect.AnnotatedElement
   22.13   * @since 1.5
   22.14   */
   22.15  public class TypeNotPresentException extends RuntimeException {
    23.1 --- a/src/share/classes/java/lang/annotation/AnnotationFormatError.java	Mon Aug 24 17:26:09 2009 -0700
    23.2 +++ b/src/share/classes/java/lang/annotation/AnnotationFormatError.java	Tue Sep 01 13:03:09 2009 -0700
    23.3 @@ -28,8 +28,12 @@
    23.4  /**
    23.5   * Thrown when the annotation parser attempts to read an annotation
    23.6   * from a class file and determines that the annotation is malformed.
    23.7 + * This error can be thrown by the {@linkplain
    23.8 + * java.lang.reflect.AnnotatedElement API used to read annotations
    23.9 + * reflectively}.
   23.10   *
   23.11   * @author  Josh Bloch
   23.12 + * @see     java.lang.reflect.AnnotatedElement
   23.13   * @since   1.5
   23.14   */
   23.15  public class AnnotationFormatError extends Error {
    24.1 --- a/src/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java	Mon Aug 24 17:26:09 2009 -0700
    24.2 +++ b/src/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java	Tue Sep 01 13:03:09 2009 -0700
    24.3 @@ -30,8 +30,12 @@
    24.4   * Thrown to indicate that a program has attempted to access an element of
    24.5   * an annotation whose type has changed after the annotation was compiled
    24.6   * (or serialized).
    24.7 + * This exception can be thrown by the {@linkplain
    24.8 + * java.lang.reflect.AnnotatedElement API used to read annotations
    24.9 + * reflectively}.
   24.10   *
   24.11   * @author  Josh Bloch
   24.12 + * @see     java.lang.reflect.AnnotatedElement
   24.13   * @since 1.5
   24.14   */
   24.15  public class AnnotationTypeMismatchException extends RuntimeException {
    25.1 --- a/src/share/classes/java/lang/annotation/IncompleteAnnotationException.java	Mon Aug 24 17:26:09 2009 -0700
    25.2 +++ b/src/share/classes/java/lang/annotation/IncompleteAnnotationException.java	Tue Sep 01 13:03:09 2009 -0700
    25.3 @@ -30,8 +30,12 @@
    25.4   * an annotation type that was added to the annotation type definition after
    25.5   * the annotation was compiled (or serialized).  This exception will not be
    25.6   * thrown if the new element has a default value.
    25.7 + * This exception can be thrown by the {@linkplain
    25.8 + * java.lang.reflect.AnnotatedElement API used to read annotations
    25.9 + * reflectively}.
   25.10   *
   25.11   * @author  Josh Bloch
   25.12 + * @see     java.lang.reflect.AnnotatedElement
   25.13   * @since 1.5
   25.14   */
   25.15  public class IncompleteAnnotationException extends RuntimeException {
    26.1 --- a/src/share/classes/java/lang/reflect/AnnotatedElement.java	Mon Aug 24 17:26:09 2009 -0700
    26.2 +++ b/src/share/classes/java/lang/reflect/AnnotatedElement.java	Tue Sep 01 13:03:09 2009 -0700
    26.3 @@ -50,6 +50,11 @@
    26.4   * java.lang.annotation.AnnotationTypeMismatchException} or an
    26.5   * {@link java.lang.annotation.IncompleteAnnotationException}.
    26.6   *
    26.7 + * @see java.lang.EnumConstantNotPresentException
    26.8 + * @see java.lang.TypeNotPresentException
    26.9 + * @see java.lang.annotation.AnnotationFormatError
   26.10 + * @see java.lang.annotation.AnnotationTypeMismatchException
   26.11 + * @see java.lang.annotation.IncompleteAnnotationException
   26.12   * @since 1.5
   26.13   * @author Josh Bloch
   26.14   */
    27.1 --- a/src/share/classes/java/nio/channels/AsynchronousByteChannel.java	Mon Aug 24 17:26:09 2009 -0700
    27.2 +++ b/src/share/classes/java/nio/channels/AsynchronousByteChannel.java	Tue Sep 01 13:03:09 2009 -0700
    27.3 @@ -56,18 +56,18 @@
    27.4      /**
    27.5       * Reads a sequence of bytes from this channel into the given buffer.
    27.6       *
    27.7 -     * <p> This method initiates an operation to read a sequence of bytes from
    27.8 -     * this channel into the given buffer. The method returns a {@link Future}
    27.9 -     * representing the pending result of the operation. The result of the
   27.10 -     * operation, obtained by invoking the {@code Future} 's {@link
   27.11 -     * Future#get() get} method, is the number of bytes read or {@code -1} if
   27.12 -     * all bytes have been read and the channel has reached end-of-stream.
   27.13 +     * <p> This method initiates an asynchronous read operation to read a
   27.14 +     * sequence of bytes from this channel into the given buffer. The {@code
   27.15 +     * handler} parameter is a completion handler that is invoked when the read
   27.16 +     * operation completes (or fails). The result passed to the completion
   27.17 +     * handler is the number of bytes read or {@code -1} if no bytes could be
   27.18 +     * read because the channel has reached end-of-stream.
   27.19       *
   27.20 -     * <p> This method initiates a read operation to read up to <i>r</i> bytes
   27.21 -     * from the channel, where <i>r</i> is the number of bytes remaining in the
   27.22 -     * buffer, that is, {@code dst.remaining()} at the time that the read is
   27.23 -     * attempted. Where <i>r</i> is 0, the read operation completes immediately
   27.24 -     * with a result of {@code 0} without initiating an I/O operation.
   27.25 +     * <p> The read operation may read up to <i>r</i> bytes from the channel,
   27.26 +     * where <i>r</i> is the number of bytes remaining in the buffer, that is,
   27.27 +     * {@code dst.remaining()} at the time that the read is attempted. Where
   27.28 +     * <i>r</i> is 0, the read operation completes immediately with a result of
   27.29 +     * {@code 0} without initiating an I/O operation.
   27.30       *
   27.31       * <p> Suppose that a byte sequence of length <i>n</i> is read, where
   27.32       * <tt>0</tt>&nbsp;<tt>&lt;</tt>&nbsp;<i>n</i>&nbsp;<tt>&lt;=</tt>&nbsp;<i>r</i>.
   27.33 @@ -79,44 +79,46 @@
   27.34       * <i>p</i>&nbsp;<tt>+</tt>&nbsp;<i>n</i>; its limit will not have changed.
   27.35       *
   27.36       * <p> Buffers are not safe for use by multiple concurrent threads so care
   27.37 -     * should be taken to not to access the buffer until the operaton has completed.
   27.38 +     * should be taken to not access the buffer until the operation has
   27.39 +     * completed.
   27.40       *
   27.41       * <p> This method may be invoked at any time. Some channel types may not
   27.42       * allow more than one read to be outstanding at any given time. If a thread
   27.43       * initiates a read operation before a previous read operation has
   27.44       * completed then a {@link ReadPendingException} will be thrown.
   27.45       *
   27.46 -     * <p> The <tt>handler</tt> parameter is used to specify a {@link
   27.47 -     * CompletionHandler}. When the read operation completes the handler's
   27.48 -     * {@link CompletionHandler#completed completed} method is executed.
   27.49 -     *
   27.50 -     *
   27.51       * @param   dst
   27.52       *          The buffer into which bytes are to be transferred
   27.53       * @param   attachment
   27.54       *          The object to attach to the I/O operation; can be {@code null}
   27.55       * @param   handler
   27.56 -     *          The completion handler object; can be {@code null}
   27.57 -     *
   27.58 -     * @return  A Future representing the result of the operation
   27.59 +     *          The completion handler
   27.60       *
   27.61       * @throws  IllegalArgumentException
   27.62       *          If the buffer is read-only
   27.63       * @throws  ReadPendingException
   27.64       *          If the channel does not allow more than one read to be outstanding
   27.65       *          and a previous read has not completed
   27.66 +     * @throws  ShutdownChannelGroupException
   27.67 +     *          If the channel is associated with a {@link AsynchronousChannelGroup
   27.68 +     *          group} that has terminated
   27.69       */
   27.70 -    <A> Future<Integer> read(ByteBuffer dst,
   27.71 -                             A attachment,
   27.72 -                             CompletionHandler<Integer,? super A> handler);
   27.73 +    <A> void read(ByteBuffer dst,
   27.74 +                  A attachment,
   27.75 +                  CompletionHandler<Integer,? super A> handler);
   27.76  
   27.77      /**
   27.78       * Reads a sequence of bytes from this channel into the given buffer.
   27.79       *
   27.80 -     * <p> An invocation of this method of the form <tt>c.read(dst)</tt>
   27.81 -     * behaves in exactly the same manner as the invocation
   27.82 -     * <blockquote><pre>
   27.83 -     * c.read(dst, null, null);</pre></blockquote>
   27.84 +     * <p> This method initiates an asynchronous read operation to read a
   27.85 +     * sequence of bytes from this channel into the given buffer. The method
   27.86 +     * behaves in exactly the same manner as the {@link
   27.87 +     * #read(ByteBuffer,Object,CompletionHandler)
   27.88 +     * read(ByteBuffer,Object,CompletionHandler)} method except that instead
   27.89 +     * of specifying a completion handler, this method returns a {@code Future}
   27.90 +     * representing the pending result. The {@code Future}'s {@link Future#get()
   27.91 +     * get} method returns the number of bytes read or {@code -1} if no bytes
   27.92 +     * could be read because the channel has reached end-of-stream.
   27.93       *
   27.94       * @param   dst
   27.95       *          The buffer into which bytes are to be transferred
   27.96 @@ -134,17 +136,17 @@
   27.97      /**
   27.98       * Writes a sequence of bytes to this channel from the given buffer.
   27.99       *
  27.100 -     * <p> This method initiates an operation to write a sequence of bytes to
  27.101 -     * this channel from the given buffer. This method returns a {@link
  27.102 -     * Future} representing the pending result of the operation. The result
  27.103 -     * of the operation, obtained by invoking the <tt>Future</tt>'s {@link
  27.104 -     * Future#get() get} method, is the number of bytes written, possibly zero.
  27.105 +     * <p> This method initiates an asynchronous write operation to write a
  27.106 +     * sequence of bytes to this channel from the given buffer. The {@code
  27.107 +     * handler} parameter is a completion handler that is invoked when the write
  27.108 +     * operation completes (or fails). The result passed to the completion
  27.109 +     * handler is the number of bytes written.
  27.110       *
  27.111 -     * <p> This method initiates a write operation to write up to <i>r</i> bytes
  27.112 -     * to the channel, where <i>r</i> is the number of bytes remaining in the
  27.113 -     * buffer, that is, {@code src.remaining()}  at the moment the write is
  27.114 -     * attempted. Where <i>r</i> is 0, the write operation completes immediately
  27.115 -     * with a result of {@code 0} without initiating an I/O operation.
  27.116 +     * <p> The write operation may write up to <i>r</i> bytes to the channel,
  27.117 +     * where <i>r</i> is the number of bytes remaining in the buffer, that is,
  27.118 +     * {@code src.remaining()} at the time that the write is attempted. Where
  27.119 +     * <i>r</i> is 0, the write operation completes immediately with a result of
  27.120 +     * {@code 0} without initiating an I/O operation.
  27.121       *
  27.122       * <p> Suppose that a byte sequence of length <i>n</i> is written, where
  27.123       * <tt>0</tt>&nbsp;<tt>&lt;</tt>&nbsp;<i>n</i>&nbsp;<tt>&lt;=</tt>&nbsp;<i>r</i>.
  27.124 @@ -156,41 +158,43 @@
  27.125       * <i>p</i>&nbsp;<tt>+</tt>&nbsp;<i>n</i>; its limit will not have changed.
  27.126       *
  27.127       * <p> Buffers are not safe for use by multiple concurrent threads so care
  27.128 -     * should be taken to not to access the buffer until the operaton has completed.
  27.129 +     * should be taken to not access the buffer until the operation has
  27.130 +     * completed.
  27.131       *
  27.132       * <p> This method may be invoked at any time. Some channel types may not
  27.133       * allow more than one write to be outstanding at any given time. If a thread
  27.134       * initiates a write operation before a previous write operation has
  27.135       * completed then a {@link WritePendingException} will be thrown.
  27.136       *
  27.137 -     * <p> The <tt>handler</tt> parameter is used to specify a {@link
  27.138 -     * CompletionHandler}. When the write operation completes the handler's
  27.139 -     * {@link CompletionHandler#completed completed} method is executed.
  27.140 -     *
  27.141       * @param   src
  27.142       *          The buffer from which bytes are to be retrieved
  27.143       * @param   attachment
  27.144       *          The object to attach to the I/O operation; can be {@code null}
  27.145       * @param   handler
  27.146 -     *          The completion handler object; can be {@code null}
  27.147 -     *
  27.148 -     * @return  A Future representing the result of the operation
  27.149 +     *          The completion handler object
  27.150       *
  27.151       * @throws  WritePendingException
  27.152       *          If the channel does not allow more than one write to be outstanding
  27.153       *          and a previous write has not completed
  27.154 +     * @throws  ShutdownChannelGroupException
  27.155 +     *          If the channel is associated with a {@link AsynchronousChannelGroup
  27.156 +     *          group} that has terminated
  27.157       */
  27.158 -    <A> Future<Integer> write(ByteBuffer src,
  27.159 -                              A attachment,
  27.160 -                              CompletionHandler<Integer,? super A> handler);
  27.161 +    <A> void write(ByteBuffer src,
  27.162 +                   A attachment,
  27.163 +                   CompletionHandler<Integer,? super A> handler);
  27.164  
  27.165      /**
  27.166       * Writes a sequence of bytes to this channel from the given buffer.
  27.167       *
  27.168 -     * <p> An invocation of this method of the form <tt>c.write(src)</tt>
  27.169 -     * behaves in exactly the same manner as the invocation
  27.170 -     * <blockquote><pre>
  27.171 -     * c.write(src, null, null);</pre></blockquote>
  27.172 +     * <p> This method initiates an asynchronous write operation to write a
  27.173 +     * sequence of bytes to this channel from the given buffer. The method
  27.174 +     * behaves in exactly the same manner as the {@link
  27.175 +     * #write(ByteBuffer,Object,CompletionHandler)
  27.176 +     * write(ByteBuffer,Object,CompletionHandler)} method except that instead
  27.177 +     * of specifying a completion handler, this method returns a {@code Future}
  27.178 +     * representing the pending result. The {@code Future}'s {@link Future#get()
  27.179 +     * get} method returns the number of bytes written.
  27.180       *
  27.181       * @param   src
  27.182       *          The buffer from which bytes are to be retrieved
    28.1 --- a/src/share/classes/java/nio/channels/AsynchronousChannel.java	Mon Aug 24 17:26:09 2009 -0700
    28.2 +++ b/src/share/classes/java/nio/channels/AsynchronousChannel.java	Tue Sep 01 13:03:09 2009 -0700
    28.3 @@ -34,7 +34,8 @@
    28.4   *
    28.5   * <ol>
    28.6   * <li><pre>{@link Future}&lt;V&gt; <em>operation</em>(<em>...</em>)</pre></li>
    28.7 - * <li><pre>Future&lt;V&gt; <em>operation</em>(<em>...</em> A attachment, {@link CompletionHandler}&lt;V,? super A&gt handler)</pre></li>
    28.8 + * <li><pre>void <em>operation</em>(<em>...</em> A attachment, {@link
    28.9 + *   CompletionHandler}&lt;V,? super A&gt; handler)</pre></li>
   28.10   * </ol>
   28.11   *
   28.12   * where <i>operation</i> is the name of the I/O operation (read or write for
   28.13 @@ -48,7 +49,7 @@
   28.14   * interface may be used to check if the operation has completed, wait for its
   28.15   * completion, and to retrieve the result. In the second form, a {@link
   28.16   * CompletionHandler} is invoked to consume the result of the I/O operation when
   28.17 - * it completes, fails, or is cancelled.
   28.18 + * it completes or fails.
   28.19   *
   28.20   * <p> A channel that implements this interface is <em>asynchronously
   28.21   * closeable</em>: If an I/O operation is outstanding on the channel and the
   28.22 @@ -63,33 +64,33 @@
   28.23   * <h4>Cancellation</h4>
   28.24   *
   28.25   * <p> The {@code Future} interface defines the {@link Future#cancel cancel}
   28.26 - * method to cancel execution of a task.
   28.27 + * method to cancel execution. This causes all threads waiting on the result of
   28.28 + * the I/O operation to throw {@link java.util.concurrent.CancellationException}.
   28.29 + * Whether the underlying I/O operation can be cancelled is highly implementation
   28.30 + * specific and therefore not specified. Where cancellation leaves the channel,
   28.31 + * or the entity to which it is connected, in an inconsistent state, then the
   28.32 + * channel is put into an implementation specific <em>error state</em> that
   28.33 + * prevents further attempts to initiate I/O operations that are <i>similar</i>
   28.34 + * to the operation that was cancelled. For example, if a read operation is
   28.35 + * cancelled but the implementation cannot guarantee that bytes have not been
   28.36 + * read from the channel then it puts the channel into an error state; further
   28.37 + * attempts to initiate a {@code read} operation cause an unspecified runtime
   28.38 + * exception to be thrown. Similarly, if a write operation is cancelled but the
   28.39 + * implementation cannot guarantee that bytes have not been written to the
   28.40 + * channel then subsequent attempts to initiate a {@code write} will fail with
   28.41 + * an unspecified runtime exception.
   28.42   *
   28.43 - * <p> Where the {@code cancel} method is invoked with the {@code
   28.44 + * <p> Where the {@link Future#cancel cancel} method is invoked with the {@code
   28.45   * mayInterruptIfRunning} parameter set to {@code true} then the I/O operation
   28.46 - * may be interrupted by closing the channel. This will cause any other I/O
   28.47 - * operations outstanding on the channel to complete with the exception {@link
   28.48 - * AsynchronousCloseException}.
   28.49 - *
   28.50 - * <p> If a {@code CompletionHandler} is specified when initiating an I/O
   28.51 - * operation, and the {@code cancel} method is invoked to cancel the I/O
   28.52 - * operation before it completes, then the {@code CompletionHandler}'s {@link
   28.53 - * CompletionHandler#cancelled cancelled} method is invoked.
   28.54 - *
   28.55 - * <p> If an implementation of this interface supports a means to cancel I/O
   28.56 - * operations, and where cancellation may leave the channel, or the entity to
   28.57 - * which it is connected, in an inconsistent state, then the channel is put into
   28.58 - * an implementation specific <em>error state</em> that prevents further
   28.59 - * attempts to initiate I/O operations on the channel. For example, if a read
   28.60 - * operation is cancelled but the implementation cannot guarantee that bytes
   28.61 - * have not been read from the channel then it puts the channel into error state
   28.62 - * state; further attempts to initiate a {@code read} operation causes an
   28.63 - * unspecified runtime exception to be thrown.
   28.64 + * may be interrupted by closing the channel. In that case all threads waiting
   28.65 + * on the result of the I/O operation throw {@code CancellationException} and
   28.66 + * any other I/O operations outstanding on the channel complete with the
   28.67 + * exception {@link AsynchronousCloseException}.
   28.68   *
   28.69   * <p> Where the {@code cancel} method is invoked to cancel read or write
   28.70 - * operations then it recommended that all buffers used in the I/O operations be
   28.71 - * discarded or care taken to ensure that the buffers are not accessed while the
   28.72 - * channel remains open.
   28.73 + * operations then it is recommended that all buffers used in the I/O operations
   28.74 + * be discarded or care taken to ensure that the buffers are not accessed while
   28.75 + * the channel remains open.
   28.76   *
   28.77   *  @since 1.7
   28.78   */
   28.79 @@ -102,7 +103,7 @@
   28.80       *
   28.81       * <p> Any outstanding asynchronous operations upon this channel will
   28.82       * complete with the exception {@link AsynchronousCloseException}. After a
   28.83 -     * channel is closed then further attempts to initiate asynchronous I/O
   28.84 +     * channel is closed, further attempts to initiate asynchronous I/O
   28.85       * operations complete immediately with cause {@link ClosedChannelException}.
   28.86       *
   28.87       * <p>  This method otherwise behaves exactly as specified by the {@link
    29.1 --- a/src/share/classes/java/nio/channels/AsynchronousDatagramChannel.java	Mon Aug 24 17:26:09 2009 -0700
    29.2 +++ b/src/share/classes/java/nio/channels/AsynchronousDatagramChannel.java	Tue Sep 01 13:03:09 2009 -0700
    29.3 @@ -109,19 +109,13 @@
    29.4   *  // print the source address of all packets that we receive
    29.5   *  dc.receive(buffer, buffer, new CompletionHandler&lt;SocketAddress,ByteBuffer&gt;() {
    29.6   *      public void completed(SocketAddress sa, ByteBuffer buffer) {
    29.7 - *          try {
    29.8 - *               System.out.println(sa);
    29.9 - *
   29.10 - *               buffer.clear();
   29.11 - *               dc.receive(buffer, buffer, this);
   29.12 - *           } catch (...) { ... }
   29.13 + *          System.out.println(sa);
   29.14 + *          buffer.clear();
   29.15 + *          dc.receive(buffer, buffer, this);
   29.16   *      }
   29.17   *      public void failed(Throwable exc, ByteBuffer buffer) {
   29.18   *          ...
   29.19   *      }
   29.20 - *      public void cancelled(ByteBuffer buffer) {
   29.21 - *          ...
   29.22 - *      }
   29.23   *  });
   29.24   * </pre>
   29.25   *
   29.26 @@ -314,10 +308,10 @@
   29.27      /**
   29.28       * Receives a datagram via this channel.
   29.29       *
   29.30 -     * <p> This method initiates the receiving of a datagram, returning a
   29.31 -     * {@code Future} representing the pending result of the operation.
   29.32 -     * The {@code Future}'s {@link Future#get() get} method returns
   29.33 -     * the source address of the datagram upon successful completion.
   29.34 +     * <p> This method initiates the receiving of a datagram into the given
   29.35 +     * buffer. The {@code handler} parameter is a completion handler that is
   29.36 +     * invoked when the receive operation completes (or fails). The result
   29.37 +     * passed to the completion handler is the datagram's source address.
   29.38       *
   29.39       * <p> The datagram is transferred into the given byte buffer starting at
   29.40       * its current position, as if by a regular {@link AsynchronousByteChannel#read
   29.41 @@ -350,28 +344,26 @@
   29.42       * @param   attachment
   29.43       *          The object to attach to the I/O operation; can be {@code null}
   29.44       * @param   handler
   29.45 -     *          The handler for consuming the result; can be {@code null}
   29.46 -     *
   29.47 -     * @return  a {@code Future} object representing the pending result
   29.48 +     *          The handler for consuming the result
   29.49       *
   29.50       * @throws  IllegalArgumentException
   29.51       *          If the timeout is negative or the buffer is read-only
   29.52       * @throws  ShutdownChannelGroupException
   29.53 -     *          If a handler is specified, and the channel group is shutdown
   29.54 +     *          If the channel group has terminated
   29.55       */
   29.56 -    public abstract <A> Future<SocketAddress> receive(ByteBuffer dst,
   29.57 -                                                      long timeout,
   29.58 -                                                      TimeUnit unit,
   29.59 -                                                      A attachment,
   29.60 -                                                      CompletionHandler<SocketAddress,? super A> handler);
   29.61 +    public abstract <A> void receive(ByteBuffer dst,
   29.62 +                                     long timeout,
   29.63 +                                     TimeUnit unit,
   29.64 +                                     A attachment,
   29.65 +                                     CompletionHandler<SocketAddress,? super A> handler);
   29.66  
   29.67      /**
   29.68       * Receives a datagram via this channel.
   29.69       *
   29.70 -     * <p> This method initiates the receiving of a datagram, returning a
   29.71 -     * {@code Future} representing the pending result of the operation.
   29.72 -     * The {@code Future}'s {@link Future#get() get} method returns
   29.73 -     * the source address of the datagram upon successful completion.
   29.74 +     * <p> This method initiates the receiving of a datagram into the given
   29.75 +     * buffer. The {@code handler} parameter is a completion handler that is
   29.76 +     * invoked when the receive operation completes (or fails). The result
   29.77 +     * passed to the completion handler is the datagram's source address.
   29.78       *
   29.79       * <p> This method is equivalent to invoking {@link
   29.80       * #receive(ByteBuffer,long,TimeUnit,Object,CompletionHandler)} with a
   29.81 @@ -382,34 +374,30 @@
   29.82       * @param   attachment
   29.83       *          The object to attach to the I/O operation; can be {@code null}
   29.84       * @param   handler
   29.85 -     *          The handler for consuming the result; can be {@code null}
   29.86 -     *
   29.87 -     * @return  a {@code Future} object representing the pending result
   29.88 +     *          The handler for consuming the result
   29.89       *
   29.90       * @throws  IllegalArgumentException
   29.91       *          If the buffer is read-only
   29.92       * @throws  ShutdownChannelGroupException
   29.93 -     *          If a handler is specified, and the channel group is shutdown
   29.94 +     *          If the channel group has terminated
   29.95       */
   29.96 -    public final <A> Future<SocketAddress> receive(ByteBuffer dst,
   29.97 -                                                   A attachment,
   29.98 -                                                   CompletionHandler<SocketAddress,? super A> handler)
   29.99 +    public final <A> void receive(ByteBuffer dst,
  29.100 +                                  A attachment,
  29.101 +                                  CompletionHandler<SocketAddress,? super A> handler)
  29.102      {
  29.103 -        return receive(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
  29.104 +        receive(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
  29.105      }
  29.106  
  29.107      /**
  29.108       * Receives a datagram via this channel.
  29.109       *
  29.110 -     * <p> This method initiates the receiving of a datagram, returning a
  29.111 -     * {@code Future} representing the pending result of the operation.
  29.112 -     * The {@code Future}'s {@link Future#get() get} method returns
  29.113 -     * the source address of the datagram upon successful completion.
  29.114 -     *
  29.115 -     * <p> This method is equivalent to invoking {@link
  29.116 -     * #receive(ByteBuffer,long,TimeUnit,Object,CompletionHandler)} with a
  29.117 -     * timeout of {@code 0L}, and an attachment and completion handler
  29.118 -     * of {@code null}.
  29.119 +     * <p> This method initiates the receiving of a datagram into the given
  29.120 +     * buffer. The method behaves in exactly the same manner as the {@link
  29.121 +     * #receive(ByteBuffer,Object,CompletionHandler)
  29.122 +     * receive(ByteBuffer,Object,CompletionHandler)} method except that instead
  29.123 +     * of specifying a completion handler, this method returns a {@code Future}
  29.124 +     * representing the pending result. The {@code Future}'s {@link Future#get()
  29.125 +     * get} method returns the datagram's source address.
  29.126       *
  29.127       * @param   dst
  29.128       *          The buffer into which the datagram is to be transferred
  29.129 @@ -419,84 +407,19 @@
  29.130       * @throws  IllegalArgumentException
  29.131       *          If the buffer is read-only
  29.132       */
  29.133 -    public final <A> Future<SocketAddress> receive(ByteBuffer dst) {
  29.134 -        return receive(dst, 0L, TimeUnit.MILLISECONDS, null, null);
  29.135 -    }
  29.136 +    public abstract Future<SocketAddress> receive(ByteBuffer dst);
  29.137  
  29.138      /**
  29.139       * Sends a datagram via this channel.
  29.140       *
  29.141 -     * <p> This method initiates sending of a datagram, returning a
  29.142 -     * {@code Future} representing the pending result of the operation.
  29.143 -     * The operation sends the remaining bytes in the given buffer as a single
  29.144 -     * datagram to the given target address. The result of the operation, obtained
  29.145 -     * by invoking the {@code Future}'s {@link Future#get() get}
  29.146 -     * method, is the number of bytes sent.
  29.147 +     * <p> This method initiates sending of a datagram from the given buffer to
  29.148 +     * the given address. The {@code handler} parameter is a completion handler
  29.149 +     * that is invoked when the send completes (or fails). The result passed to
  29.150 +     * the completion handler is the number of bytes sent.
  29.151       *
  29.152 -     * <p> The datagram is transferred from the byte buffer as if by a regular
  29.153 -     * {@link AsynchronousByteChannel#write write} operation.
  29.154 -     *
  29.155 -     * <p> If a timeout is specified and the timeout elapses before the operation
  29.156 -     * completes then the operation completes with the exception {@link
  29.157 -     * InterruptedByTimeoutException}. When a timeout elapses then the state of
  29.158 -     * the {@link ByteBuffer} is not defined. The buffers should be discarded or
  29.159 -     * at least care must be taken to ensure that the buffer is not accessed
  29.160 -     * while the channel remains open.
  29.161 -     *
  29.162 -     * <p> If there is a security manager installed and the channel is not
  29.163 -     * connected then this method verifies that the target address and port number
  29.164 -     * are permitted by the security manager's {@link SecurityManager#checkConnect
  29.165 -     * checkConnect} method.  The overhead of this security check can be avoided
  29.166 -     * by first connecting the socket via the {@link #connect connect} method.
  29.167 -     *
  29.168 -     * @param   src
  29.169 -     *          The buffer containing the datagram to be sent
  29.170 -     * @param   target
  29.171 -     *          The address to which the datagram is to be sent
  29.172 -     * @param   timeout
  29.173 -     *          The timeout, or {@code 0L} for no timeout
  29.174 -     * @param   unit
  29.175 -     *          The time unit of the {@code timeout} argument
  29.176 -     * @param   attachment
  29.177 -     *          The object to attach to the I/O operation; can be {@code null}
  29.178 -     * @param   handler
  29.179 -     *          The handler for consuming the result; can be {@code null}
  29.180 -     *
  29.181 -     * @return  a {@code Future} object representing the pending result
  29.182 -     *
  29.183 -     * @throws  UnresolvedAddressException
  29.184 -     *          If the given remote address is not fully resolved
  29.185 -     * @throws  UnsupportedAddressTypeException
  29.186 -     *          If the type of the given remote address is not supported
  29.187 -     * @throws  IllegalArgumentException
  29.188 -     *          If the timeout is negative, or if the channel's socket is
  29.189 -     *          connected to an address that is not equal to {@code target}
  29.190 -     * @throws  SecurityException
  29.191 -     *          If a security manager has been installed and it does not permit
  29.192 -     *          datagrams to be sent to the given address
  29.193 -     * @throws  ShutdownChannelGroupException
  29.194 -     *          If a handler is specified, and the channel group is shutdown
  29.195 -     */
  29.196 -    public abstract <A> Future<Integer> send(ByteBuffer src,
  29.197 -                                             SocketAddress target,
  29.198 -                                             long timeout,
  29.199 -                                             TimeUnit unit,
  29.200 -                                             A attachment,
  29.201 -                                             CompletionHandler<Integer,? super A> handler);
  29.202 -
  29.203 -    /**
  29.204 -     * Sends a datagram via this channel.
  29.205 -     *
  29.206 -     * <p> This method initiates sending of a datagram, returning a
  29.207 -     * {@code Future} representing the pending result of the operation.
  29.208 -     * The operation sends the remaining bytes in the given buffer as a single
  29.209 -     * datagram to the given target address. The result of the operation, obtained
  29.210 -     * by invoking the {@code Future}'s {@link Future#get() get}
  29.211 -     * method, is the number of bytes sent.
  29.212 -     *
  29.213 -     * <p> This method is equivalent to invoking {@link
  29.214 -     * #send(ByteBuffer,SocketAddress,long,TimeUnit,Object,CompletionHandler)}
  29.215 -     * with a timeout of {@code 0L}.
  29.216 +     * <p> Otherwise this method works in the same manner as the {@link
  29.217 +     * AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)}
  29.218 +     * method.
  29.219       *
  29.220       * @param   src
  29.221       *          The buffer containing the datagram to be sent
  29.222 @@ -505,9 +428,7 @@
  29.223       * @param   attachment
  29.224       *          The object to attach to the I/O operation; can be {@code null}
  29.225       * @param   handler
  29.226 -     *          The handler for consuming the result; can be {@code null}
  29.227 -     *
  29.228 -     * @return  a {@code Future} object representing the pending result
  29.229 +     *          The handler for consuming the result
  29.230       *
  29.231       * @throws  UnresolvedAddressException
  29.232       *          If the given remote address is not fully resolved
  29.233 @@ -520,30 +441,23 @@
  29.234       *          If a security manager has been installed and it does not permit
  29.235       *          datagrams to be sent to the given address
  29.236       * @throws  ShutdownChannelGroupException
  29.237 -     *          If a handler is specified, and the channel group is shutdown
  29.238 +     *          If the channel group has terminated
  29.239       */
  29.240 -    public final <A> Future<Integer> send(ByteBuffer src,
  29.241 -                                          SocketAddress target,
  29.242 -                                          A attachment,
  29.243 -                                          CompletionHandler<Integer,? super A> handler)
  29.244 -    {
  29.245 -        return send(src, target, 0L, TimeUnit.MILLISECONDS, attachment, handler);
  29.246 -    }
  29.247 +    public abstract <A> void send(ByteBuffer src,
  29.248 +                                  SocketAddress target,
  29.249 +                                  A attachment,
  29.250 +                                  CompletionHandler<Integer,? super A> handler);
  29.251  
  29.252      /**
  29.253       * Sends a datagram via this channel.
  29.254       *
  29.255 -     * <p> This method initiates sending of a datagram, returning a
  29.256 -     * {@code Future} representing the pending result of the operation.
  29.257 -     * The operation sends the remaining bytes in the given buffer as a single
  29.258 -     * datagram to the given target address. The result of the operation, obtained
  29.259 -     * by invoking the {@code Future}'s {@link Future#get() get}
  29.260 -     * method, is the number of bytes sent.
  29.261 -     *
  29.262 -     * <p> This method is equivalent to invoking {@link
  29.263 -     * #send(ByteBuffer,SocketAddress,long,TimeUnit,Object,CompletionHandler)}
  29.264 -     * with a timeout of {@code 0L} and an attachment and completion handler
  29.265 -     * of {@code null}.
  29.266 +     * <p> This method initiates sending of a datagram from the given buffer to
  29.267 +     * the given address. The method behaves in exactly the same manner as the
  29.268 +     * {@link #send(ByteBuffer,SocketAddress,Object,CompletionHandler)
  29.269 +     * send(ByteBuffer,SocketAddress,Object,CompletionHandler)} method except
  29.270 +     * that instead of specifying a completion handler, this method returns a
  29.271 +     * {@code Future} representing the pending result. The {@code Future}'s
  29.272 +     * {@link Future#get() get} method returns the number of bytes sent.
  29.273       *
  29.274       * @param   src
  29.275       *          The buffer containing the datagram to be sent
  29.276 @@ -563,17 +477,15 @@
  29.277       *          If a security manager has been installed and it does not permit
  29.278       *          datagrams to be sent to the given address
  29.279       */
  29.280 -    public final Future<Integer> send(ByteBuffer src, SocketAddress target) {
  29.281 -        return send(src, target, 0L, TimeUnit.MILLISECONDS, null, null);
  29.282 -    }
  29.283 +    public abstract Future<Integer> send(ByteBuffer src, SocketAddress target);
  29.284  
  29.285      /**
  29.286       * Receives a datagram via this channel.
  29.287       *
  29.288 -     * <p> This method initiates the receiving of a datagram, returning a
  29.289 -     * {@code Future} representing the pending result of the operation.
  29.290 -     * The {@code Future}'s {@link Future#get() get} method returns
  29.291 -     * the number of bytes transferred upon successful completion.
  29.292 +     * <p> This method initiates the receiving of a datagram into the given
  29.293 +     * buffer. The {@code handler} parameter is a completion handler that is
  29.294 +     * invoked when the receive operation completes (or fails). The result
  29.295 +     * passed to the completion handler is number of bytes read.
  29.296       *
  29.297       * <p> This method may only be invoked if this channel is connected, and it
  29.298       * only accepts datagrams from the peer that the channel is connected too.
  29.299 @@ -599,120 +511,62 @@
  29.300       * @param   attachment
  29.301       *          The object to attach to the I/O operation; can be {@code null}
  29.302       * @param   handler
  29.303 -     *          The handler for consuming the result; can be {@code null}
  29.304 -     *
  29.305 -     * @return  a {@code Future} object representing the pending result
  29.306 +     *          The handler for consuming the result
  29.307       *
  29.308       * @throws  IllegalArgumentException
  29.309       *          If the timeout is negative or buffer is read-only
  29.310       * @throws  NotYetConnectedException
  29.311       *          If this channel is not connected
  29.312       * @throws  ShutdownChannelGroupException
  29.313 -     *          If a handler is specified, and the channel group is shutdown
  29.314 +     *          If the channel group has terminated
  29.315       */
  29.316 -    public abstract <A> Future<Integer> read(ByteBuffer dst,
  29.317 -                                             long timeout,
  29.318 -                                             TimeUnit unit,
  29.319 -                                             A attachment,
  29.320 -                                             CompletionHandler<Integer,? super A> handler);
  29.321 +    public abstract <A> void read(ByteBuffer dst,
  29.322 +                                  long timeout,
  29.323 +                                  TimeUnit unit,
  29.324 +                                  A attachment,
  29.325 +                                  CompletionHandler<Integer,? super A> handler);
  29.326  
  29.327      /**
  29.328       * @throws  NotYetConnectedException
  29.329       *          If this channel is not connected
  29.330       * @throws  ShutdownChannelGroupException
  29.331 -     *          If a handler is specified, and the channel group is shutdown
  29.332 +     *          If the channel group has terminated
  29.333       */
  29.334      @Override
  29.335 -    public final <A> Future<Integer> read(ByteBuffer dst,
  29.336 -                                          A attachment,
  29.337 -                                          CompletionHandler<Integer,? super A> handler)
  29.338 +    public final <A> void read(ByteBuffer dst,
  29.339 +                               A attachment,
  29.340 +                               CompletionHandler<Integer,? super A> handler)
  29.341      {
  29.342 -        return read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
  29.343 +        read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
  29.344      }
  29.345  
  29.346      /**
  29.347       * @throws  NotYetConnectedException
  29.348       *          If this channel is not connected
  29.349       * @throws  ShutdownChannelGroupException
  29.350 -     *          If a handler is specified, and the channel group is shutdown
  29.351 +     *          If the channel group has terminated
  29.352       */
  29.353      @Override
  29.354 -    public final Future<Integer> read(ByteBuffer dst) {
  29.355 -        return read(dst, 0L, TimeUnit.MILLISECONDS, null, null);
  29.356 -    }
  29.357 -
  29.358 -    /**
  29.359 -     * Writes a datagram to this channel.
  29.360 -     *
  29.361 -     * <p> This method initiates sending of a datagram, returning a
  29.362 -     * {@code Future} representing the pending result of the operation.
  29.363 -     * The operation sends the remaining bytes in the given buffer as a single
  29.364 -     * datagram. The result of the operation, obtained by invoking the
  29.365 -     * {@code Future}'s {@link Future#get() get} method, is the
  29.366 -     * number of bytes sent.
  29.367 -     *
  29.368 -     * <p> The datagram is transferred from the byte buffer as if by a regular
  29.369 -     * {@link AsynchronousByteChannel#write write} operation.
  29.370 -     *
  29.371 -     * <p> This method may only be invoked if this channel is connected,
  29.372 -     * in which case it sends datagrams directly to the socket's peer.  Otherwise
  29.373 -     * it behaves exactly as specified in the {@link
  29.374 -     * AsynchronousByteChannel} interface.
  29.375 -     *
  29.376 -     * <p> If a timeout is specified and the timeout elapses before the operation
  29.377 -     * completes then the operation completes with the exception {@link
  29.378 -     * InterruptedByTimeoutException}. When a timeout elapses then the state of
  29.379 -     * the {@link ByteBuffer} is not defined. The buffers should be discarded or
  29.380 -     * at least care must be taken to ensure that the buffer is not accessed
  29.381 -     * while the channel remains open.
  29.382 -     *
  29.383 -     * @param   src
  29.384 -     *          The buffer containing the datagram to be sent
  29.385 -     * @param   timeout
  29.386 -     *          The timeout, or {@code 0L} for no timeout
  29.387 -     * @param   unit
  29.388 -     *          The time unit of the {@code timeout} argument
  29.389 -     * @param   attachment
  29.390 -     *          The object to attach to the I/O operation; can be {@code null}
  29.391 -     * @param   handler
  29.392 -     *          The handler for consuming the result; can be {@code null}
  29.393 -     *
  29.394 -     * @return  a {@code Future} object representing the pending result
  29.395 -     *
  29.396 -     * @throws  IllegalArgumentException
  29.397 -     *          If the timeout is negative
  29.398 -     * @throws  NotYetConnectedException
  29.399 -     *          If this channel is not connected
  29.400 -     * @throws  ShutdownChannelGroupException
  29.401 -     *          If a handler is specified, and the channel group is shutdown
  29.402 -     */
  29.403 -    public abstract <A> Future<Integer> write(ByteBuffer src,
  29.404 -                                              long timeout,
  29.405 -                                              TimeUnit unit,
  29.406 -                                              A attachment,
  29.407 -                                              CompletionHandler<Integer,? super A> handler);
  29.408 -    /**
  29.409 -     * @throws  NotYetConnectedException
  29.410 -     *          If this channel is not connected
  29.411 -     * @throws  ShutdownChannelGroupException
  29.412 -     *          If a handler is specified, and the channel group is shutdown
  29.413 -     */
  29.414 -    @Override
  29.415 -    public final <A> Future<Integer> write(ByteBuffer src,
  29.416 -                                           A attachment,
  29.417 -                                           CompletionHandler<Integer,? super A> handler)
  29.418 -    {
  29.419 -        return write(src, 0L, TimeUnit.MILLISECONDS, attachment, handler);
  29.420 -    }
  29.421 +    public abstract Future<Integer> read(ByteBuffer dst);
  29.422  
  29.423      /**
  29.424       * @throws  NotYetConnectedException
  29.425       *          If this channel is not connected
  29.426       * @throws  ShutdownChannelGroupException
  29.427 -     *          If a handler is specified, and the channel group is shutdown
  29.428 +     *          If the channel group has terminated
  29.429       */
  29.430      @Override
  29.431 -    public final Future<Integer> write(ByteBuffer src) {
  29.432 -        return write(src, 0L, TimeUnit.MILLISECONDS, null, null);
  29.433 -    }
  29.434 +    public abstract <A> void  write(ByteBuffer src,
  29.435 +                                    A attachment,
  29.436 +                                    CompletionHandler<Integer,? super A> handler);
  29.437 +
  29.438 +
  29.439 +    /**
  29.440 +     * @throws  NotYetConnectedException
  29.441 +     *          If this channel is not connected
  29.442 +     * @throws  ShutdownChannelGroupException
  29.443 +     *          If the channel group has terminated
  29.444 +     */
  29.445 +    @Override
  29.446 +    public abstract Future<Integer> write(ByteBuffer src);
  29.447  }
    30.1 --- a/src/share/classes/java/nio/channels/AsynchronousFileChannel.java	Mon Aug 24 17:26:09 2009 -0700
    30.2 +++ b/src/share/classes/java/nio/channels/AsynchronousFileChannel.java	Tue Sep 01 13:03:09 2009 -0700
    30.3 @@ -48,7 +48,12 @@
    30.4   *
    30.5   * <p> An asynchronous file channel does not have a <i>current position</i>
    30.6   * within the file. Instead, the file position is specified to each read and
    30.7 - * write operation.
    30.8 + * write methd that initiate asynchronous operations. A {@link CompletionHandler}
    30.9 + * is specified as a parameter and is invoked to consume the result of the I/O
   30.10 + * operation. This class also defines read and write methods that initiate
   30.11 + * asynchronous operations, returning a {@link Future} to represent the pending
   30.12 + * result of the operation. The {@code Future} may be used to check if the
   30.13 + * operation has completed, to wait for its completion.
   30.14   *
   30.15   * <p> In addition to read and write operations, this class defines the
   30.16   * following operations: </p>
   30.17 @@ -59,18 +64,11 @@
   30.18   *   out</i>} to the underlying storage device, ensuring that data are not
   30.19   *   lost in the event of a system crash.  </p></li>
   30.20   *
   30.21 - *   <li><p> A region of a file may be {@link FileLock <i>locked</i>}
   30.22 - *   against access by other programs.  </p></li>
   30.23 + *   <li><p> A region of a file may be {@link #lock <i>locked</i>} against
   30.24 + *   access by other programs.  </p></li>
   30.25   *
   30.26   * </ul>
   30.27   *
   30.28 - * <p> The {@link #read read}, {@link #write write}, and {@link #lock lock}
   30.29 - * methods defined by this class are asynchronous  and return a {@link Future}
   30.30 - * to represent the pending result of the operation. This may be used to check
   30.31 - * if the operation has completed, to wait for its completion, and to retrieve
   30.32 - * the result. These method may optionally specify a {@link CompletionHandler}
   30.33 - * that is invoked to consume the result of the I/O operation when it completes.
   30.34 - *
   30.35   * <p> An {@code AsynchronousFileChannel} is associated with a thread pool to
   30.36   * which tasks are submitted to handle I/O events and dispatch to completion
   30.37   * handlers that consume the results of I/O operations on the channel. The
   30.38 @@ -123,22 +121,6 @@
   30.39      }
   30.40  
   30.41      /**
   30.42 -     * Closes this channel.
   30.43 -     *
   30.44 -     * <p> If this channel is associated with its own thread pool then closing
   30.45 -     * the channel causes the thread pool to shutdown after all actively
   30.46 -     * executing completion handlers have completed. No attempt is made to stop
   30.47 -     * or interrupt actively completion handlers.
   30.48 -     *
   30.49 -     * <p> This method otherwise behaves exactly as specified by the {@link
   30.50 -     * AsynchronousChannel} interface.
   30.51 -     *
   30.52 -     * @throws  IOException     {@inheritDoc}
   30.53 -     */
   30.54 -    @Override
   30.55 -    public abstract void close() throws IOException;
   30.56 -
   30.57 -    /**
   30.58       * Opens or creates a file for reading and/or writing, returning an
   30.59       * asynchronous file channel to access the file.
   30.60       *
   30.61 @@ -215,9 +197,8 @@
   30.62       * should be taken when configuring the {@code Executor}. Minimally it
   30.63       * should support an unbounded work queue and should not run tasks on the
   30.64       * caller thread of the {@link ExecutorService#execute execute} method.
   30.65 -     * {@link #close Closing} the channel results in the orderly {@link
   30.66 -     * ExecutorService#shutdown shutdown} of the executor service. Shutting down
   30.67 -     * the executor service by other means results in unspecified behavior.
   30.68 +     * Shutting down the executor service while the channel is open results in
   30.69 +     * unspecified behavior.
   30.70       *
   30.71       * <p> The {@code attrs} parameter is an optional array of file {@link
   30.72       * FileAttribute file-attributes} to set atomically when creating the file.
   30.73 @@ -276,7 +257,8 @@
   30.74       * <p> An invocation of this method behaves in exactly the same way as the
   30.75       * invocation
   30.76       * <pre>
   30.77 -     *     ch.{@link #open(Path,Set,ExecutorService,FileAttribute[]) open}(file, opts, null, new FileAttribute&lt;?&gt;[0]);
   30.78 +     *     ch.{@link #open(Path,Set,ExecutorService,FileAttribute[])
   30.79 +     *       open}(file, opts, null, new FileAttribute&lt;?&gt;[0]);
   30.80       * </pre>
   30.81       * where {@code opts} is a {@code Set} containing the options specified to
   30.82       * this method.
   30.83 @@ -405,10 +387,11 @@
   30.84      /**
   30.85       * Acquires a lock on the given region of this channel's file.
   30.86       *
   30.87 -     * <p> This method initiates an operation to acquire a lock on the given region
   30.88 -     * of this channel's file. The method returns a {@code Future} representing
   30.89 -     * the pending result of the operation. Its {@link Future#get() get}
   30.90 -     * method returns the {@link FileLock} on successful completion.
   30.91 +     * <p> This method initiates an operation to acquire a lock on the given
   30.92 +     * region of this channel's file. The {@code handler} parameter is a
   30.93 +     * completion handler that is invoked when the lock is acquired (or the
   30.94 +     * operation fails). The result passed to the completion handler is the
   30.95 +     * resulting {@code FileLock}.
   30.96       *
   30.97       * <p> The region specified by the {@code position} and {@code size}
   30.98       * parameters need not be contained within, or even overlap, the actual
   30.99 @@ -455,9 +438,7 @@
  30.100       * @param   attachment
  30.101       *          The object to attach to the I/O operation; can be {@code null}
  30.102       * @param   handler
  30.103 -     *          The handler for consuming the result; can be {@code null}
  30.104 -     *
  30.105 -     * @return  a {@code Future} object representing the pending result
  30.106 +     *          The handler for consuming the result
  30.107       *
  30.108       * @throws  OverlappingFileLockException
  30.109       *          If a lock that overlaps the requested region is already held by
  30.110 @@ -466,26 +447,24 @@
  30.111       * @throws  IllegalArgumentException
  30.112       *          If the preconditions on the parameters do not hold
  30.113       * @throws  NonReadableChannelException
  30.114 -     *          If {@code shared} is true this channel but was not opened for reading
  30.115 +     *          If {@code shared} is true but this channel was not opened for reading
  30.116       * @throws  NonWritableChannelException
  30.117       *          If {@code shared} is false but this channel was not opened for writing
  30.118 -     * @throws  ShutdownChannelGroupException
  30.119 -     *          If a handler is specified, the channel is closed, and the channel
  30.120 -     *          was originally created with its own thread pool
  30.121       */
  30.122 -    public abstract <A> Future<FileLock> lock(long position,
  30.123 -                                              long size,
  30.124 -                                              boolean shared,
  30.125 -                                              A attachment,
  30.126 -                                              CompletionHandler<FileLock,? super A> handler);
  30.127 +    public abstract <A> void lock(long position,
  30.128 +                                  long size,
  30.129 +                                  boolean shared,
  30.130 +                                  A attachment,
  30.131 +                                  CompletionHandler<FileLock,? super A> handler);
  30.132  
  30.133      /**
  30.134       * Acquires an exclusive lock on this channel's file.
  30.135       *
  30.136 -     * <p> This method initiates an operation to acquire an exclusive lock on this
  30.137 -     * channel's file. The method returns a {@code Future} representing
  30.138 -     * the pending result of the operation. Its {@link Future#get() get}
  30.139 -     * method returns the {@link FileLock} on successful completion.
  30.140 +     * <p> This method initiates an operation to acquire a lock on the given
  30.141 +     * region of this channel's file. The {@code handler} parameter is a
  30.142 +     * completion handler that is invoked when the lock is acquired (or the
  30.143 +     * operation fails). The result passed to the completion handler is the
  30.144 +     * resulting {@code FileLock}.
  30.145       *
  30.146       * <p> An invocation of this method of the form {@code ch.lock(att,handler)}
  30.147       * behaves in exactly the same way as the invocation
  30.148 @@ -496,7 +475,70 @@
  30.149       * @param   attachment
  30.150       *          The object to attach to the I/O operation; can be {@code null}
  30.151       * @param   handler
  30.152 -     *          The handler for consuming the result; can be {@code null}
  30.153 +     *          The handler for consuming the result
  30.154 +     *
  30.155 +     * @throws  OverlappingFileLockException
  30.156 +     *          If a lock is already held by this Java virtual machine, or there
  30.157 +     *          is already a pending attempt to lock a region
  30.158 +     * @throws  NonWritableChannelException
  30.159 +     *          If this channel was not opened for writing
  30.160 +     */
  30.161 +    public final <A> void lock(A attachment,
  30.162 +                               CompletionHandler<FileLock,? super A> handler)
  30.163 +    {
  30.164 +        lock(0L, Long.MAX_VALUE, false, attachment, handler);
  30.165 +    }
  30.166 +
  30.167 +    /**
  30.168 +     * Acquires a lock on the given region of this channel's file.
  30.169 +     *
  30.170 +     * <p> This method initiates an operation to acquire a lock on the given
  30.171 +     * region of this channel's file.  The method behaves in exactly the same
  30.172 +     * manner as the {@link #lock(long, long, boolean, Object, CompletionHandler)}
  30.173 +     * method except that instead of specifying a completion handler, this
  30.174 +     * method returns a {@code Future} representing the pending result. The
  30.175 +     * {@code Future}'s {@link Future#get() get} method returns the {@link
  30.176 +     * FileLock} on successful completion.
  30.177 +     *
  30.178 +     * @param   position
  30.179 +     *          The position at which the locked region is to start; must be
  30.180 +     *          non-negative
  30.181 +     * @param   size
  30.182 +     *          The size of the locked region; must be non-negative, and the sum
  30.183 +     *          {@code position}&nbsp;+&nbsp;{@code size} must be non-negative
  30.184 +     * @param   shared
  30.185 +     *          {@code true} to request a shared lock, in which case this
  30.186 +     *          channel must be open for reading (and possibly writing);
  30.187 +     *          {@code false} to request an exclusive lock, in which case this
  30.188 +     *          channel must be open for writing (and possibly reading)
  30.189 +     *
  30.190 +     * @return  a {@code Future} object representing the pending result
  30.191 +     *
  30.192 +     * @throws  OverlappingFileLockException
  30.193 +     *          If a lock is already held by this Java virtual machine, or there
  30.194 +     *          is already a pending attempt to lock a region
  30.195 +     * @throws  IllegalArgumentException
  30.196 +     *          If the preconditions on the parameters do not hold
  30.197 +     * @throws  NonReadableChannelException
  30.198 +     *          If {@code shared} is true but this channel was not opened for reading
  30.199 +     * @throws  NonWritableChannelException
  30.200 +     *          If {@code shared} is false but this channel was not opened for writing
  30.201 +     */
  30.202 +    public abstract Future<FileLock> lock(long position, long size, boolean shared);
  30.203 +
  30.204 +    /**
  30.205 +     * Acquires an exclusive lock on this channel's file.
  30.206 +     *
  30.207 +     * <p> This method initiates an operation to acquire an exclusive lock on this
  30.208 +     * channel's file. The method returns a {@code Future} representing the
  30.209 +     * pending result of the operation. The {@code Future}'s {@link Future#get()
  30.210 +     * get} method returns the {@link FileLock} on successful completion.
  30.211 +     *
  30.212 +     * <p> An invocation of this method behaves in exactly the same way as the
  30.213 +     * invocation
  30.214 +     * <pre>
  30.215 +     *     ch.{@link #lock(long,long,boolean) lock}(0L, Long.MAX_VALUE, false)
  30.216 +     * </pre>
  30.217       *
  30.218       * @return  a {@code Future} object representing the pending result
  30.219       *
  30.220 @@ -505,40 +547,9 @@
  30.221       *          is already a pending attempt to lock a region
  30.222       * @throws  NonWritableChannelException
  30.223       *          If this channel was not opened for writing
  30.224 -     * @throws  ShutdownChannelGroupException
  30.225 -     *          If a handler is specified, the channel is closed, and the channel
  30.226 -     *          was originally created with its own thread pool
  30.227 -     */
  30.228 -    public final <A> Future<FileLock> lock(A attachment,
  30.229 -                                           CompletionHandler<FileLock,? super A> handler)
  30.230 -    {
  30.231 -        return lock(0L, Long.MAX_VALUE, false, attachment, handler);
  30.232 -    }
  30.233 -
  30.234 -    /**
  30.235 -     * Acquires an exclusive lock on this channel's file.
  30.236 -     *
  30.237 -     * <p> This method initiates an operation to acquire an exclusive lock on this
  30.238 -     * channel's file. The method returns a {@code Future} representing the
  30.239 -     * pending result of the operation. Its {@link Future#get() get} method
  30.240 -     * returns the {@link FileLock} on successful completion.
  30.241 -     *
  30.242 -     * <p> An invocation of this method behaves in exactly the same way as the
  30.243 -     * invocation
  30.244 -     * <pre>
  30.245 -     *     ch.{@link #lock(long,long,boolean,Object,CompletionHandler) lock}(0L, Long.MAX_VALUE, false, null, null)
  30.246 -     * </pre>
  30.247 -     *
  30.248 -     * @return  A {@code Future} object representing the pending result
  30.249 -     *
  30.250 -     * @throws  OverlappingFileLockException
  30.251 -     *          If a lock is already held by this Java virtual machine, or there
  30.252 -     *          is already a pending attempt to lock a region
  30.253 -     * @throws  NonWritableChannelException
  30.254 -     *          If this channel was not opened for writing
  30.255       */
  30.256      public final Future<FileLock> lock() {
  30.257 -        return lock(0L, Long.MAX_VALUE, false, null, null);
  30.258 +        return lock(0L, Long.MAX_VALUE, false);
  30.259      }
  30.260  
  30.261      /**
  30.262 @@ -576,7 +587,7 @@
  30.263       *          blocked in this method and is attempting to lock an overlapping
  30.264       *          region of the same file
  30.265       * @throws  NonReadableChannelException
  30.266 -     *          If {@code shared} is true this channel but was not opened for reading
  30.267 +     *          If {@code shared} is true but this channel was not opened for reading
  30.268       * @throws  NonWritableChannelException
  30.269       *          If {@code shared} is false but this channel was not opened for writing
  30.270       *
  30.271 @@ -629,11 +640,10 @@
  30.272       * starting at the given file position.
  30.273       *
  30.274       * <p> This method initiates the reading of a sequence of bytes from this
  30.275 -     * channel into the given buffer, starting at the given file position. This
  30.276 -     * method returns a {@code Future} representing the pending result of the
  30.277 -     * operation. The Future's {@link Future#get() get} method returns the
  30.278 -     * number of bytes read or {@code -1} if the given position is greater than
  30.279 -     * or equal to the file's size at the time that the read is attempted.
  30.280 +     * channel into the given buffer, starting at the given file position. The
  30.281 +     * result of the read is the number of bytes read or {@code -1} if the given
  30.282 +     * position is greater than or equal to the file's size at the time that the
  30.283 +     * read is attempted.
  30.284       *
  30.285       * <p> This method works in the same manner as the {@link
  30.286       * AsynchronousByteChannel#read(ByteBuffer,Object,CompletionHandler)}
  30.287 @@ -649,22 +659,17 @@
  30.288       * @param   attachment
  30.289       *          The object to attach to the I/O operation; can be {@code null}
  30.290       * @param   handler
  30.291 -     *          The handler for consuming the result; can be {@code null}
  30.292 -     *
  30.293 -     * @return  A {@code Future} object representing the pending result
  30.294 +     *          The handler for consuming the result
  30.295       *
  30.296       * @throws  IllegalArgumentException
  30.297       *          If the position is negative or the buffer is read-only
  30.298       * @throws  NonReadableChannelException
  30.299       *          If this channel was not opened for reading
  30.300 -     * @throws  ShutdownChannelGroupException
  30.301 -     *          If a handler is specified, the channel is closed, and the channel
  30.302 -     *          was originally created with its own thread pool
  30.303       */
  30.304 -    public abstract <A> Future<Integer> read(ByteBuffer dst,
  30.305 -                                             long position,
  30.306 -                                             A attachment,
  30.307 -                                             CompletionHandler<Integer,? super A> handler);
  30.308 +    public abstract <A> void read(ByteBuffer dst,
  30.309 +                                  long position,
  30.310 +                                  A attachment,
  30.311 +                                  CompletionHandler<Integer,? super A> handler);
  30.312  
  30.313      /**
  30.314       * Reads a sequence of bytes from this channel into the given buffer,
  30.315 @@ -673,13 +678,15 @@
  30.316       * <p> This method initiates the reading of a sequence of bytes from this
  30.317       * channel into the given buffer, starting at the given file position. This
  30.318       * method returns a {@code Future} representing the pending result of the
  30.319 -     * operation. The Future's {@link Future#get() get} method returns the
  30.320 -     * number of bytes read or {@code -1} if the given position is greater
  30.321 +     * operation. The {@code Future}'s {@link Future#get() get} method returns
  30.322 +     * the number of bytes read or {@code -1} if the given position is greater
  30.323       * than or equal to the file's size at the time that the read is attempted.
  30.324       *
  30.325 -     * <p> This method is equivalent to invoking {@link
  30.326 -     * #read(ByteBuffer,long,Object,CompletionHandler)} with the {@code attachment}
  30.327 -     * and handler parameters set to {@code null}.
  30.328 +     * <p> This method works in the same manner as the {@link
  30.329 +     * AsynchronousByteChannel#read(ByteBuffer)} method, except that bytes are
  30.330 +     * read starting at the given file position. If the given file position is
  30.331 +     * greater than the file's size at the time that the read is attempted then
  30.332 +     * no bytes are read.
  30.333       *
  30.334       * @param   dst
  30.335       *          The buffer into which bytes are to be transferred
  30.336 @@ -694,20 +701,12 @@
  30.337       * @throws  NonReadableChannelException
  30.338       *          If this channel was not opened for reading
  30.339       */
  30.340 -    public final Future<Integer> read(ByteBuffer dst, long position) {
  30.341 -        return read(dst, position, null, null);
  30.342 -    }
  30.343 +    public abstract Future<Integer> read(ByteBuffer dst, long position);
  30.344  
  30.345      /**
  30.346       * Writes a sequence of bytes to this channel from the given buffer, starting
  30.347       * at the given file position.
  30.348       *
  30.349 -     * <p> This method initiates the writing of a sequence of bytes to this channel
  30.350 -     * from the given buffer, starting at the given file position. The method
  30.351 -     * returns a {@code Future} representing the pending result of the write
  30.352 -     * operation. The Future's {@link Future#get() get} method returns the
  30.353 -     * number of bytes written.
  30.354 -     *
  30.355       * <p> This method works in the same manner as the {@link
  30.356       * AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)}
  30.357       * method, except that bytes are written starting at the given file position.
  30.358 @@ -724,36 +723,35 @@
  30.359       * @param   attachment
  30.360       *          The object to attach to the I/O operation; can be {@code null}
  30.361       * @param   handler
  30.362 -     *          The handler for consuming the result; can be {@code null}
  30.363 -     *
  30.364 -     * @return  A {@code Future} object representing the pending result
  30.365 +     *          The handler for consuming the result
  30.366       *
  30.367       * @throws  IllegalArgumentException
  30.368       *          If the position is negative
  30.369       * @throws  NonWritableChannelException
  30.370       *          If this channel was not opened for writing
  30.371 -     * @throws  ShutdownChannelGroupException
  30.372 -     *          If a handler is specified, the channel is closed, and the channel
  30.373 -     *          was originally created with its own thread pool
  30.374       */
  30.375 -    public abstract <A> Future<Integer> write(ByteBuffer src,
  30.376 -                                              long position,
  30.377 -                                              A attachment,
  30.378 -                                              CompletionHandler<Integer,? super A> handler);
  30.379 +    public abstract <A> void write(ByteBuffer src,
  30.380 +                                   long position,
  30.381 +                                   A attachment,
  30.382 +                                   CompletionHandler<Integer,? super A> handler);
  30.383  
  30.384      /**
  30.385       * Writes a sequence of bytes to this channel from the given buffer, starting
  30.386       * at the given file position.
  30.387       *
  30.388 -     * <p> This method initiates the writing of a sequence of bytes to this channel
  30.389 -     * from the given buffer, starting at the given file position. The method
  30.390 -     * returns a {@code Future} representing the pending result of the write
  30.391 -     * operation. The Future's {@link Future#get() get} method returns the
  30.392 -     * number of bytes written.
  30.393 +     * <p> This method initiates the writing of a sequence of bytes to this
  30.394 +     * channel from the given buffer, starting at the given file position. The
  30.395 +     * method returns a {@code Future} representing the pending result of the
  30.396 +     * write operation. The {@code Future}'s {@link Future#get() get} method
  30.397 +     * returns the number of bytes written.
  30.398       *
  30.399 -     * <p> This method is equivalent to invoking {@link
  30.400 -     * #write(ByteBuffer,long,Object,CompletionHandler)} with the {@code attachment}
  30.401 -     * and handler parameters set to {@code null}.
  30.402 +     * <p> This method works in the same manner as the {@link
  30.403 +     * AsynchronousByteChannel#write(ByteBuffer)} method, except that bytes are
  30.404 +     * written starting at the given file position. If the given position is
  30.405 +     * greater than the file's size, at the time that the write is attempted,
  30.406 +     * then the file will be grown to accommodate the new bytes; the values of
  30.407 +     * any bytes between the previous end-of-file and the newly-written bytes
  30.408 +     * are unspecified.
  30.409       *
  30.410       * @param   src
  30.411       *          The buffer from which bytes are to be transferred
  30.412 @@ -768,7 +766,5 @@
  30.413       * @throws  NonWritableChannelException
  30.414       *          If this channel was not opened for writing
  30.415       */
  30.416 -    public final Future<Integer> write(ByteBuffer src, long position) {
  30.417 -        return write(src, position, null, null);
  30.418 -    }
  30.419 +    public abstract Future<Integer> write(ByteBuffer src, long position);
  30.420  }
    31.1 --- a/src/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java	Mon Aug 24 17:26:09 2009 -0700
    31.2 +++ b/src/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java	Tue Sep 01 13:03:09 2009 -0700
    31.3 @@ -85,9 +85,6 @@
    31.4   *      public void failed(Throwable exc, Void att) {
    31.5   *          ...
    31.6   *      }
    31.7 - *      public void cancelled(Void att) {
    31.8 - *          ...
    31.9 - *      }
   31.10   *  });
   31.11   * </pre>
   31.12   *
   31.13 @@ -240,11 +237,11 @@
   31.14      /**
   31.15       * Accepts a connection.
   31.16       *
   31.17 -     * <p> This method initiates accepting a connection made to this channel's
   31.18 -     * socket, returning a {@link Future} representing the pending result
   31.19 -     * of the operation. The {@code Future}'s {@link Future#get() get}
   31.20 -     * method will return the {@link AsynchronousSocketChannel} for the new
   31.21 -     * connection on successful completion.
   31.22 +     * <p> This method initiates an asynchronous operation to accept a
   31.23 +     * connection made to this channel's socket. The {@code handler} parameter is
   31.24 +     * a completion handler that is invoked when a connection is accepted (or
   31.25 +     * the operation fails). The result passed to the completion handler is
   31.26 +     * the {@link AsynchronousSocketChannel} to the new connection.
   31.27       *
   31.28       * <p> When a new connection is accepted then the resulting {@code
   31.29       * AsynchronousSocketChannel} will be bound to the same {@link
   31.30 @@ -269,35 +266,35 @@
   31.31       * @param   attachment
   31.32       *          The object to attach to the I/O operation; can be {@code null}
   31.33       * @param   handler
   31.34 -     *          The handler for consuming the result; can be {@code null}
   31.35 -     *
   31.36 -     * @return  an <tt>Future</tt> object representing the pending result
   31.37 +     *          The handler for consuming the result
   31.38       *
   31.39       * @throws  AcceptPendingException
   31.40       *          If an accept operation is already in progress on this channel
   31.41       * @throws  NotYetBoundException
   31.42       *          If this channel's socket has not yet been bound
   31.43       * @throws  ShutdownChannelGroupException
   31.44 -     *          If a handler is specified, and the channel group is shutdown
   31.45 +     *          If the channel group has terminated
   31.46       */
   31.47 -    public abstract <A> Future<AsynchronousSocketChannel>
   31.48 -        accept(A attachment, CompletionHandler<AsynchronousSocketChannel,? super A> handler);
   31.49 +    public abstract <A> void accept(A attachment,
   31.50 +                                    CompletionHandler<AsynchronousSocketChannel,? super A> handler);
   31.51  
   31.52      /**
   31.53       * Accepts a connection.
   31.54       *
   31.55 -     * <p> This method is equivalent to invoking {@link
   31.56 -     * #accept(Object,CompletionHandler)} with the {@code attachment}
   31.57 -     * and {@code handler} parameters set to {@code null}.
   31.58 +     * <p> This method initiates an asynchronous operation to accept a
   31.59 +     * connection made to this channel's socket. The method behaves in exactly
   31.60 +     * the same manner as the {@link #accept(Object, CompletionHandler)} method
   31.61 +     * except that instead of specifying a completion handler, this method
   31.62 +     * returns a {@code Future} representing the pending result. The {@code
   31.63 +     * Future}'s {@link Future#get() get} method returns the {@link
   31.64 +     * AsynchronousSocketChannel} to the new connection on successful completion.
   31.65       *
   31.66 -     * @return  an <tt>Future</tt> object representing the pending result
   31.67 +     * @return  a {@code Future} object representing the pending result
   31.68       *
   31.69       * @throws  AcceptPendingException
   31.70       *          If an accept operation is already in progress on this channel
   31.71       * @throws  NotYetBoundException
   31.72       *          If this channel's socket has not yet been bound
   31.73       */
   31.74 -    public final Future<AsynchronousSocketChannel> accept() {
   31.75 -        return accept(null, null);
   31.76 -    }
   31.77 +    public abstract Future<AsynchronousSocketChannel> accept();
   31.78  }
    32.1 --- a/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java	Mon Aug 24 17:26:09 2009 -0700
    32.2 +++ b/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java	Tue Sep 01 13:03:09 2009 -0700
    32.3 @@ -274,14 +274,11 @@
    32.4      /**
    32.5       * Connects this channel.
    32.6       *
    32.7 -     * <p> This method initiates an operation to connect this channel, returning
    32.8 -     * a {@code Future} representing the pending result of the operation. If
    32.9 -     * the connection is successfully established then the {@code Future}'s
   32.10 -     * {@link Future#get() get} method will return {@code null}. If the
   32.11 -     * connection cannot be established then the channel is closed. In that case,
   32.12 -     * invoking the {@code get} method throws {@link
   32.13 -     * java.util.concurrent.ExecutionException} with an {@code IOException} as
   32.14 -     * the cause.
   32.15 +     * <p> This method initiates an operation to connect this channel. The
   32.16 +     * {@code handler} parameter is a completion handler that is invoked when
   32.17 +     * the connection is successfully established or connection cannot be
   32.18 +     * established. If the connection cannot be established then the channel is
   32.19 +     * closed.
   32.20       *
   32.21       * <p> This method performs exactly the same security checks as the {@link
   32.22       * java.net.Socket} class.  That is, if a security manager has been
   32.23 @@ -294,9 +291,7 @@
   32.24       * @param   attachment
   32.25       *          The object to attach to the I/O operation; can be {@code null}
   32.26       * @param   handler
   32.27 -     *          The handler for consuming the result; can be {@code null}
   32.28 -     *
   32.29 -     * @return  A {@code Future} object representing the pending result
   32.30 +     *          The handler for consuming the result
   32.31       *
   32.32       * @throws  UnresolvedAddressException
   32.33       *          If the given remote address is not fully resolved
   32.34 @@ -307,23 +302,26 @@
   32.35       * @throws  ConnectionPendingException
   32.36       *          If a connection operation is already in progress on this channel
   32.37       * @throws  ShutdownChannelGroupException
   32.38 -     *          If a handler is specified, and the channel group is shutdown
   32.39 +     *          If the channel group has terminated
   32.40       * @throws  SecurityException
   32.41       *          If a security manager has been installed
   32.42       *          and it does not permit access to the given remote endpoint
   32.43       *
   32.44       * @see #getRemoteAddress
   32.45       */
   32.46 -    public abstract <A> Future<Void> connect(SocketAddress remote,
   32.47 -                                             A attachment,
   32.48 -                                             CompletionHandler<Void,? super A> handler);
   32.49 +    public abstract <A> void connect(SocketAddress remote,
   32.50 +                                     A attachment,
   32.51 +                                     CompletionHandler<Void,? super A> handler);
   32.52  
   32.53      /**
   32.54       * Connects this channel.
   32.55       *
   32.56 -     * <p> This method is equivalent to invoking {@link
   32.57 -     * #connect(SocketAddress,Object,CompletionHandler)} with the {@code attachment}
   32.58 -     * and handler parameters set to {@code null}.
   32.59 +     * <p> This method initiates an operation to connect this channel. This
   32.60 +     * method behaves in exactly the same manner as the {@link
   32.61 +     * #connect(SocketAddress, Object, CompletionHandler)} method except that
   32.62 +     * instead of specifying a completion handler, this method returns a {@code
   32.63 +     * Future} representing the pending result. The {@code Future}'s {@link
   32.64 +     * Future#get() get} method returns {@code null} on successful completion.
   32.65       *
   32.66       * @param   remote
   32.67       *          The remote address to which this channel is to be connected
   32.68 @@ -342,18 +340,17 @@
   32.69       *          If a security manager has been installed
   32.70       *          and it does not permit access to the given remote endpoint
   32.71       */
   32.72 -    public final Future<Void> connect(SocketAddress remote) {
   32.73 -        return connect(remote, null, null);
   32.74 -    }
   32.75 +    public abstract Future<Void> connect(SocketAddress remote);
   32.76  
   32.77      /**
   32.78       * Reads a sequence of bytes from this channel into the given buffer.
   32.79       *
   32.80 -     * <p> This method initiates the reading of a sequence of bytes from this
   32.81 -     * channel into the given buffer, returning a {@code Future} representing
   32.82 -     * the pending result of the operation. The {@code Future}'s {@link
   32.83 -     * Future#get() get} method returns the number of bytes read or {@code -1}
   32.84 -     * if all bytes have been read and channel has reached end-of-stream.
   32.85 +     * <p> This method initiates an asynchronous read operation to read a
   32.86 +     * sequence of bytes from this channel into the given buffer. The {@code
   32.87 +     * handler} parameter is a completion handler that is invoked when the read
   32.88 +     * operation completes (or fails). The result passed to the completion
   32.89 +     * handler is the number of bytes read or {@code -1} if no bytes could be
   32.90 +     * read because the channel has reached end-of-stream.
   32.91       *
   32.92       * <p> If a timeout is specified and the timeout elapses before the operation
   32.93       * completes then the operation completes with the exception {@link
   32.94 @@ -376,9 +373,7 @@
   32.95       * @param   attachment
   32.96       *          The object to attach to the I/O operation; can be {@code null}
   32.97       * @param   handler
   32.98 -     *          The handler for consuming the result; can be {@code null}
   32.99 -     *
  32.100 -     * @return  A {@code Future} object representing the pending result
  32.101 +     *          The handler for consuming the result
  32.102       *
  32.103       * @throws  IllegalArgumentException
  32.104       *          If the {@code timeout} parameter is negative or the buffer is
  32.105 @@ -388,13 +383,13 @@
  32.106       * @throws  NotYetConnectedException
  32.107       *          If this channel is not yet connected
  32.108       * @throws  ShutdownChannelGroupException
  32.109 -     *          If a handler is specified, and the channel group is shutdown
  32.110 +     *          If the channel group has terminated
  32.111       */
  32.112 -    public abstract <A> Future<Integer> read(ByteBuffer dst,
  32.113 -                                             long timeout,
  32.114 -                                             TimeUnit unit,
  32.115 -                                             A attachment,
  32.116 -                                             CompletionHandler<Integer,? super A> handler);
  32.117 +    public abstract <A> void read(ByteBuffer dst,
  32.118 +                                  long timeout,
  32.119 +                                  TimeUnit unit,
  32.120 +                                  A attachment,
  32.121 +                                  CompletionHandler<Integer,? super A> handler);
  32.122  
  32.123      /**
  32.124       * @throws  IllegalArgumentException        {@inheritDoc}
  32.125 @@ -402,14 +397,14 @@
  32.126       * @throws  NotYetConnectedException
  32.127       *          If this channel is not yet connected
  32.128       * @throws  ShutdownChannelGroupException
  32.129 -     *          If a handler is specified, and the channel group is shutdown
  32.130 +     *          If the channel group has terminated
  32.131       */
  32.132      @Override
  32.133 -    public final <A> Future<Integer> read(ByteBuffer dst,
  32.134 -                                          A attachment,
  32.135 -                                          CompletionHandler<Integer,? super A> handler)
  32.136 +    public final <A> void read(ByteBuffer dst,
  32.137 +                               A attachment,
  32.138 +                               CompletionHandler<Integer,? super A> handler)
  32.139      {
  32.140 -        return read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
  32.141 +        read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
  32.142      }
  32.143  
  32.144      /**
  32.145 @@ -419,16 +414,18 @@
  32.146       *          If this channel is not yet connected
  32.147       */
  32.148      @Override
  32.149 -    public final Future<Integer> read(ByteBuffer dst) {
  32.150 -        return read(dst, 0L, TimeUnit.MILLISECONDS, null, null);
  32.151 -    }
  32.152 +    public abstract Future<Integer> read(ByteBuffer dst);
  32.153  
  32.154      /**
  32.155       * Reads a sequence of bytes from this channel into a subsequence of the
  32.156       * given buffers. This operation, sometimes called a <em>scattering read</em>,
  32.157       * is often useful when implementing network protocols that group data into
  32.158       * segments consisting of one or more fixed-length headers followed by a
  32.159 -     * variable-length body.
  32.160 +     * variable-length body. The {@code handler} parameter is a completion
  32.161 +     * handler that is invoked when the read operation completes (or fails). The
  32.162 +     * result passed to the completion handler is the number of bytes read or
  32.163 +     * {@code -1} if no bytes could be read because the channel has reached
  32.164 +     * end-of-stream.
  32.165       *
  32.166       * <p> This method initiates a read of up to <i>r</i> bytes from this channel,
  32.167       * where <i>r</i> is the total number of bytes remaining in the specified
  32.168 @@ -456,11 +453,6 @@
  32.169       * I/O operation is performed with the maximum number of buffers allowed by
  32.170       * the operating system.
  32.171       *
  32.172 -     * <p> The return value from this method is a {@code Future} representing
  32.173 -     * the pending result of the operation. The {@code Future}'s {@link
  32.174 -     * Future#get() get} method returns the number of bytes read or {@code -1L}
  32.175 -     * if all bytes have been read and the channel has reached end-of-stream.
  32.176 -     *
  32.177       * <p> If a timeout is specified and the timeout elapses before the operation
  32.178       * completes then it completes with the exception {@link
  32.179       * InterruptedByTimeoutException}. Where a timeout occurs, and the
  32.180 @@ -485,9 +477,7 @@
  32.181       * @param   attachment
  32.182       *          The object to attach to the I/O operation; can be {@code null}
  32.183       * @param   handler
  32.184 -     *          The handler for consuming the result; can be {@code null}
  32.185 -     *
  32.186 -     * @return  A {@code Future} object representing the pending result
  32.187 +     *          The handler for consuming the result
  32.188       *
  32.189       * @throws  IndexOutOfBoundsException
  32.190       *          If the pre-conditions for the {@code offset}  and {@code length}
  32.191 @@ -500,23 +490,24 @@
  32.192       * @throws  NotYetConnectedException
  32.193       *          If this channel is not yet connected
  32.194       * @throws  ShutdownChannelGroupException
  32.195 -     *          If a handler is specified, and the channel group is shutdown
  32.196 +     *          If the channel group has terminated
  32.197       */
  32.198 -    public abstract <A> Future<Long> read(ByteBuffer[] dsts,
  32.199 -                                          int offset,
  32.200 -                                          int length,
  32.201 -                                          long timeout,
  32.202 -                                          TimeUnit unit,
  32.203 -                                          A attachment,
  32.204 -                                          CompletionHandler<Long,? super A> handler);
  32.205 +    public abstract <A> void read(ByteBuffer[] dsts,
  32.206 +                                  int offset,
  32.207 +                                  int length,
  32.208 +                                  long timeout,
  32.209 +                                  TimeUnit unit,
  32.210 +                                  A attachment,
  32.211 +                                  CompletionHandler<Long,? super A> handler);
  32.212  
  32.213      /**
  32.214       * Writes a sequence of bytes to this channel from the given buffer.
  32.215       *
  32.216 -     * <p> This method initiates the writing of a sequence of bytes to this channel
  32.217 -     * from the given buffer, returning a {@code Future} representing the
  32.218 -     * pending result of the operation. The {@code Future}'s {@link Future#get()
  32.219 -     * get} method will return the number of bytes written.
  32.220 +     * <p> This method initiates an asynchronous write operation to write a
  32.221 +     * sequence of bytes to this channel from the given buffer. The {@code
  32.222 +     * handler} parameter is a completion handler that is invoked when the write
  32.223 +     * operation completes (or fails). The result passed to the completion
  32.224 +     * handler is the number of bytes written.
  32.225       *
  32.226       * <p> If a timeout is specified and the timeout elapses before the operation
  32.227       * completes then it completes with the exception {@link
  32.228 @@ -539,9 +530,7 @@
  32.229       * @param   attachment
  32.230       *          The object to attach to the I/O operation; can be {@code null}
  32.231       * @param   handler
  32.232 -     *          The handler for consuming the result; can be {@code null}
  32.233 -     *
  32.234 -     * @return  A {@code Future} object representing the pending result
  32.235 +     *          The handler for consuming the result
  32.236       *
  32.237       * @throws  IllegalArgumentException
  32.238       *          If the {@code timeout} parameter is negative
  32.239 @@ -550,28 +539,28 @@
  32.240       * @throws  NotYetConnectedException
  32.241       *          If this channel is not yet connected
  32.242       * @throws  ShutdownChannelGroupException
  32.243 -     *          If a handler is specified, and the channel group is shutdown
  32.244 +     *          If the channel group has terminated
  32.245       */
  32.246 -    public abstract <A> Future<Integer> write(ByteBuffer src,
  32.247 -                                              long timeout,
  32.248 -                                              TimeUnit unit,
  32.249 -                                              A attachment,
  32.250 -                                              CompletionHandler<Integer,? super A> handler);
  32.251 +    public abstract <A> void write(ByteBuffer src,
  32.252 +                                   long timeout,
  32.253 +                                   TimeUnit unit,
  32.254 +                                   A attachment,
  32.255 +                                   CompletionHandler<Integer,? super A> handler);
  32.256  
  32.257      /**
  32.258       * @throws  WritePendingException          {@inheritDoc}
  32.259       * @throws  NotYetConnectedException
  32.260       *          If this channel is not yet connected
  32.261       * @throws  ShutdownChannelGroupException
  32.262 -     *          If a handler is specified, and the channel group is shutdown
  32.263 +     *          If the channel group has terminated
  32.264       */
  32.265      @Override
  32.266 -    public final <A> Future<Integer> write(ByteBuffer src,
  32.267 -                                           A attachment,
  32.268 -                                           CompletionHandler<Integer,? super A> handler)
  32.269 +    public final <A> void write(ByteBuffer src,
  32.270 +                                A attachment,
  32.271 +                                CompletionHandler<Integer,? super A> handler)
  32.272  
  32.273      {
  32.274 -        return write(src, 0L, TimeUnit.MILLISECONDS, attachment, handler);
  32.275 +        write(src, 0L, TimeUnit.MILLISECONDS, attachment, handler);
  32.276      }
  32.277  
  32.278      /**
  32.279 @@ -580,16 +569,16 @@
  32.280       *          If this channel is not yet connected
  32.281       */
  32.282      @Override
  32.283 -    public final Future<Integer> write(ByteBuffer src) {
  32.284 -        return write(src, 0L, TimeUnit.MILLISECONDS, null, null);
  32.285 -    }
  32.286 +    public abstract Future<Integer> write(ByteBuffer src);
  32.287  
  32.288      /**
  32.289       * Writes a sequence of bytes to this channel from a subsequence of the given
  32.290       * buffers. This operation, sometimes called a <em>gathering write</em>, is
  32.291       * often useful when implementing network protocols that group data into
  32.292       * segments consisting of one or more fixed-length headers followed by a
  32.293 -     * variable-length body.
  32.294 +     * variable-length body. The {@code handler} parameter is a completion
  32.295 +     * handler that is invoked when the write operation completes (or fails).
  32.296 +     * The result passed to the completion handler is the number of bytes written.
  32.297       *
  32.298       * <p> This method initiates a write of up to <i>r</i> bytes to this channel,
  32.299       * where <i>r</i> is the total number of bytes remaining in the specified
  32.300 @@ -616,10 +605,6 @@
  32.301       * remaining), exceeds this limit, then the I/O operation is performed with
  32.302       * the maximum number of buffers allowed by the operating system.
  32.303       *
  32.304 -     * <p> The return value from this method is a {@code Future} representing
  32.305 -     * the pending result of the operation. The {@code Future}'s {@link
  32.306 -     * Future#get() get} method will return the number of bytes written.
  32.307 -     *
  32.308       * <p> If a timeout is specified and the timeout elapses before the operation
  32.309       * completes then it completes with the exception {@link
  32.310       * InterruptedByTimeoutException}. Where a timeout occurs, and the
  32.311 @@ -644,9 +629,7 @@
  32.312       * @param   attachment
  32.313       *          The object to attach to the I/O operation; can be {@code null}
  32.314       * @param   handler
  32.315 -     *          The handler for consuming the result; can be {@code null}
  32.316 -     *
  32.317 -     * @return  A {@code Future} object representing the pending result
  32.318 +     *          The handler for consuming the result
  32.319       *
  32.320       * @throws  IndexOutOfBoundsException
  32.321       *          If the pre-conditions for the {@code offset}  and {@code length}
  32.322 @@ -658,13 +641,13 @@
  32.323       * @throws  NotYetConnectedException
  32.324       *          If this channel is not yet connected
  32.325       * @throws  ShutdownChannelGroupException
  32.326 -     *          If a handler is specified, and the channel group is shutdown
  32.327 +     *          If the channel group has terminated
  32.328       */
  32.329 -    public abstract <A> Future<Long> write(ByteBuffer[] srcs,
  32.330 -                                           int offset,
  32.331 -                                           int length,
  32.332 -                                           long timeout,
  32.333 -                                           TimeUnit unit,
  32.334 -                                           A attachment,
  32.335 -                                           CompletionHandler<Long,? super A> handler);
  32.336 +    public abstract <A> void write(ByteBuffer[] srcs,
  32.337 +                                   int offset,
  32.338 +                                   int length,
  32.339 +                                   long timeout,
  32.340 +                                   TimeUnit unit,
  32.341 +                                   A attachment,
  32.342 +                                   CompletionHandler<Long,? super A> handler);
  32.343  }
    33.1 --- a/src/share/classes/java/nio/channels/Channels.java	Mon Aug 24 17:26:09 2009 -0700
    33.2 +++ b/src/share/classes/java/nio/channels/Channels.java	Tue Sep 01 13:03:09 2009 -0700
    33.3 @@ -182,7 +182,6 @@
    33.4      }
    33.5  
    33.6      /**
    33.7 -     * {@note new}
    33.8       * Constructs a stream that reads bytes from the given channel.
    33.9       *
   33.10       * <p> The stream will not be buffered, and it will not support the {@link
   33.11 @@ -258,7 +257,6 @@
   33.12      }
   33.13  
   33.14      /**
   33.15 -     * {@note new}
   33.16       * Constructs a stream that writes bytes to the given channel.
   33.17       *
   33.18       * <p> The stream will not be buffered. The stream will be safe for access
    34.1 --- a/src/share/classes/java/nio/channels/CompletionHandler.java	Mon Aug 24 17:26:09 2009 -0700
    34.2 +++ b/src/share/classes/java/nio/channels/CompletionHandler.java	Tue Sep 01 13:03:09 2009 -0700
    34.3 @@ -32,11 +32,9 @@
    34.4   * handler to be specified to consume the result of an asynchronous operation.
    34.5   * The {@link #completed completed} method is invoked when the I/O operation
    34.6   * completes successfully. The {@link #failed failed} method is invoked if the
    34.7 - * I/O operations fails. The {@link #cancelled cancelled} method is invoked when
    34.8 - * the I/O operation is cancelled by invoking the {@link
    34.9 - * java.util.concurrent.Future#cancel cancel} method. The implementations of
   34.10 - * these methods should complete in a timely manner so as to avoid keeping the
   34.11 - * invoking thread from dispatching to other completion handlers.
   34.12 + * I/O operations fails. The implementations of these methods should complete
   34.13 + * in a timely manner so as to avoid keeping the invoking thread from dispatching
   34.14 + * to other completion handlers.
   34.15   *
   34.16   * @param   <V>     The result type of the I/O operation
   34.17   * @param   <A>     The type of the object attached to the I/O operation
   34.18 @@ -65,13 +63,4 @@
   34.19       *          The object attached to the I/O operation when it was initiated.
   34.20       */
   34.21      void failed(Throwable exc, A attachment);
   34.22 -
   34.23 -    /**
   34.24 -     * Invoked when an operation is cancelled by invoking the {@link
   34.25 -     * java.util.concurrent.Future#cancel cancel} method.
   34.26 -     *
   34.27 -     * @param   attachment
   34.28 -     *          The object attached to the I/O operation when it was initiated.
   34.29 -     */
   34.30 -    void cancelled(A attachment);
   34.31  }
    35.1 --- a/src/share/classes/java/nio/channels/FileChannel.java	Mon Aug 24 17:26:09 2009 -0700
    35.2 +++ b/src/share/classes/java/nio/channels/FileChannel.java	Tue Sep 01 13:03:09 2009 -0700
    35.3 @@ -39,8 +39,7 @@
    35.4  /**
    35.5   * A channel for reading, writing, mapping, and manipulating a file.
    35.6   *
    35.7 - * <p> {@note revised}
    35.8 - * A file channel is a {@link SeekableByteChannel} that is connected to
    35.9 + * <p> A file channel is a {@link SeekableByteChannel} that is connected to
   35.10   * a file. It has a current <i>position</i> within its file which can
   35.11   * be both {@link #position() <i>queried</i>} and {@link #position(long)
   35.12   * <i>modified</i>}.  The file itself contains a variable-length sequence
   35.13 @@ -151,7 +150,6 @@
   35.14   * @author Mike McCloskey
   35.15   * @author JSR-51 Expert Group
   35.16   * @since 1.4
   35.17 - * @updated 1.7
   35.18   */
   35.19  
   35.20  public abstract class FileChannel
   35.21 @@ -164,7 +162,6 @@
   35.22      protected FileChannel() { }
   35.23  
   35.24      /**
   35.25 -     * {@note new}
   35.26       * Opens or creates a file, returning a file channel to access the file.
   35.27       *
   35.28       * <p> The {@code options} parameter determines how the file is opened.
   35.29 @@ -293,7 +290,6 @@
   35.30      private static final FileAttribute<?>[] NO_ATTRIBUTES = new FileAttribute[0];
   35.31  
   35.32      /**
   35.33 -     * {@note new}
   35.34       * Opens or creates a file, returning a file channel to access the file.
   35.35       *
   35.36       * <p> An invocation of this method behaves in exactly the same way as the
    36.1 --- a/src/share/classes/java/nio/channels/FileLock.java	Mon Aug 24 17:26:09 2009 -0700
    36.2 +++ b/src/share/classes/java/nio/channels/FileLock.java	Tue Sep 01 13:03:09 2009 -0700
    36.3 @@ -114,7 +114,6 @@
    36.4   * @author Mark Reinhold
    36.5   * @author JSR-51 Expert Group
    36.6   * @since 1.4
    36.7 - * @updated 1.7
    36.8   */
    36.9  
   36.10  public abstract class FileLock {
   36.11 @@ -161,7 +160,7 @@
   36.12      }
   36.13  
   36.14      /**
   36.15 -     * {@note new} Initializes a new instance of this class.
   36.16 +     * Initializes a new instance of this class.
   36.17       *
   36.18       * @param  channel
   36.19       *         The channel upon whose file this lock is held
   36.20 @@ -199,7 +198,6 @@
   36.21      }
   36.22  
   36.23      /**
   36.24 -     * {@note revised}
   36.25       * Returns the file channel upon whose file this lock was acquired.
   36.26       *
   36.27       * <p> This method has been superseded by the {@link #acquiredBy acquiredBy}
   36.28 @@ -213,7 +211,6 @@
   36.29      }
   36.30  
   36.31      /**
   36.32 -     * {@note new}
   36.33       * Returns the channel upon whose file this lock was acquired.
   36.34       *
   36.35       * @return  The channel upon whose file this lock was acquired.
    37.1 --- a/src/share/classes/java/nio/channels/exceptions	Mon Aug 24 17:26:09 2009 -0700
    37.2 +++ b/src/share/classes/java/nio/channels/exceptions	Tue Sep 01 13:03:09 2009 -0700
    37.3 @@ -190,5 +190,5 @@
    37.4  gen ShutdownChannelGroupException "
    37.5   * Unchecked exception thrown when an attempt is made to construct a channel in 
    37.6   * a group that is shutdown or the completion handler for an I/O operation 
    37.7 - * cannot be invoked because the channel group is shutdown." \
    37.8 + * cannot be invoked because the channel group has terminated." \
    37.9   -3903801676350154157L
    38.1 --- a/src/share/classes/java/nio/channels/package-info.java	Mon Aug 24 17:26:09 2009 -0700
    38.2 +++ b/src/share/classes/java/nio/channels/package-info.java	Tue Sep 01 13:03:09 2009 -0700
    38.3 @@ -285,7 +285,6 @@
    38.4   * java.lang.NullPointerException NullPointerException} to be thrown.
    38.5   *
    38.6   * @since 1.4
    38.7 - * @updated 1.7
    38.8   * @author Mark Reinhold
    38.9   * @author JSR-51 Expert Group
   38.10   */
    39.1 --- a/src/share/classes/java/nio/file/FileRef.java	Mon Aug 24 17:26:09 2009 -0700
    39.2 +++ b/src/share/classes/java/nio/file/FileRef.java	Tue Sep 01 13:03:09 2009 -0700
    39.3 @@ -39,8 +39,6 @@
    39.4   * metadata or file attributes.
    39.5   *
    39.6   * @since 1.7
    39.7 - * @see java.io.Inputs
    39.8 - * @see java.io.Outputs
    39.9   * @see java.nio.file.attribute.Attributes
   39.10   * @see java.io.File#toPath
   39.11   */
    40.1 --- a/src/share/classes/java/util/Scanner.java	Mon Aug 24 17:26:09 2009 -0700
    40.2 +++ b/src/share/classes/java/util/Scanner.java	Tue Sep 01 13:03:09 2009 -0700
    40.3 @@ -674,7 +674,6 @@
    40.4      }
    40.5  
    40.6      /**
    40.7 -     * {@note new}
    40.8       * Constructs a new <code>Scanner</code> that produces values scanned
    40.9       * from the specified file. Bytes from the file are converted into
   40.10       * characters using the underlying platform's
   40.11 @@ -694,7 +693,6 @@
   40.12      }
   40.13  
   40.14      /**
   40.15 -     * {@note new}
   40.16       * Constructs a new <code>Scanner</code> that produces values scanned
   40.17       * from the specified file. Bytes from the file are converted into
   40.18       * characters using the specified charset.
    41.1 --- a/src/share/classes/sun/nio/ch/AbstractFuture.java	Mon Aug 24 17:26:09 2009 -0700
    41.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.3 @@ -1,63 +0,0 @@
    41.4 -/*
    41.5 - * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
    41.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    41.7 - *
    41.8 - * This code is free software; you can redistribute it and/or modify it
    41.9 - * under the terms of the GNU General Public License version 2 only, as
   41.10 - * published by the Free Software Foundation.  Sun designates this
   41.11 - * particular file as subject to the "Classpath" exception as provided
   41.12 - * by Sun in the LICENSE file that accompanied this code.
   41.13 - *
   41.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
   41.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   41.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   41.17 - * version 2 for more details (a copy is included in the LICENSE file that
   41.18 - * accompanied this code).
   41.19 - *
   41.20 - * You should have received a copy of the GNU General Public License version
   41.21 - * 2 along with this work; if not, write to the Free Software Foundation,
   41.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   41.23 - *
   41.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   41.25 - * CA 95054 USA or visit www.sun.com if you need additional information or
   41.26 - * have any questions.
   41.27 - */
   41.28 -
   41.29 -package sun.nio.ch;
   41.30 -
   41.31 -import java.nio.channels.AsynchronousChannel;
   41.32 -import java.util.concurrent.Future;
   41.33 -
   41.34 -/**
   41.35 - * Base implementation of Future used for asynchronous I/O
   41.36 - */
   41.37 -
   41.38 -abstract class AbstractFuture<V,A>
   41.39 -    implements Future<V>
   41.40 -{
   41.41 -    private final AsynchronousChannel channel;
   41.42 -    private final A attachment;
   41.43 -
   41.44 -    protected AbstractFuture(AsynchronousChannel channel, A attachment) {
   41.45 -        this.channel = channel;
   41.46 -        this.attachment = attachment;
   41.47 -    }
   41.48 -
   41.49 -    final AsynchronousChannel channel() {
   41.50 -        return channel;
   41.51 -    }
   41.52 -
   41.53 -    final A attachment() {
   41.54 -        return attachment;
   41.55 -    }
   41.56 -
   41.57 -    /**
   41.58 -     * Returns the result of the operation if it has completed successfully.
   41.59 -     */
   41.60 -    abstract V value();
   41.61 -
   41.62 -    /**
   41.63 -     * Returns the exception if the operation has failed.
   41.64 -     */
   41.65 -    abstract Throwable exception();
   41.66 -}
    42.1 --- a/src/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java	Mon Aug 24 17:26:09 2009 -0700
    42.2 +++ b/src/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java	Tue Sep 01 13:03:09 2009 -0700
    42.3 @@ -32,8 +32,8 @@
    42.4  import java.io.FileDescriptor;
    42.5  import java.util.Queue;
    42.6  import java.util.concurrent.*;
    42.7 -import java.util.concurrent.locks.*;
    42.8  import java.util.concurrent.atomic.AtomicInteger;
    42.9 +import java.util.concurrent.atomic.AtomicBoolean;
   42.10  import java.security.PrivilegedAction;
   42.11  import java.security.AccessController;
   42.12  import java.security.AccessControlContext;
   42.13 @@ -65,11 +65,8 @@
   42.14      private final Queue<Runnable> taskQueue;
   42.15  
   42.16      // group shutdown
   42.17 -    // shutdownLock is RW lock so as to allow for concurrent queuing of tasks
   42.18 -    // when using a fixed thread pool.
   42.19 -    private final ReadWriteLock shutdownLock = new ReentrantReadWriteLock();
   42.20 +    private final AtomicBoolean shutdown = new AtomicBoolean();
   42.21      private final Object shutdownNowLock = new Object();
   42.22 -    private volatile boolean shutdown;
   42.23      private volatile boolean terminateInitiated;
   42.24  
   42.25      AsynchronousChannelGroupImpl(AsynchronousChannelProvider provider,
   42.26 @@ -214,7 +211,7 @@
   42.27  
   42.28      @Override
   42.29      public final boolean isShutdown() {
   42.30 -        return shutdown;
   42.31 +        return shutdown.get();
   42.32      }
   42.33  
   42.34      @Override
   42.35 @@ -260,17 +257,10 @@
   42.36  
   42.37      @Override
   42.38      public final void shutdown() {
   42.39 -        shutdownLock.writeLock().lock();
   42.40 -        try {
   42.41 -            if (shutdown) {
   42.42 -                // already shutdown
   42.43 -                return;
   42.44 -            }
   42.45 -            shutdown = true;
   42.46 -        } finally {
   42.47 -            shutdownLock.writeLock().unlock();
   42.48 +        if (shutdown.getAndSet(true)) {
   42.49 +            // already shutdown
   42.50 +            return;
   42.51          }
   42.52 -
   42.53          // if there are channels in the group then shutdown will continue
   42.54          // when the last channel is closed
   42.55          if (!isEmpty()) {
   42.56 @@ -289,12 +279,7 @@
   42.57  
   42.58      @Override
   42.59      public final void shutdownNow() throws IOException {
   42.60 -        shutdownLock.writeLock().lock();
   42.61 -        try {
   42.62 -            shutdown = true;
   42.63 -        } finally {
   42.64 -            shutdownLock.writeLock().unlock();
   42.65 -        }
   42.66 +        shutdown.set(true);
   42.67          synchronized (shutdownNowLock) {
   42.68              if (!terminateInitiated) {
   42.69                  terminateInitiated = true;
   42.70 @@ -305,6 +290,18 @@
   42.71          }
   42.72      }
   42.73  
   42.74 +    /**
   42.75 +     * For use by AsynchronousFileChannel to release resources without shutting
   42.76 +     * down the thread pool.
   42.77 +     */
   42.78 +    final void detachFromThreadPool() {
   42.79 +        if (shutdown.getAndSet(true))
   42.80 +            throw new AssertionError("Already shutdown");
   42.81 +        if (!isEmpty())
   42.82 +            throw new AssertionError("Group not empty");
   42.83 +        shutdownHandlerTasks();
   42.84 +    }
   42.85 +
   42.86      @Override
   42.87      public final boolean awaitTermination(long timeout, TimeUnit unit)
   42.88          throws InterruptedException
    43.1 --- a/src/share/classes/sun/nio/ch/AsynchronousFileChannelImpl.java	Mon Aug 24 17:26:09 2009 -0700
    43.2 +++ b/src/share/classes/sun/nio/ch/AsynchronousFileChannelImpl.java	Tue Sep 01 13:03:09 2009 -0700
    43.3 @@ -25,8 +25,10 @@
    43.4  
    43.5  package sun.nio.ch;
    43.6  
    43.7 +import java.nio.ByteBuffer;
    43.8  import java.nio.channels.*;
    43.9  import java.util.concurrent.ExecutorService;
   43.10 +import java.util.concurrent.Future;
   43.11  import java.util.concurrent.locks.*;
   43.12  import java.io.FileDescriptor;
   43.13  import java.io.IOException;
   43.14 @@ -101,6 +103,33 @@
   43.15  
   43.16      // -- file locking --
   43.17  
   43.18 +    abstract <A> Future<FileLock> implLock(long position,
   43.19 +                                           long size,
   43.20 +                                           boolean shared,
   43.21 +                                           A attachment,
   43.22 +                                           CompletionHandler<FileLock,? super A> handler);
   43.23 +
   43.24 +    @Override
   43.25 +    public final Future<FileLock> lock(long position,
   43.26 +                                       long size,
   43.27 +                                       boolean shared)
   43.28 +
   43.29 +    {
   43.30 +        return implLock(position, size, shared, null, null);
   43.31 +    }
   43.32 +
   43.33 +    @Override
   43.34 +    public final <A> void lock(long position,
   43.35 +                               long size,
   43.36 +                               boolean shared,
   43.37 +                               A attachment,
   43.38 +                               CompletionHandler<FileLock,? super A> handler)
   43.39 +    {
   43.40 +        if (handler == null)
   43.41 +            throw new NullPointerException("'handler' is null");
   43.42 +        implLock(position, size, shared, attachment, handler);
   43.43 +    }
   43.44 +
   43.45      private volatile FileLockTable fileLockTable;
   43.46  
   43.47      final void ensureFileLockTableInitialized() throws IOException {
   43.48 @@ -175,4 +204,50 @@
   43.49              end();
   43.50          }
   43.51      }
   43.52 +
   43.53 +
   43.54 +    // -- reading and writing --
   43.55 +
   43.56 +    abstract <A> Future<Integer> implRead(ByteBuffer dst,
   43.57 +                                         long position,
   43.58 +                                         A attachment,
   43.59 +                                         CompletionHandler<Integer,? super A> handler);
   43.60 +
   43.61 +    @Override
   43.62 +    public final Future<Integer> read(ByteBuffer dst, long position) {
   43.63 +        return implRead(dst, position, null, null);
   43.64 +    }
   43.65 +
   43.66 +    @Override
   43.67 +    public final <A> void read(ByteBuffer dst,
   43.68 +                               long position,
   43.69 +                               A attachment,
   43.70 +                               CompletionHandler<Integer,? super A> handler)
   43.71 +    {
   43.72 +        if (handler == null)
   43.73 +            throw new NullPointerException("'handler' is null");
   43.74 +        implRead(dst, position, attachment, handler);
   43.75 +    }
   43.76 +
   43.77 +    abstract <A> Future<Integer> implWrite(ByteBuffer src,
   43.78 +                                           long position,
   43.79 +                                           A attachment,
   43.80 +                                           CompletionHandler<Integer,? super A> handler);
   43.81 +
   43.82 +
   43.83 +    @Override
   43.84 +    public final Future<Integer> write(ByteBuffer src, long position) {
   43.85 +        return implWrite(src, position, null, null);
   43.86 +    }
   43.87 +
   43.88 +    @Override
   43.89 +    public final <A> void write(ByteBuffer src,
   43.90 +                                long position,
   43.91 +                                A attachment,
   43.92 +                                CompletionHandler<Integer,? super A> handler)
   43.93 +    {
   43.94 +        if (handler == null)
   43.95 +            throw new NullPointerException("'handler' is null");
   43.96 +        implWrite(src, position, attachment, handler);
   43.97 +    }
   43.98  }
    44.1 --- a/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java	Mon Aug 24 17:26:09 2009 -0700
    44.2 +++ b/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java	Tue Sep 01 13:03:09 2009 -0700
    44.3 @@ -35,6 +35,7 @@
    44.4  import java.util.Set;
    44.5  import java.util.HashSet;
    44.6  import java.util.Collections;
    44.7 +import java.util.concurrent.Future;
    44.8  import java.util.concurrent.locks.ReadWriteLock;
    44.9  import java.util.concurrent.locks.ReentrantReadWriteLock;
   44.10  import sun.net.NetHooks;
   44.11 @@ -108,6 +109,29 @@
   44.12          implClose();
   44.13      }
   44.14  
   44.15 +    /**
   44.16 +     * Invoked by accept to accept connection
   44.17 +     */
   44.18 +    abstract Future<AsynchronousSocketChannel>
   44.19 +        implAccept(Object attachment,
   44.20 +                   CompletionHandler<AsynchronousSocketChannel,Object> handler);
   44.21 +
   44.22 +
   44.23 +    @Override
   44.24 +    public final Future<AsynchronousSocketChannel> accept() {
   44.25 +        return implAccept(null, null);
   44.26 +    }
   44.27 +
   44.28 +    @Override
   44.29 +    @SuppressWarnings("unchecked")
   44.30 +    public final <A> void accept(A attachment,
   44.31 +                                 CompletionHandler<AsynchronousSocketChannel,? super A> handler)
   44.32 +    {
   44.33 +        if (handler == null)
   44.34 +            throw new NullPointerException("'handler' is null");
   44.35 +        implAccept(attachment, (CompletionHandler<AsynchronousSocketChannel,Object>)handler);
   44.36 +    }
   44.37 +
   44.38      final boolean isAcceptKilled() {
   44.39          return acceptKilled;
   44.40      }
    45.1 --- a/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java	Mon Aug 24 17:26:09 2009 -0700
    45.2 +++ b/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java	Tue Sep 01 13:03:09 2009 -0700
    45.3 @@ -184,28 +184,53 @@
    45.4      }
    45.5  
    45.6      /**
    45.7 +     * Invoked by connect to initiate the connect operation.
    45.8 +     */
    45.9 +    abstract <A> Future<Void> implConnect(SocketAddress remote,
   45.10 +                                          A attachment,
   45.11 +                                          CompletionHandler<Void,? super A> handler);
   45.12 +
   45.13 +    @Override
   45.14 +    public final Future<Void> connect(SocketAddress remote) {
   45.15 +        return implConnect(remote, null, null);
   45.16 +    }
   45.17 +
   45.18 +    @Override
   45.19 +    public final <A> void connect(SocketAddress remote,
   45.20 +                                  A attachment,
   45.21 +                                  CompletionHandler<Void,? super A> handler)
   45.22 +    {
   45.23 +        if (handler == null)
   45.24 +            throw new NullPointerException("'handler' is null");
   45.25 +        implConnect(remote, attachment, handler);
   45.26 +    }
   45.27 +
   45.28 +    /**
   45.29       * Invoked by read to initiate the I/O operation.
   45.30       */
   45.31 -    abstract <V extends Number,A> Future<V> readImpl(ByteBuffer[] dsts,
   45.32 -                                                     boolean isScatteringRead,
   45.33 +    abstract <V extends Number,A> Future<V> implRead(boolean isScatteringRead,
   45.34 +                                                     ByteBuffer dst,
   45.35 +                                                     ByteBuffer[] dsts,
   45.36                                                       long timeout,
   45.37                                                       TimeUnit unit,
   45.38                                                       A attachment,
   45.39                                                       CompletionHandler<V,? super A> handler);
   45.40  
   45.41      @SuppressWarnings("unchecked")
   45.42 -    private <V extends Number,A> Future<V> read(ByteBuffer[] dsts,
   45.43 -                                                boolean isScatteringRead,
   45.44 +    private <V extends Number,A> Future<V> read(boolean isScatteringRead,
   45.45 +                                                ByteBuffer dst,
   45.46 +                                                ByteBuffer[] dsts,
   45.47                                                  long timeout,
   45.48                                                  TimeUnit unit,
   45.49 -                                                A attachment,
   45.50 +                                                A att,
   45.51                                                  CompletionHandler<V,? super A> handler)
   45.52      {
   45.53          if (!isOpen()) {
   45.54 -            CompletedFuture<V,A> result = CompletedFuture
   45.55 -                .withFailure(this, new ClosedChannelException(), attachment);
   45.56 -            Invoker.invoke(handler, result);
   45.57 -            return result;
   45.58 +            Throwable e = new ClosedChannelException();
   45.59 +            if (handler == null)
   45.60 +                return CompletedFuture.withFailure(e);
   45.61 +            Invoker.invoke(this, handler, att, null, e);
   45.62 +            return null;
   45.63          }
   45.64  
   45.65          if (remoteAddress == null)
   45.66 @@ -213,13 +238,13 @@
   45.67          if (timeout < 0L)
   45.68              throw new IllegalArgumentException("Negative timeout");
   45.69  
   45.70 -        boolean hasSpaceToRead = isScatteringRead || dsts[0].hasRemaining();
   45.71 +        boolean hasSpaceToRead = isScatteringRead || dst.hasRemaining();
   45.72          boolean shutdown = false;
   45.73  
   45.74          // check and update state
   45.75          synchronized (readLock) {
   45.76              if (readKilled)
   45.77 -                throw new RuntimeException("Reading not allowed due to timeout or cancellation");
   45.78 +                throw new IllegalStateException("Reading not allowed due to timeout or cancellation");
   45.79              if (reading)
   45.80                  throw new ReadPendingException();
   45.81              if (readShutdown) {
   45.82 @@ -234,44 +259,53 @@
   45.83          // immediately complete with -1 if shutdown for read
   45.84          // immediately complete with 0 if no space remaining
   45.85          if (shutdown || !hasSpaceToRead) {
   45.86 -            CompletedFuture<V,A> result;
   45.87 +            Number result;
   45.88              if (isScatteringRead) {
   45.89 -                Long value = (shutdown) ? Long.valueOf(-1L) : Long.valueOf(0L);
   45.90 -                result = (CompletedFuture<V,A>)CompletedFuture.withResult(this, value, attachment);
   45.91 +                result = (shutdown) ? Long.valueOf(-1L) : Long.valueOf(0L);
   45.92              } else {
   45.93 -                int value = (shutdown) ? -1 : 0;
   45.94 -                result = (CompletedFuture<V,A>)CompletedFuture.withResult(this, value, attachment);
   45.95 +                result = (shutdown) ? -1 : 0;
   45.96              }
   45.97 -            Invoker.invoke(handler, result);
   45.98 -            return result;
   45.99 +            if (handler == null)
  45.100 +                return CompletedFuture.withResult((V)result);
  45.101 +            Invoker.invoke(this, handler, att, (V)result, null);
  45.102 +            return null;
  45.103          }
  45.104  
  45.105 -        return readImpl(dsts, isScatteringRead, timeout, unit, attachment, handler);
  45.106 +        return implRead(isScatteringRead, dst, dsts, timeout, unit, att, handler);
  45.107      }
  45.108  
  45.109      @Override
  45.110 -    public final <A> Future<Integer> read(ByteBuffer dst,
  45.111 -                                          long timeout,
  45.112 -                                          TimeUnit unit,
  45.113 -                                          A attachment,
  45.114 -                                          CompletionHandler<Integer,? super A> handler)
  45.115 -    {
  45.116 +    public final Future<Integer> read(ByteBuffer dst) {
  45.117          if (dst.isReadOnly())
  45.118              throw new IllegalArgumentException("Read-only buffer");
  45.119 -        ByteBuffer[] bufs = new ByteBuffer[1];
  45.120 -        bufs[0] = dst;
  45.121 -        return read(bufs, false, timeout, unit, attachment, handler);
  45.122 +        return read(false, dst, null, 0L, TimeUnit.MILLISECONDS, null, null);
  45.123      }
  45.124  
  45.125      @Override
  45.126 -    public final <A> Future<Long> read(ByteBuffer[] dsts,
  45.127 -                                       int offset,
  45.128 -                                       int length,
  45.129 -                                       long timeout,
  45.130 -                                       TimeUnit unit,
  45.131 -                                       A attachment,
  45.132 -                                       CompletionHandler<Long,? super A> handler)
  45.133 +    public final <A> void read(ByteBuffer dst,
  45.134 +                               long timeout,
  45.135 +                               TimeUnit unit,
  45.136 +                               A attachment,
  45.137 +                               CompletionHandler<Integer,? super A> handler)
  45.138      {
  45.139 +        if (handler == null)
  45.140 +            throw new NullPointerException("'handler' is null");
  45.141 +        if (dst.isReadOnly())
  45.142 +            throw new IllegalArgumentException("Read-only buffer");
  45.143 +        read(false, dst, null, timeout, unit, attachment, handler);
  45.144 +    }
  45.145 +
  45.146 +    @Override
  45.147 +    public final <A> void read(ByteBuffer[] dsts,
  45.148 +                               int offset,
  45.149 +                               int length,
  45.150 +                               long timeout,
  45.151 +                               TimeUnit unit,
  45.152 +                               A attachment,
  45.153 +                               CompletionHandler<Long,? super A> handler)
  45.154 +    {
  45.155 +        if (handler == null)
  45.156 +            throw new NullPointerException("'handler' is null");
  45.157          if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
  45.158              throw new IndexOutOfBoundsException();
  45.159          ByteBuffer[] bufs = Util.subsequence(dsts, offset, length);
  45.160 @@ -279,39 +313,41 @@
  45.161              if (bufs[i].isReadOnly())
  45.162                  throw new IllegalArgumentException("Read-only buffer");
  45.163          }
  45.164 -        return read(bufs, true, timeout, unit, attachment, handler);
  45.165 +        read(true, null, bufs, timeout, unit, attachment, handler);
  45.166      }
  45.167  
  45.168      /**
  45.169       * Invoked by write to initiate the I/O operation.
  45.170       */
  45.171 -    abstract <V extends Number,A> Future<V> writeImpl(ByteBuffer[] srcs,
  45.172 -                                                      boolean isGatheringWrite,
  45.173 +    abstract <V extends Number,A> Future<V> implWrite(boolean isGatheringWrite,
  45.174 +                                                      ByteBuffer src,
  45.175 +                                                      ByteBuffer[] srcs,
  45.176                                                        long timeout,
  45.177                                                        TimeUnit unit,
  45.178                                                        A attachment,
  45.179                                                        CompletionHandler<V,? super A> handler);
  45.180  
  45.181      @SuppressWarnings("unchecked")
  45.182 -    private <V extends Number,A> Future<V> write(ByteBuffer[] srcs,
  45.183 -                                                 boolean isGatheringWrite,
  45.184 +    private <V extends Number,A> Future<V> write(boolean isGatheringWrite,
  45.185 +                                                 ByteBuffer src,
  45.186 +                                                 ByteBuffer[] srcs,
  45.187                                                   long timeout,
  45.188                                                   TimeUnit unit,
  45.189 -                                                 A attachment,
  45.190 +                                                 A att,
  45.191                                                   CompletionHandler<V,? super A> handler)
  45.192      {
  45.193 -        boolean hasDataToWrite = isGatheringWrite || srcs[0].hasRemaining();
  45.194 +        boolean hasDataToWrite = isGatheringWrite || src.hasRemaining();
  45.195  
  45.196          boolean closed = false;
  45.197          if (isOpen()) {
  45.198              if (remoteAddress == null)
  45.199                  throw new NotYetConnectedException();
  45.200 -            if (timeout < 0L)
  45.201 +             if (timeout < 0L)
  45.202                  throw new IllegalArgumentException("Negative timeout");
  45.203              // check and update state
  45.204              synchronized (writeLock) {
  45.205                  if (writeKilled)
  45.206 -                    throw new RuntimeException("Writing not allowed due to timeout or cancellation");
  45.207 +                    throw new IllegalStateException("Writing not allowed due to timeout or cancellation");
  45.208                  if (writing)
  45.209                      throw new WritePendingException();
  45.210                  if (writeShutdown) {
  45.211 @@ -327,52 +363,57 @@
  45.212  
  45.213          // channel is closed or shutdown for write
  45.214          if (closed) {
  45.215 -            CompletedFuture<V,A> result = CompletedFuture
  45.216 -                .withFailure(this, new ClosedChannelException(), attachment);
  45.217 -            Invoker.invoke(handler, result);
  45.218 -            return result;
  45.219 +            Throwable e = new ClosedChannelException();
  45.220 +            if (handler == null)
  45.221 +                return CompletedFuture.withFailure(e);
  45.222 +            Invoker.invoke(this, handler, att, null, e);
  45.223 +            return null;
  45.224          }
  45.225  
  45.226          // nothing to write so complete immediately
  45.227          if (!hasDataToWrite) {
  45.228 -            CompletedFuture<V,A> result;
  45.229 -            if (isGatheringWrite) {
  45.230 -                result = (CompletedFuture<V,A>)CompletedFuture.withResult(this, 0L, attachment);
  45.231 -            } else {
  45.232 -                result = (CompletedFuture<V,A>)CompletedFuture.withResult(this, 0, attachment);
  45.233 -            }
  45.234 -            Invoker.invoke(handler, result);
  45.235 -            return result;
  45.236 +            Number result = (isGatheringWrite) ? (Number)0L : (Number)0;
  45.237 +            if (handler == null)
  45.238 +                return CompletedFuture.withResult((V)result);
  45.239 +            Invoker.invoke(this, handler, att, (V)result, null);
  45.240 +            return null;
  45.241          }
  45.242  
  45.243 -        return writeImpl(srcs, isGatheringWrite, timeout, unit, attachment, handler);
  45.244 +        return implWrite(isGatheringWrite, src, srcs, timeout, unit, att, handler);
  45.245      }
  45.246  
  45.247      @Override
  45.248 -    public final <A> Future<Integer> write(ByteBuffer src,
  45.249 -                                           long timeout,
  45.250 -                                           TimeUnit unit,
  45.251 -                                           A attachment,
  45.252 -                                           CompletionHandler<Integer,? super A> handler)
  45.253 -    {
  45.254 -        ByteBuffer[] bufs = new ByteBuffer[1];
  45.255 -        bufs[0] = src;
  45.256 -        return write(bufs, false, timeout, unit, attachment, handler);
  45.257 +    public final Future<Integer> write(ByteBuffer src) {
  45.258 +        return write(false, src, null, 0L, TimeUnit.MILLISECONDS, null, null);
  45.259      }
  45.260  
  45.261      @Override
  45.262 -    public final <A> Future<Long> write(ByteBuffer[] srcs,
  45.263 -                                        int offset,
  45.264 -                                        int length,
  45.265 -                                        long timeout,
  45.266 -                                        TimeUnit unit,
  45.267 -                                        A attachment,
  45.268 -                                        CompletionHandler<Long,? super A> handler)
  45.269 +    public final <A> void write(ByteBuffer src,
  45.270 +                                long timeout,
  45.271 +                                TimeUnit unit,
  45.272 +                                A attachment,
  45.273 +                                CompletionHandler<Integer,? super A> handler)
  45.274      {
  45.275 +        if (handler == null)
  45.276 +            throw new NullPointerException("'handler' is null");
  45.277 +        write(false, src, null, timeout, unit, attachment, handler);
  45.278 +    }
  45.279 +
  45.280 +    @Override
  45.281 +    public final <A> void  write(ByteBuffer[] srcs,
  45.282 +                                 int offset,
  45.283 +                                 int length,
  45.284 +                                 long timeout,
  45.285 +                                 TimeUnit unit,
  45.286 +                                 A attachment,
  45.287 +                                 CompletionHandler<Long,? super A> handler)
  45.288 +    {
  45.289 +        if (handler == null)
  45.290 +            throw new NullPointerException("'handler' is null");
  45.291          if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
  45.292              throw new IndexOutOfBoundsException();
  45.293          srcs = Util.subsequence(srcs, offset, length);
  45.294 -        return write(srcs, true, timeout, unit, attachment, handler);
  45.295 +        write(true, null, srcs, timeout, unit, attachment, handler);
  45.296      }
  45.297  
  45.298      @Override
  45.299 @@ -461,7 +502,6 @@
  45.300      }
  45.301  
  45.302      @Override
  45.303 -    @SuppressWarnings("unchecked")
  45.304      public final SocketAddress getRemoteAddress() throws IOException {
  45.305          if (!isOpen())
  45.306              throw new ClosedChannelException();
    46.1 --- a/src/share/classes/sun/nio/ch/CompletedFuture.java	Mon Aug 24 17:26:09 2009 -0700
    46.2 +++ b/src/share/classes/sun/nio/ch/CompletedFuture.java	Tue Sep 01 13:03:09 2009 -0700
    46.3 @@ -25,7 +25,7 @@
    46.4  
    46.5  package sun.nio.ch;
    46.6  
    46.7 -import java.nio.channels.AsynchronousChannel;
    46.8 +import java.util.concurrent.Future;
    46.9  import java.util.concurrent.TimeUnit;
   46.10  import java.util.concurrent.ExecutionException;
   46.11  import java.io.IOException;
   46.12 @@ -35,39 +35,35 @@
   46.13   * completed.
   46.14   */
   46.15  
   46.16 -final class CompletedFuture<V,A>
   46.17 -    extends AbstractFuture<V,A>
   46.18 -{
   46.19 +final class CompletedFuture<V> implements Future<V> {
   46.20      private final V result;
   46.21      private final Throwable exc;
   46.22  
   46.23 -    private CompletedFuture(AsynchronousChannel channel,
   46.24 -                            V result,
   46.25 -                            Throwable exc,
   46.26 -                            A attachment)
   46.27 -    {
   46.28 -        super(channel, attachment);
   46.29 +    private CompletedFuture(V result, Throwable exc) {
   46.30          this.result = result;
   46.31          this.exc = exc;
   46.32      }
   46.33  
   46.34      @SuppressWarnings("unchecked")
   46.35 -    static <V,A> CompletedFuture<V,A> withResult(AsynchronousChannel channel,
   46.36 -                                                 V result,
   46.37 -                                                 A attachment)
   46.38 -    {
   46.39 -        return new CompletedFuture<V,A>(channel, result, null, attachment);
   46.40 +    static <V> CompletedFuture<V> withResult(V result) {
   46.41 +        return new CompletedFuture<V>(result, null);
   46.42      }
   46.43  
   46.44      @SuppressWarnings("unchecked")
   46.45 -    static <V,A> CompletedFuture<V,A> withFailure(AsynchronousChannel channel,
   46.46 -                                                  Throwable exc,
   46.47 -                                                  A attachment)
   46.48 -    {
   46.49 +    static <V> CompletedFuture<V> withFailure(Throwable exc) {
   46.50          // exception must be IOException or SecurityException
   46.51          if (!(exc instanceof IOException) && !(exc instanceof SecurityException))
   46.52              exc = new IOException(exc);
   46.53 -        return new CompletedFuture(channel, null, exc, attachment);
   46.54 +        return new CompletedFuture(null, exc);
   46.55 +    }
   46.56 +
   46.57 +    @SuppressWarnings("unchecked")
   46.58 +    static <V> CompletedFuture<V> withResult(V result, Throwable exc) {
   46.59 +        if (exc == null) {
   46.60 +            return withResult(result);
   46.61 +        } else {
   46.62 +            return withFailure(exc);
   46.63 +        }
   46.64      }
   46.65  
   46.66      @Override
   46.67 @@ -100,14 +96,4 @@
   46.68      public boolean cancel(boolean mayInterruptIfRunning) {
   46.69          return false;
   46.70      }
   46.71 -
   46.72 -    @Override
   46.73 -    Throwable exception() {
   46.74 -        return exc;
   46.75 -    }
   46.76 -
   46.77 -    @Override
   46.78 -    V value() {
   46.79 -        return result;
   46.80 -    }
   46.81  }
    47.1 --- a/src/share/classes/sun/nio/ch/Invoker.java	Mon Aug 24 17:26:09 2009 -0700
    47.2 +++ b/src/share/classes/sun/nio/ch/Invoker.java	Tue Sep 01 13:03:09 2009 -0700
    47.3 @@ -117,33 +117,32 @@
    47.4       * Invoke handler without checking the thread identity or number of handlers
    47.5       * on the thread stack.
    47.6       */
    47.7 -    @SuppressWarnings("unchecked")
    47.8      static <V,A> void invokeUnchecked(CompletionHandler<V,? super A> handler,
    47.9 -                                      AbstractFuture<V,A> result)
   47.10 +                                      A attachment,
   47.11 +                                      V value,
   47.12 +                                      Throwable exc)
   47.13      {
   47.14 -        if (handler != null && !result.isCancelled()) {
   47.15 -            Throwable exc = result.exception();
   47.16 -            if (exc == null) {
   47.17 -                handler.completed(result.value(), result.attachment());
   47.18 -            } else {
   47.19 -                handler.failed(exc, result.attachment());
   47.20 -            }
   47.21 +        if (exc == null) {
   47.22 +            handler.completed(value, attachment);
   47.23 +        } else {
   47.24 +            handler.failed(exc, attachment);
   47.25 +        }
   47.26  
   47.27 -            // clear interrupt
   47.28 -            Thread.interrupted();
   47.29 -        }
   47.30 +        // clear interrupt
   47.31 +        Thread.interrupted();
   47.32      }
   47.33  
   47.34 -
   47.35      /**
   47.36 -     * Invoke handler after incrementing the invoke count.
   47.37 +     * Invoke handler assuming thread identity already checked
   47.38       */
   47.39      static <V,A> void invokeDirect(GroupAndInvokeCount myGroupAndInvokeCount,
   47.40                                     CompletionHandler<V,? super A> handler,
   47.41 -                                   AbstractFuture<V,A> result)
   47.42 +                                   A attachment,
   47.43 +                                   V result,
   47.44 +                                   Throwable exc)
   47.45      {
   47.46          myGroupAndInvokeCount.incrementInvokeCount();
   47.47 -        invokeUnchecked(handler, result);
   47.48 +        Invoker.invokeUnchecked(handler, attachment, result, exc);
   47.49      }
   47.50  
   47.51      /**
   47.52 @@ -151,64 +150,64 @@
   47.53       * thread pool then the handler is invoked directly, otherwise it is
   47.54       * invoked indirectly.
   47.55       */
   47.56 -    static <V,A> void invoke(CompletionHandler<V,? super A> handler,
   47.57 -                             AbstractFuture<V,A> result)
   47.58 +    static <V,A> void invoke(AsynchronousChannel channel,
   47.59 +                             CompletionHandler<V,? super A> handler,
   47.60 +                             A attachment,
   47.61 +                             V result,
   47.62 +                             Throwable exc)
   47.63      {
   47.64 -        if (handler != null) {
   47.65 -            boolean invokeDirect = false;
   47.66 -            boolean identityOkay = false;
   47.67 -            GroupAndInvokeCount thisGroupAndInvokeCount = myGroupAndInvokeCount.get();
   47.68 -            if (thisGroupAndInvokeCount != null) {
   47.69 -                AsynchronousChannel channel = result.channel();
   47.70 -                if ((thisGroupAndInvokeCount.group() == ((Groupable)channel).group()))
   47.71 -                    identityOkay = true;
   47.72 -                if (identityOkay &&
   47.73 -                    (thisGroupAndInvokeCount.invokeCount() < maxHandlerInvokeCount))
   47.74 -                {
   47.75 -                    // group match
   47.76 -                    invokeDirect = true;
   47.77 -                }
   47.78 +        boolean invokeDirect = false;
   47.79 +        boolean identityOkay = false;
   47.80 +        GroupAndInvokeCount thisGroupAndInvokeCount = myGroupAndInvokeCount.get();
   47.81 +        if (thisGroupAndInvokeCount != null) {
   47.82 +            if ((thisGroupAndInvokeCount.group() == ((Groupable)channel).group()))
   47.83 +                identityOkay = true;
   47.84 +            if (identityOkay &&
   47.85 +                (thisGroupAndInvokeCount.invokeCount() < maxHandlerInvokeCount))
   47.86 +            {
   47.87 +                // group match
   47.88 +                invokeDirect = true;
   47.89              }
   47.90 -            if (invokeDirect) {
   47.91 -                thisGroupAndInvokeCount.incrementInvokeCount();
   47.92 -                invokeUnchecked(handler, result);
   47.93 -            } else {
   47.94 -                try {
   47.95 -                    invokeIndirectly(handler, result);
   47.96 -                } catch (RejectedExecutionException ree) {
   47.97 -                    // channel group shutdown; fallback to invoking directly
   47.98 -                    // if the current thread has the right identity.
   47.99 -                    if (identityOkay) {
  47.100 -                        invokeUnchecked(handler, result);
  47.101 -                    } else {
  47.102 -                        throw new ShutdownChannelGroupException();
  47.103 -                    }
  47.104 +        }
  47.105 +        if (invokeDirect) {
  47.106 +            invokeDirect(thisGroupAndInvokeCount, handler, attachment, result, exc);
  47.107 +        } else {
  47.108 +            try {
  47.109 +                invokeIndirectly(channel, handler, attachment, result, exc);
  47.110 +            } catch (RejectedExecutionException ree) {
  47.111 +                // channel group shutdown; fallback to invoking directly
  47.112 +                // if the current thread has the right identity.
  47.113 +                if (identityOkay) {
  47.114 +                    invokeDirect(thisGroupAndInvokeCount,
  47.115 +                                 handler, attachment, result, exc);
  47.116 +                } else {
  47.117 +                    throw new ShutdownChannelGroupException();
  47.118                  }
  47.119              }
  47.120          }
  47.121      }
  47.122  
  47.123      /**
  47.124 -     * Invokes the handler "indirectly" in the channel group's thread pool.
  47.125 +     * Invokes the handler indirectly via the channel group's thread pool.
  47.126       */
  47.127 -    static <V,A> void invokeIndirectly(final CompletionHandler<V,? super A> handler,
  47.128 -                                       final AbstractFuture<V,A> result)
  47.129 +    static <V,A> void invokeIndirectly(AsynchronousChannel channel,
  47.130 +                                       final CompletionHandler<V,? super A> handler,
  47.131 +                                       final A attachment,
  47.132 +                                       final V result,
  47.133 +                                       final Throwable exc)
  47.134      {
  47.135 -        if (handler != null) {
  47.136 -            AsynchronousChannel channel = result.channel();
  47.137 -            try {
  47.138 -                ((Groupable)channel).group().executeOnPooledThread(new Runnable() {
  47.139 -                    public void run() {
  47.140 -                        GroupAndInvokeCount thisGroupAndInvokeCount =
  47.141 -                            myGroupAndInvokeCount.get();
  47.142 -                        if (thisGroupAndInvokeCount != null)
  47.143 -                            thisGroupAndInvokeCount.setInvokeCount(1);
  47.144 -                        invokeUnchecked(handler, result);
  47.145 -                    }
  47.146 -                });
  47.147 -            } catch (RejectedExecutionException ree) {
  47.148 -                throw new ShutdownChannelGroupException();
  47.149 -            }
  47.150 +        try {
  47.151 +            ((Groupable)channel).group().executeOnPooledThread(new Runnable() {
  47.152 +                public void run() {
  47.153 +                    GroupAndInvokeCount thisGroupAndInvokeCount =
  47.154 +                        myGroupAndInvokeCount.get();
  47.155 +                    if (thisGroupAndInvokeCount != null)
  47.156 +                        thisGroupAndInvokeCount.setInvokeCount(1);
  47.157 +                    invokeUnchecked(handler, attachment, result, exc);
  47.158 +                }
  47.159 +            });
  47.160 +        } catch (RejectedExecutionException ree) {
  47.161 +            throw new ShutdownChannelGroupException();
  47.162          }
  47.163      }
  47.164  
  47.165 @@ -216,19 +215,19 @@
  47.166       * Invokes the handler "indirectly" in the given Executor
  47.167       */
  47.168      static <V,A> void invokeIndirectly(final CompletionHandler<V,? super A> handler,
  47.169 -                                       final AbstractFuture<V,A> result,
  47.170 +                                       final A attachment,
  47.171 +                                       final V value,
  47.172 +                                       final Throwable exc,
  47.173                                         Executor executor)
  47.174      {
  47.175 -        if (handler != null) {
  47.176 -            try {
  47.177 -                executor.execute(new Runnable() {
  47.178 -                    public void run() {
  47.179 -                        invokeUnchecked(handler, result);
  47.180 -                    }
  47.181 -                });
  47.182 -            } catch (RejectedExecutionException ree) {
  47.183 -                throw new ShutdownChannelGroupException();
  47.184 -            }
  47.185 +         try {
  47.186 +            executor.execute(new Runnable() {
  47.187 +                public void run() {
  47.188 +                    invokeUnchecked(handler, attachment, value, exc);
  47.189 +                }
  47.190 +            });
  47.191 +        } catch (RejectedExecutionException ree) {
  47.192 +            throw new ShutdownChannelGroupException();
  47.193          }
  47.194      }
  47.195  
  47.196 @@ -258,4 +257,52 @@
  47.197              throw new ShutdownChannelGroupException();
  47.198          }
  47.199      }
  47.200 +
  47.201 +    /**
  47.202 +     * Invoke handler with completed result. This method does not check the
  47.203 +     * thread identity or the number of handlers on the thread stack.
  47.204 +     */
  47.205 +    static <V,A> void invokeUnchecked(PendingFuture<V,A> future) {
  47.206 +        assert future.isDone();
  47.207 +        CompletionHandler<V,? super A> handler = future.handler();
  47.208 +        if (handler != null) {
  47.209 +            invokeUnchecked(handler,
  47.210 +                            future.attachment(),
  47.211 +                            future.value(),
  47.212 +                            future.exception());
  47.213 +        }
  47.214 +    }
  47.215 +
  47.216 +    /**
  47.217 +     * Invoke handler with completed result. If the current thread is in the
  47.218 +     * channel group's thread pool then the handler is invoked directly,
  47.219 +     * otherwise it is invoked indirectly.
  47.220 +     */
  47.221 +    static <V,A> void invoke(PendingFuture<V,A> future) {
  47.222 +        assert future.isDone();
  47.223 +        CompletionHandler<V,? super A> handler = future.handler();
  47.224 +        if (handler != null) {
  47.225 +            invoke(future.channel(),
  47.226 +                   handler,
  47.227 +                   future.attachment(),
  47.228 +                   future.value(),
  47.229 +                   future.exception());
  47.230 +        }
  47.231 +    }
  47.232 +
  47.233 +    /**
  47.234 +     * Invoke handler with completed result. The handler is invoked indirectly,
  47.235 +     * via the channel group's thread pool.
  47.236 +     */
  47.237 +    static <V,A> void invokeIndirectly(PendingFuture<V,A> future) {
  47.238 +        assert future.isDone();
  47.239 +        CompletionHandler<V,? super A> handler = future.handler();
  47.240 +        if (handler != null) {
  47.241 +            invokeIndirectly(future.channel(),
  47.242 +                             handler,
  47.243 +                             future.attachment(),
  47.244 +                             future.value(),
  47.245 +                             future.exception());
  47.246 +        }
  47.247 +    }
  47.248  }
    48.1 --- a/src/share/classes/sun/nio/ch/PendingFuture.java	Mon Aug 24 17:26:09 2009 -0700
    48.2 +++ b/src/share/classes/sun/nio/ch/PendingFuture.java	Tue Sep 01 13:03:09 2009 -0700
    48.3 @@ -34,13 +34,13 @@
    48.4   * attachment of an additional arbitrary context object and a timer task.
    48.5   */
    48.6  
    48.7 -final class PendingFuture<V,A>
    48.8 -    extends AbstractFuture<V,A>
    48.9 -{
   48.10 +final class PendingFuture<V,A> implements Future<V> {
   48.11      private static final CancellationException CANCELLED =
   48.12          new CancellationException();
   48.13  
   48.14 +    private final AsynchronousChannel channel;
   48.15      private final CompletionHandler<V,? super A> handler;
   48.16 +    private final A attachment;
   48.17  
   48.18      // true if result (or exception) is available
   48.19      private volatile boolean haveResult;
   48.20 @@ -56,14 +56,14 @@
   48.21      // optional context object
   48.22      private volatile Object context;
   48.23  
   48.24 -
   48.25      PendingFuture(AsynchronousChannel channel,
   48.26                    CompletionHandler<V,? super A> handler,
   48.27                    A attachment,
   48.28                    Object context)
   48.29      {
   48.30 -        super(channel, attachment);
   48.31 +        this.channel = channel;
   48.32          this.handler = handler;
   48.33 +        this.attachment = attachment;
   48.34          this.context = context;
   48.35      }
   48.36  
   48.37 @@ -71,14 +71,31 @@
   48.38                    CompletionHandler<V,? super A> handler,
   48.39                    A attachment)
   48.40      {
   48.41 -        super(channel, attachment);
   48.42 +        this.channel = channel;
   48.43          this.handler = handler;
   48.44 +        this.attachment = attachment;
   48.45 +    }
   48.46 +
   48.47 +    PendingFuture(AsynchronousChannel channel) {
   48.48 +        this(channel, null, null);
   48.49 +    }
   48.50 +
   48.51 +    PendingFuture(AsynchronousChannel channel, Object context) {
   48.52 +        this(channel, null, null, context);
   48.53 +    }
   48.54 +
   48.55 +    AsynchronousChannel channel() {
   48.56 +        return channel;
   48.57      }
   48.58  
   48.59      CompletionHandler<V,? super A> handler() {
   48.60          return handler;
   48.61      }
   48.62  
   48.63 +    A attachment() {
   48.64 +        return attachment;
   48.65 +    }
   48.66 +
   48.67      void setContext(Object context) {
   48.68          this.context = context;
   48.69      }
   48.70 @@ -113,36 +130,45 @@
   48.71      /**
   48.72       * Sets the result, or a no-op if the result or exception is already set.
   48.73       */
   48.74 -    boolean setResult(V res) {
   48.75 +    void setResult(V res) {
   48.76          synchronized (this) {
   48.77              if (haveResult)
   48.78 -                return false;
   48.79 +                return;
   48.80              result = res;
   48.81              haveResult = true;
   48.82              if (timeoutTask != null)
   48.83                  timeoutTask.cancel(false);
   48.84              if (latch != null)
   48.85                  latch.countDown();
   48.86 -            return true;
   48.87          }
   48.88      }
   48.89  
   48.90      /**
   48.91       * Sets the result, or a no-op if the result or exception is already set.
   48.92       */
   48.93 -    boolean setFailure(Throwable x) {
   48.94 +    void setFailure(Throwable x) {
   48.95          if (!(x instanceof IOException) && !(x instanceof SecurityException))
   48.96              x = new IOException(x);
   48.97          synchronized (this) {
   48.98              if (haveResult)
   48.99 -                return false;
  48.100 +                return;
  48.101              exc = x;
  48.102              haveResult = true;
  48.103              if (timeoutTask != null)
  48.104                  timeoutTask.cancel(false);
  48.105              if (latch != null)
  48.106                  latch.countDown();
  48.107 -            return true;
  48.108 +        }
  48.109 +    }
  48.110 +
  48.111 +    /**
  48.112 +     * Sets the result
  48.113 +     */
  48.114 +    void setResult(V res, Throwable x) {
  48.115 +        if (x == null) {
  48.116 +            setResult(res);
  48.117 +        } else {
  48.118 +            setFailure(x);
  48.119          }
  48.120      }
  48.121  
  48.122 @@ -178,12 +204,10 @@
  48.123          return result;
  48.124      }
  48.125  
  48.126 -    @Override
  48.127      Throwable exception() {
  48.128          return (exc != CANCELLED) ? exc : null;
  48.129      }
  48.130  
  48.131 -    @Override
  48.132      V value() {
  48.133          return result;
  48.134      }
  48.135 @@ -204,33 +228,6 @@
  48.136              if (haveResult)
  48.137                  return false;    // already completed
  48.138  
  48.139 -            // A shutdown of the channel group will close all channels and
  48.140 -            // shutdown the executor. To ensure that the completion handler
  48.141 -            // is executed we queue the task while holding the lock.
  48.142 -            if (handler != null) {
  48.143 -                prepareForWait();
  48.144 -                Runnable cancelTask = new Runnable() {
  48.145 -                    public void run() {
  48.146 -                        while (!haveResult) {
  48.147 -                            try {
  48.148 -                                latch.await();
  48.149 -                            } catch (InterruptedException ignore) { }
  48.150 -                        }
  48.151 -                        handler.cancelled(attachment());
  48.152 -                    }
  48.153 -                };
  48.154 -                AsynchronousChannel ch = channel();
  48.155 -                if (ch instanceof Groupable) {
  48.156 -                    ((Groupable)ch).group().executeOnPooledThread(cancelTask);
  48.157 -                } else {
  48.158 -                    if (ch instanceof AsynchronousFileChannelImpl) {
  48.159 -                        ((AsynchronousFileChannelImpl)ch).executor().execute(cancelTask);
  48.160 -                    } else {
  48.161 -                        throw new AssertionError("Should not get here");
  48.162 -                    }
  48.163 -                }
  48.164 -            }
  48.165 -
  48.166              // notify channel
  48.167              if (channel() instanceof Cancellable)
  48.168                  ((Cancellable)channel()).onCancel(this);
  48.169 @@ -249,7 +246,7 @@
  48.170              } catch (IOException ignore) { }
  48.171          }
  48.172  
  48.173 -        // release waiters (this also releases the invoker)
  48.174 +        // release waiters
  48.175          if (latch != null)
  48.176              latch.countDown();
  48.177          return true;
    49.1 --- a/src/share/classes/sun/nio/ch/SimpleAsynchronousDatagramChannelImpl.java	Mon Aug 24 17:26:09 2009 -0700
    49.2 +++ b/src/share/classes/sun/nio/ch/SimpleAsynchronousDatagramChannelImpl.java	Tue Sep 01 13:03:09 2009 -0700
    49.3 @@ -317,51 +317,71 @@
    49.4          return new WrappedMembershipKey(this, key);
    49.5      }
    49.6  
    49.7 -    @Override
    49.8 -    public <A> Future<Integer> send(ByteBuffer src,
    49.9 -                                    SocketAddress target,
   49.10 -                                    long timeout,
   49.11 -                                    TimeUnit unit,
   49.12 -                                    A attachment,
   49.13 -                                    CompletionHandler<Integer,? super A> handler)
   49.14 +    private <A> Future<Integer> implSend(ByteBuffer src,
   49.15 +                                         SocketAddress target,
   49.16 +                                         A attachment,
   49.17 +                                         CompletionHandler<Integer,? super A> handler)
   49.18      {
   49.19 -        if (timeout < 0L)
   49.20 -            throw new IllegalArgumentException("Negative timeout");
   49.21 -        if (unit == null)
   49.22 -            throw new NullPointerException();
   49.23 -
   49.24 -        CompletedFuture<Integer,A> result;
   49.25 +        int n = 0;
   49.26 +        Throwable exc = null;
   49.27          try {
   49.28 -            int n = dc.send(src, target);
   49.29 -            result = CompletedFuture.withResult(this, n, attachment);
   49.30 +            n = dc.send(src, target);
   49.31          } catch (IOException ioe) {
   49.32 -            result = CompletedFuture.withFailure(this, ioe, attachment);
   49.33 +            exc = ioe;
   49.34          }
   49.35 -        Invoker.invoke(handler, result);
   49.36 -        return result;
   49.37 +        if (handler == null)
   49.38 +            return CompletedFuture.withResult(n, exc);
   49.39 +        Invoker.invoke(this, handler, attachment, n, exc);
   49.40 +        return null;
   49.41      }
   49.42  
   49.43      @Override
   49.44 -    public <A> Future<Integer> write(ByteBuffer src,
   49.45 -                                     long timeout,
   49.46 -                                     TimeUnit unit,
   49.47 -                                     A attachment,
   49.48 -                                     CompletionHandler<Integer,? super A> handler)
   49.49 +    public Future<Integer> send(ByteBuffer src, SocketAddress target) {
   49.50 +        return implSend(src, target, null, null);
   49.51 +    }
   49.52 +
   49.53 +    @Override
   49.54 +    public <A> void send(ByteBuffer src,
   49.55 +                         SocketAddress target,
   49.56 +                         A attachment,
   49.57 +                         CompletionHandler<Integer,? super A> handler)
   49.58      {
   49.59 -        if (timeout < 0L)
   49.60 -            throw new IllegalArgumentException("Negative timeout");
   49.61 -        if (unit == null)
   49.62 -            throw new NullPointerException();
   49.63 +        if (handler == null)
   49.64 +            throw new NullPointerException("'handler' is null");
   49.65 +        implSend(src, target, attachment, handler);
   49.66 +    }
   49.67  
   49.68 -        CompletedFuture<Integer,A> result;
   49.69 +    private <A> Future<Integer> implWrite(ByteBuffer src,
   49.70 +                                          A attachment,
   49.71 +                                          CompletionHandler<Integer,? super A> handler)
   49.72 +    {
   49.73 +        int n = 0;
   49.74 +        Throwable exc = null;
   49.75          try {
   49.76 -            int n = dc.write(src);
   49.77 -            result = CompletedFuture.withResult(this, n, attachment);
   49.78 +            n = dc.write(src);
   49.79          } catch (IOException ioe) {
   49.80 -            result = CompletedFuture.withFailure(this, ioe, attachment);
   49.81 +            exc = ioe;
   49.82          }
   49.83 -        Invoker.invoke(handler, result);
   49.84 -        return result;
   49.85 +        if (handler == null)
   49.86 +            return CompletedFuture.withResult(n, exc);
   49.87 +        Invoker.invoke(this, handler, attachment, n, exc);
   49.88 +        return null;
   49.89 +
   49.90 +    }
   49.91 +
   49.92 +    @Override
   49.93 +    public Future<Integer> write(ByteBuffer src) {
   49.94 +        return implWrite(src, null, null);
   49.95 +    }
   49.96 +
   49.97 +    @Override
   49.98 +    public <A> void write(ByteBuffer src,
   49.99 +                          A attachment,
  49.100 +                          CompletionHandler<Integer,? super A> handler)
  49.101 +    {
  49.102 +        if (handler == null)
  49.103 +            throw new NullPointerException("'handler' is null");
  49.104 +        implWrite(src, attachment, handler);
  49.105      }
  49.106  
  49.107      /**
  49.108 @@ -390,12 +410,11 @@
  49.109          }
  49.110      }
  49.111  
  49.112 -    @Override
  49.113 -    public <A> Future<SocketAddress> receive(final ByteBuffer dst,
  49.114 -                                             final long timeout,
  49.115 -                                             final TimeUnit unit,
  49.116 -                                             A attachment,
  49.117 -                                             final CompletionHandler<SocketAddress,? super A> handler)
  49.118 +    private <A> Future<SocketAddress> implReceive(final ByteBuffer dst,
  49.119 +                                                  final long timeout,
  49.120 +                                                  final TimeUnit unit,
  49.121 +                                                  A attachment,
  49.122 +                                                  final CompletionHandler<SocketAddress,? super A> handler)
  49.123      {
  49.124          if (dst.isReadOnly())
  49.125              throw new IllegalArgumentException("Read-only buffer");
  49.126 @@ -406,10 +425,11 @@
  49.127  
  49.128          // complete immediately if channel closed
  49.129          if (!isOpen()) {
  49.130 -            CompletedFuture<SocketAddress,A> result = CompletedFuture.withFailure(this,
  49.131 -                new ClosedChannelException(), attachment);
  49.132 -            Invoker.invoke(handler, result);
  49.133 -            return result;
  49.134 +            Throwable exc = new ClosedChannelException();
  49.135 +            if (handler == null)
  49.136 +                return CompletedFuture.withFailure(exc);
  49.137 +            Invoker.invoke(this, handler, attachment, null, exc);
  49.138 +            return null;
  49.139          }
  49.140  
  49.141          final AccessControlContext acc = (System.getSecurityManager() == null) ?
  49.142 @@ -471,7 +491,7 @@
  49.143                          x = new AsynchronousCloseException();
  49.144                      result.setFailure(x);
  49.145                  }
  49.146 -                Invoker.invokeUnchecked(handler, result);
  49.147 +                Invoker.invokeUnchecked(result);
  49.148              }
  49.149          };
  49.150          try {
  49.151 @@ -483,11 +503,27 @@
  49.152      }
  49.153  
  49.154      @Override
  49.155 -    public <A> Future<Integer> read(final ByteBuffer dst,
  49.156 -                                    final long timeout,
  49.157 -                                    final TimeUnit unit,
  49.158 -                                    A attachment,
  49.159 -                                    final CompletionHandler<Integer,? super A> handler)
  49.160 +    public Future<SocketAddress> receive(ByteBuffer dst) {
  49.161 +        return implReceive(dst, 0L, TimeUnit.MILLISECONDS, null, null);
  49.162 +    }
  49.163 +
  49.164 +    @Override
  49.165 +    public <A> void receive(ByteBuffer dst,
  49.166 +                            long timeout,
  49.167 +                            TimeUnit unit,
  49.168 +                            A attachment,
  49.169 +                            CompletionHandler<SocketAddress,? super A> handler)
  49.170 +    {
  49.171 +        if (handler == null)
  49.172 +            throw new NullPointerException("'handler' is null");
  49.173 +        implReceive(dst, timeout, unit, attachment, handler);
  49.174 +    }
  49.175 +
  49.176 +    private <A> Future<Integer> implRead(final ByteBuffer dst,
  49.177 +                                         final long timeout,
  49.178 +                                         final TimeUnit unit,
  49.179 +                                         A attachment,
  49.180 +                                         final CompletionHandler<Integer,? super A> handler)
  49.181      {
  49.182          if (dst.isReadOnly())
  49.183              throw new IllegalArgumentException("Read-only buffer");
  49.184 @@ -495,18 +531,20 @@
  49.185              throw new IllegalArgumentException("Negative timeout");
  49.186          if (unit == null)
  49.187              throw new NullPointerException();
  49.188 +
  49.189 +        // complete immediately if channel closed
  49.190 +        if (!isOpen()) {
  49.191 +            Throwable exc = new ClosedChannelException();
  49.192 +            if (handler == null)
  49.193 +                return CompletedFuture.withFailure(exc);
  49.194 +            Invoker.invoke(this, handler, attachment, null, exc);
  49.195 +            return null;
  49.196 +        }
  49.197 +
  49.198          // another thread may disconnect before read is initiated
  49.199          if (!dc.isConnected())
  49.200              throw new NotYetConnectedException();
  49.201  
  49.202 -        // complete immediately if channel closed
  49.203 -        if (!isOpen()) {
  49.204 -            CompletedFuture<Integer,A> result = CompletedFuture.withFailure(this,
  49.205 -                new ClosedChannelException(), attachment);
  49.206 -            Invoker.invoke(handler, result);
  49.207 -            return result;
  49.208 -        }
  49.209 -
  49.210          final PendingFuture<Integer,A> result =
  49.211              new PendingFuture<Integer,A>(this, handler, attachment);
  49.212          Runnable task = new Runnable() {
  49.213 @@ -563,7 +601,7 @@
  49.214                          x = new AsynchronousCloseException();
  49.215                      result.setFailure(x);
  49.216                  }
  49.217 -                Invoker.invokeUnchecked(handler, result);
  49.218 +                Invoker.invokeUnchecked(result);
  49.219              }
  49.220          };
  49.221          try {
  49.222 @@ -575,6 +613,23 @@
  49.223      }
  49.224  
  49.225      @Override
  49.226 +    public Future<Integer> read(ByteBuffer dst) {
  49.227 +        return implRead(dst, 0L, TimeUnit.MILLISECONDS, null, null);
  49.228 +    }
  49.229 +
  49.230 +    @Override
  49.231 +    public <A> void read(ByteBuffer dst,
  49.232 +                            long timeout,
  49.233 +                            TimeUnit unit,
  49.234 +                            A attachment,
  49.235 +                            CompletionHandler<Integer,? super A> handler)
  49.236 +    {
  49.237 +        if (handler == null)
  49.238 +            throw new NullPointerException("'handler' is null");
  49.239 +        implRead(dst, timeout, unit, attachment, handler);
  49.240 +    }
  49.241 +
  49.242 +    @Override
  49.243      public  AsynchronousDatagramChannel bind(SocketAddress local)
  49.244          throws IOException
  49.245      {
    50.1 --- a/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java	Mon Aug 24 17:26:09 2009 -0700
    50.2 +++ b/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java	Tue Sep 01 13:03:09 2009 -0700
    50.3 @@ -50,9 +50,6 @@
    50.4      // Used to make native read and write calls
    50.5      private static final FileDispatcher nd = new FileDispatcherImpl();
    50.6  
    50.7 -    // indicates if the associated thread pool is the default thread pool
    50.8 -    private final boolean isDefaultExecutor;
    50.9 -
   50.10      // Thread-safe set of IDs of native threads, for signalling
   50.11      private final NativeThreadSet threads = new NativeThreadSet(2);
   50.12  
   50.13 @@ -60,11 +57,9 @@
   50.14      SimpleAsynchronousFileChannelImpl(FileDescriptor fdObj,
   50.15                                        boolean reading,
   50.16                                        boolean writing,
   50.17 -                                      ExecutorService executor,
   50.18 -                                      boolean isDefaultexecutor)
   50.19 +                                      ExecutorService executor)
   50.20      {
   50.21          super(fdObj, reading, writing, executor);
   50.22 -        this.isDefaultExecutor = isDefaultexecutor;
   50.23      }
   50.24  
   50.25      public static AsynchronousFileChannel open(FileDescriptor fdo,
   50.26 @@ -73,17 +68,9 @@
   50.27                                                 ThreadPool pool)
   50.28      {
   50.29          // Executor is either default or based on pool parameters
   50.30 -        ExecutorService executor;
   50.31 -        boolean isDefaultexecutor;
   50.32 -        if (pool == null) {
   50.33 -            executor = DefaultExecutorHolder.defaultExecutor;
   50.34 -            isDefaultexecutor = true;
   50.35 -        } else {
   50.36 -            executor = pool.executor();
   50.37 -            isDefaultexecutor = false;
   50.38 -        }
   50.39 -        return new SimpleAsynchronousFileChannelImpl(fdo,
   50.40 -            reading, writing, executor, isDefaultexecutor);
   50.41 +        ExecutorService executor = (pool == null) ?
   50.42 +            DefaultExecutorHolder.defaultExecutor : pool.executor();
   50.43 +        return new SimpleAsynchronousFileChannelImpl(fdo, reading, writing, executor);
   50.44      }
   50.45  
   50.46      @Override
   50.47 @@ -114,16 +101,6 @@
   50.48  
   50.49          // close file
   50.50          nd.close(fdObj);
   50.51 -
   50.52 -        // shutdown executor if specific to this channel
   50.53 -        if (!isDefaultExecutor) {
   50.54 -            AccessController.doPrivileged(new PrivilegedAction<Void>() {
   50.55 -                public Void run() {
   50.56 -                    executor.shutdown();
   50.57 -                    return null;
   50.58 -                }
   50.59 -            });
   50.60 -        }
   50.61      }
   50.62  
   50.63      @Override
   50.64 @@ -194,11 +171,11 @@
   50.65      }
   50.66  
   50.67      @Override
   50.68 -    public <A> Future<FileLock> lock(final long position,
   50.69 -                                     final long size,
   50.70 -                                     final boolean shared,
   50.71 -                                     A attachment,
   50.72 -                                     final CompletionHandler<FileLock,? super A> handler)
   50.73 +    <A> Future<FileLock> implLock(final long position,
   50.74 +                                  final long size,
   50.75 +                                  final boolean shared,
   50.76 +                                  final A attachment,
   50.77 +                                  final CompletionHandler<FileLock,? super A> handler)
   50.78      {
   50.79          if (shared && !reading)
   50.80              throw new NonReadableChannelException();
   50.81 @@ -208,16 +185,19 @@
   50.82          // add to lock table
   50.83          final FileLockImpl fli = addToFileLockTable(position, size, shared);
   50.84          if (fli == null) {
   50.85 -            CompletedFuture<FileLock,A> result = CompletedFuture
   50.86 -                .withFailure(this, new ClosedChannelException(), attachment);
   50.87 -            Invoker.invokeIndirectly(handler, result, executor);
   50.88 -            return result;
   50.89 +            Throwable exc = new ClosedChannelException();
   50.90 +            if (handler == null)
   50.91 +                return CompletedFuture.withFailure(exc);
   50.92 +            Invoker.invokeIndirectly(handler, attachment, null, exc, executor);
   50.93 +            return null;
   50.94          }
   50.95  
   50.96 -        final PendingFuture<FileLock,A> result =
   50.97 -            new PendingFuture<FileLock,A>(this, handler, attachment);
   50.98 +        final PendingFuture<FileLock,A> result = (handler == null) ?
   50.99 +            new PendingFuture<FileLock,A>(this) : null;
  50.100          Runnable task = new Runnable() {
  50.101              public void run() {
  50.102 +                Throwable exc = null;
  50.103 +
  50.104                  int ti = threads.add();
  50.105                  try {
  50.106                      int n;
  50.107 @@ -226,31 +206,36 @@
  50.108                          do {
  50.109                              n = nd.lock(fdObj, true, position, size, shared);
  50.110                          } while ((n == FileDispatcher.INTERRUPTED) && isOpen());
  50.111 -                        if (n == FileDispatcher.LOCKED && isOpen()) {
  50.112 -                            result.setResult(fli);
  50.113 -                        } else {
  50.114 +                        if (n != FileDispatcher.LOCKED || !isOpen()) {
  50.115                              throw new AsynchronousCloseException();
  50.116                          }
  50.117                      } catch (IOException x) {
  50.118                          removeFromFileLockTable(fli);
  50.119                          if (!isOpen())
  50.120                              x = new AsynchronousCloseException();
  50.121 -                        result.setFailure(x);
  50.122 +                        exc = x;
  50.123                      } finally {
  50.124                          end();
  50.125                      }
  50.126                  } finally {
  50.127                      threads.remove(ti);
  50.128                  }
  50.129 -                Invoker.invokeUnchecked(handler, result);
  50.130 +                if (handler == null) {
  50.131 +                    result.setResult(fli, exc);
  50.132 +                } else {
  50.133 +                    Invoker.invokeUnchecked(handler, attachment, fli, exc);
  50.134 +                }
  50.135              }
  50.136          };
  50.137 +        boolean executed = false;
  50.138          try {
  50.139              executor.execute(task);
  50.140 -        } catch (RejectedExecutionException ree) {
  50.141 -            // rollback
  50.142 -            removeFromFileLockTable(fli);
  50.143 -            throw new ShutdownChannelGroupException();
  50.144 +            executed = true;
  50.145 +        } finally {
  50.146 +            if (!executed) {
  50.147 +                // rollback
  50.148 +                removeFromFileLockTable(fli);
  50.149 +            }
  50.150          }
  50.151          return result;
  50.152      }
  50.153 @@ -301,10 +286,10 @@
  50.154      }
  50.155  
  50.156      @Override
  50.157 -    public <A> Future<Integer> read(final ByteBuffer dst,
  50.158 -                                    final long position,
  50.159 -                                    A attachment,
  50.160 -                                    final CompletionHandler<Integer,? super A> handler)
  50.161 +    <A> Future<Integer> implRead(final ByteBuffer dst,
  50.162 +                                 final long position,
  50.163 +                                 final A attachment,
  50.164 +                                 final CompletionHandler<Integer,? super A> handler)
  50.165      {
  50.166          if (position < 0)
  50.167              throw new IllegalArgumentException("Negative position");
  50.168 @@ -315,55 +300,52 @@
  50.169  
  50.170          // complete immediately if channel closed or no space remaining
  50.171          if (!isOpen() || (dst.remaining() == 0)) {
  50.172 -            CompletedFuture<Integer,A> result;
  50.173 -            if (isOpen()) {
  50.174 -                result = CompletedFuture.withResult(this, 0, attachment);
  50.175 -            } else {
  50.176 -                result = CompletedFuture.withFailure(this,
  50.177 -                    new ClosedChannelException(), attachment);
  50.178 -            }
  50.179 -            Invoker.invokeIndirectly(handler, result, executor);
  50.180 -            return result;
  50.181 +            Throwable exc = (isOpen()) ? null : new ClosedChannelException();
  50.182 +            if (handler == null)
  50.183 +                return CompletedFuture.withResult(0, exc);
  50.184 +            Invoker.invokeIndirectly(handler, attachment, 0, exc, executor);
  50.185 +            return null;
  50.186          }
  50.187  
  50.188 -        final PendingFuture<Integer,A> result =
  50.189 -            new PendingFuture<Integer,A>(this, handler, attachment);
  50.190 +        final PendingFuture<Integer,A> result = (handler == null) ?
  50.191 +            new PendingFuture<Integer,A>(this) : null;
  50.192          Runnable task = new Runnable() {
  50.193              public void run() {
  50.194 +                int n = 0;
  50.195 +                Throwable exc = null;
  50.196 +
  50.197                  int ti = threads.add();
  50.198                  try {
  50.199                      begin();
  50.200 -                    int n;
  50.201                      do {
  50.202                          n = IOUtil.read(fdObj, dst, position, nd, null);
  50.203                      } while ((n == IOStatus.INTERRUPTED) && isOpen());
  50.204                      if (n < 0 && !isOpen())
  50.205                          throw new AsynchronousCloseException();
  50.206 -                    result.setResult(n);
  50.207                  } catch (IOException x) {
  50.208                      if (!isOpen())
  50.209                          x = new AsynchronousCloseException();
  50.210 -                    result.setFailure(x);
  50.211 +                    exc = x;
  50.212                  } finally {
  50.213                      end();
  50.214                      threads.remove(ti);
  50.215                  }
  50.216 -                Invoker.invokeUnchecked(handler, result);
  50.217 +                if (handler == null) {
  50.218 +                    result.setResult(n, exc);
  50.219 +                } else {
  50.220 +                    Invoker.invokeUnchecked(handler, attachment, n, exc);
  50.221 +                }
  50.222              }
  50.223          };
  50.224 -        try {
  50.225 -            executor.execute(task);
  50.226 -        } catch (RejectedExecutionException ree) {
  50.227 -            throw new ShutdownChannelGroupException();
  50.228 -        }
  50.229 +        executor.execute(task);
  50.230          return result;
  50.231      }
  50.232  
  50.233      @Override
  50.234 -    public <A> Future<Integer> write(final ByteBuffer src,
  50.235 -                                     final long position,
  50.236 -                                     A attachment,
  50.237 -                                     final CompletionHandler<Integer,? super A> handler)
  50.238 +    <A> Future<Integer> implWrite(final ByteBuffer src,
  50.239 +                                  final long position,
  50.240 +                                  final A attachment,
  50.241 +                                  final CompletionHandler<Integer,? super A> handler)
  50.242      {
  50.243          if (position < 0)
  50.244              throw new IllegalArgumentException("Negative position");
  50.245 @@ -372,47 +354,44 @@
  50.246  
  50.247          // complete immediately if channel is closed or no bytes remaining
  50.248          if (!isOpen() || (src.remaining() == 0)) {
  50.249 -            CompletedFuture<Integer,A> result;
  50.250 -            if (isOpen()) {
  50.251 -                result = CompletedFuture.withResult(this, 0, attachment);
  50.252 -            } else {
  50.253 -                result = CompletedFuture.withFailure(this,
  50.254 -                    new ClosedChannelException(), attachment);
  50.255 -            }
  50.256 -            Invoker.invokeIndirectly(handler, result, executor);
  50.257 -            return result;
  50.258 +            Throwable exc = (isOpen()) ? null : new ClosedChannelException();
  50.259 +            if (handler == null)
  50.260 +                return CompletedFuture.withResult(0, exc);
  50.261 +            Invoker.invokeIndirectly(handler, attachment, 0, exc, executor);
  50.262 +            return null;
  50.263          }
  50.264  
  50.265 -        final PendingFuture<Integer,A> result =
  50.266 -            new PendingFuture<Integer,A>(this, handler, attachment);
  50.267 +        final PendingFuture<Integer,A> result = (handler == null) ?
  50.268 +            new PendingFuture<Integer,A>(this) : null;
  50.269          Runnable task = new Runnable() {
  50.270              public void run() {
  50.271 +                int n = 0;
  50.272 +                Throwable exc = null;
  50.273 +
  50.274                  int ti = threads.add();
  50.275                  try {
  50.276                      begin();
  50.277 -                    int n;
  50.278                      do {
  50.279                          n = IOUtil.write(fdObj, src, position, nd, null);
  50.280                      } while ((n == IOStatus.INTERRUPTED) && isOpen());
  50.281                      if (n < 0 && !isOpen())
  50.282                          throw new AsynchronousCloseException();
  50.283 -                    result.setResult(n);
  50.284                  } catch (IOException x) {
  50.285                      if (!isOpen())
  50.286                          x = new AsynchronousCloseException();
  50.287 -                    result.setFailure(x);
  50.288 +                    exc = x;
  50.289                  } finally {
  50.290                      end();
  50.291                      threads.remove(ti);
  50.292                  }
  50.293 -                Invoker.invokeUnchecked(handler, result);
  50.294 +                if (handler == null) {
  50.295 +                    result.setResult(n, exc);
  50.296 +                } else {
  50.297 +                    Invoker.invokeUnchecked(handler, attachment, n, exc);
  50.298 +                }
  50.299              }
  50.300          };
  50.301 -        try {
  50.302 -            executor.execute(task);
  50.303 -        } catch (RejectedExecutionException ree) {
  50.304 -            throw new ShutdownChannelGroupException();
  50.305 -        }
  50.306 +        executor.execute(task);
  50.307          return result;
  50.308      }
  50.309  }
    51.1 --- a/src/share/classes/sun/nio/cs/ext/ISO2022.java	Mon Aug 24 17:26:09 2009 -0700
    51.2 +++ b/src/share/classes/sun/nio/cs/ext/ISO2022.java	Tue Sep 01 13:03:09 2009 -0700
    51.3 @@ -388,9 +388,9 @@
    51.4  
    51.5      protected static class Encoder extends CharsetEncoder {
    51.6          private final Surrogate.Parser sgp = new Surrogate.Parser();
    51.7 -        private final byte SS2 = (byte)0x8e;
    51.8 -        private final byte PLANE2 = (byte)0xA2;
    51.9 -        private final byte PLANE3 = (byte)0xA3;
   51.10 +        public static final byte SS2 = (byte)0x8e;
   51.11 +        public static final byte PLANE2 = (byte)0xA2;
   51.12 +        public static final byte PLANE3 = (byte)0xA3;
   51.13          private final byte MSB = (byte)0x80;
   51.14  
   51.15          protected final byte maximumDesignatorLength = 4;
    52.1 --- a/src/share/classes/sun/nio/cs/ext/ISO2022_CN_CNS.java	Mon Aug 24 17:26:09 2009 -0700
    52.2 +++ b/src/share/classes/sun/nio/cs/ext/ISO2022_CN_CNS.java	Tue Sep 01 13:03:09 2009 -0700
    52.3 @@ -76,6 +76,15 @@
    52.4              } catch (Exception e) { }
    52.5          }
    52.6  
    52.7 +        private byte[] bb = new byte[4];
    52.8 +        public boolean canEncode(char c) {
    52.9 +            int n = 0;
   52.10 +            return (c <= '\u007f' ||
   52.11 +                    (n = ((EUC_TW.Encoder)ISOEncoder).toEUC(c, bb)) == 2 ||
   52.12 +                    (n == 4 && bb[0] == SS2 &&
   52.13 +                     (bb[1] == PLANE2 || bb[1] == PLANE3)));
   52.14 +        }
   52.15 +
   52.16          /*
   52.17           * Since ISO2022-CN-CNS possesses a CharsetEncoder
   52.18           * without the corresponding CharsetDecoder half the
    53.1 --- a/src/share/classes/sun/security/jgss/SunProvider.java	Mon Aug 24 17:26:09 2009 -0700
    53.2 +++ b/src/share/classes/sun/security/jgss/SunProvider.java	Tue Sep 01 13:03:09 2009 -0700
    53.3 @@ -62,7 +62,7 @@
    53.4  
    53.5      public SunProvider() {
    53.6          /* We are the Sun JGSS provider */
    53.7 -        super("SunJGSS", 1.0, INFO);
    53.8 +        super("SunJGSS", 1.7d, INFO);
    53.9  
   53.10          AccessController.doPrivileged(
   53.11                          new java.security.PrivilegedAction<Void>() {
    54.1 --- a/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java	Mon Aug 24 17:26:09 2009 -0700
    54.2 +++ b/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java	Tue Sep 01 13:03:09 2009 -0700
    54.3 @@ -41,6 +41,7 @@
    54.4  import java.io.FileInputStream;
    54.5  import java.io.FileOutputStream;
    54.6  import java.io.File;
    54.7 +import java.util.Comparator;
    54.8  import java.util.StringTokenizer;
    54.9  
   54.10  /**
   54.11 @@ -229,10 +230,11 @@
   54.12      /**
   54.13       * Reads the service key from the keytab file.
   54.14       * @param service the PrincipalName of the requested service.
   54.15 -     * @return the last service key in the keytab
   54.16 +     * @return the last service key in the keytab with the highest kvno
   54.17       */
   54.18      public EncryptionKey readServiceKey(PrincipalName service) {
   54.19          KeyTabEntry entry = null;
   54.20 +        EncryptionKey key = null;
   54.21          if (entries != null) {
   54.22              // Find latest entry for this service that has an etype
   54.23              // that has been configured for use
   54.24 @@ -240,9 +242,12 @@
   54.25                  entry = entries.elementAt(i);
   54.26                  if (entry.service.match(service)) {
   54.27                      if (EType.isSupported(entry.keyType)) {
   54.28 -                        return new EncryptionKey(entry.keyblock,
   54.29 +                        if (key == null ||
   54.30 +                                entry.keyVersion > key.getKeyVersionNumber()) {
   54.31 +                            key = new EncryptionKey(entry.keyblock,
   54.32                                               entry.keyType,
   54.33                                               new Integer(entry.keyVersion));
   54.34 +                        }
   54.35                      } else if (DEBUG) {
   54.36                          System.out.println("Found unsupported keytype (" +
   54.37                              entry.keyType + ") for " + service);
   54.38 @@ -250,12 +255,13 @@
   54.39                  }
   54.40              }
   54.41          }
   54.42 -        return null;
   54.43 +        return key;
   54.44      }
   54.45  
   54.46      /**
   54.47       * Reads all keys for a service from the keytab file that have
   54.48 -     * etypes that have been configured for use.
   54.49 +     * etypes that have been configured for use. If there are multiple
   54.50 +     * keys with same etype, the one with the highest kvno is returned.
   54.51       * @param service the PrincipalName of the requested service
   54.52       * @return an array containing all the service keys
   54.53       */
   54.54 @@ -288,49 +294,39 @@
   54.55          size = keys.size();
   54.56          if (size == 0)
   54.57              return null;
   54.58 -        EncryptionKey[] retVal = new EncryptionKey[size];
   54.59 +        EncryptionKey[] retVal = keys.toArray(new EncryptionKey[size]);
   54.60  
   54.61          // Sort keys according to default_tkt_enctypes
   54.62 -        int pos = 0;
   54.63 -        EncryptionKey k;
   54.64          if (DEBUG) {
   54.65              System.out.println("Ordering keys wrt default_tkt_enctypes list");
   54.66          }
   54.67 -        int[] etypes = EType.getDefaults("default_tkt_enctypes");
   54.68 -        if (etypes == null || etypes == EType.getBuiltInDefaults()) {
   54.69 -            // Either no supported types specified in default_tkt_enctypes
   54.70 -            // or no default_tkt_enctypes entry at all. For both cases,
   54.71 -            // just return supported keys in the order retrieved
   54.72 -            for (int i = 0; i < size; i++) {
   54.73 -                retVal[pos++] = keys.get(i);
   54.74 -            }
   54.75 -        } else {
   54.76 -            for (int j = 0; j < etypes.length && pos < size; j++) {
   54.77 -                int target = etypes[j];
   54.78 -                for (int i = 0; i < size && pos < size; i++) {
   54.79 -                    k = keys.get(i);
   54.80 -                    if (k != null && k.getEType() == target) {
   54.81 -                        if (DEBUG) {
   54.82 -                            System.out.println(pos + ": " + k);
   54.83 +
   54.84 +        final int[] etypes = EType.getDefaults("default_tkt_enctypes");
   54.85 +
   54.86 +        // Sort the keys, k1 is preferred than k2 if:
   54.87 +        // 1. k1's etype appears earlier in etypes than k2's
   54.88 +        // 2. If same, k1's KVNO is higher
   54.89 +        Arrays.sort(retVal, new Comparator<EncryptionKey>() {
   54.90 +            @Override
   54.91 +            public int compare(EncryptionKey o1, EncryptionKey o2) {
   54.92 +                if (etypes != null && etypes != EType.getBuiltInDefaults()) {
   54.93 +                    int o1EType = o1.getEType();
   54.94 +                    int o2EType = o2.getEType();
   54.95 +                    if (o1EType != o2EType) {
   54.96 +                        for (int i=0; i<etypes.length; i++) {
   54.97 +                            if (etypes[i] == o1EType) {
   54.98 +                                return -1;
   54.99 +                            } else if (etypes[i] == o2EType) {
  54.100 +                                return 1;
  54.101 +                            }
  54.102                          }
  54.103 -                        retVal[pos++] = k;
  54.104 -                        keys.set(i, null);  // Cleared from consideration
  54.105                      }
  54.106                  }
  54.107 +                return o2.getKeyVersionNumber().intValue()
  54.108 +                        - o1.getKeyVersionNumber().intValue();
  54.109              }
  54.110 -            // copy the rest
  54.111 -            for (int i = 0; i < size && pos < size; i++) {
  54.112 -                k = keys.get(i);
  54.113 -                if (k != null) {
  54.114 -                    retVal[pos++] = k;
  54.115 -                }
  54.116 -            }
  54.117 -        }
  54.118 -        if (pos != size) {
  54.119 -            throw new RuntimeException(
  54.120 -                "Internal Error: did not copy all keys;expecting " + size +
  54.121 -                    "; got " + pos);
  54.122 -        }
  54.123 +        });
  54.124 +
  54.125          return retVal;
  54.126      }
  54.127  
    55.1 --- a/src/share/classes/sun/security/provider/Sun.java	Mon Aug 24 17:26:09 2009 -0700
    55.2 +++ b/src/share/classes/sun/security/provider/Sun.java	Tue Sep 01 13:03:09 2009 -0700
    55.3 @@ -46,7 +46,7 @@
    55.4  
    55.5      public Sun() {
    55.6          /* We are the SUN provider */
    55.7 -        super("SUN", 1.6, INFO);
    55.8 +        super("SUN", 1.7, INFO);
    55.9  
   55.10          // if there is no security manager installed, put directly into
   55.11          // the provider. Otherwise, create a temporary map and use a
    56.1 --- a/src/share/classes/sun/security/smartcardio/SunPCSC.java	Mon Aug 24 17:26:09 2009 -0700
    56.2 +++ b/src/share/classes/sun/security/smartcardio/SunPCSC.java	Tue Sep 01 13:03:09 2009 -0700
    56.3 @@ -40,7 +40,7 @@
    56.4      private static final long serialVersionUID = 6168388284028876579L;
    56.5  
    56.6      public SunPCSC() {
    56.7 -        super("SunPCSC", 1.6d, "Sun PC/SC provider");
    56.8 +        super("SunPCSC", 1.7d, "Sun PC/SC provider");
    56.9          AccessController.doPrivileged(new PrivilegedAction<Void>() {
   56.10              public Void run() {
   56.11                  put("TerminalFactory.PC/SC", "sun.security.smartcardio.SunPCSC$Factory");
    57.1 --- a/src/share/classes/sun/security/ssl/SunJSSE.java	Mon Aug 24 17:26:09 2009 -0700
    57.2 +++ b/src/share/classes/sun/security/ssl/SunJSSE.java	Tue Sep 01 13:03:09 2009 -0700
    57.3 @@ -103,7 +103,7 @@
    57.4  
    57.5      // standard constructor
    57.6      protected SunJSSE() {
    57.7 -        super("SunJSSE", 1.6d, info);
    57.8 +        super("SunJSSE", 1.7d, info);
    57.9          subclassCheck();
   57.10          if (Boolean.TRUE.equals(fips)) {
   57.11              throw new ProviderException
    58.1 --- a/src/share/classes/sun/security/util/Password.java	Mon Aug 24 17:26:09 2009 -0700
    58.2 +++ b/src/share/classes/sun/security/util/Password.java	Tue Sep 01 13:03:09 2009 -0700
    58.3 @@ -1,5 +1,5 @@
    58.4  /*
    58.5 - * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
    58.6 + * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
    58.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    58.8   *
    58.9   * This code is free software; you can redistribute it and/or modify it
   58.10 @@ -37,6 +37,14 @@
   58.11  public class Password {
   58.12      /** Reads user password from given input stream. */
   58.13      public static char[] readPassword(InputStream in) throws IOException {
   58.14 +        return readPassword(in, false);
   58.15 +    }
   58.16 +
   58.17 +    /** Reads user password from given input stream.
   58.18 +     * @param isEchoOn true if the password should be echoed on the screen
   58.19 +     */
   58.20 +    public static char[] readPassword(InputStream in, boolean isEchoOn)
   58.21 +            throws IOException {
   58.22  
   58.23          char[] consoleEntered = null;
   58.24          byte[] consoleBytes = null;
   58.25 @@ -44,7 +52,7 @@
   58.26          try {
   58.27              // Use the new java.io.Console class
   58.28              Console con = null;
   58.29 -            if (in == System.in && ((con = System.console()) != null)) {
   58.30 +            if (!isEchoOn && in == System.in && ((con = System.console()) != null)) {
   58.31                  consoleEntered = con.readPassword();
   58.32                  // readPassword returns "" if you just print ENTER,
   58.33                  // to be compatible with old Password class, change to null
    59.1 --- a/src/share/native/sun/security/ec/ec.c	Mon Aug 24 17:26:09 2009 -0700
    59.2 +++ b/src/share/native/sun/security/ec/ec.c	Tue Sep 01 13:03:09 2009 -0700
    59.3 @@ -422,7 +422,7 @@
    59.4       */
    59.5      if ((privKeyBytes = PORT_Alloc(2*len, kmflag)) == NULL) goto cleanup;
    59.6      if (randomlen != 2 * len) {
    59.7 -        goto cleanup;
    59.8 +        randomlen = 2 * len;
    59.9      }
   59.10      /* No need to generate - random bytes are now supplied */
   59.11      /* CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(privKeyBytes, 2*len) );*/
    60.1 --- a/src/solaris/classes/sun/nio/ch/EPollPort.java	Mon Aug 24 17:26:09 2009 -0700
    60.2 +++ b/src/solaris/classes/sun/nio/ch/EPollPort.java	Tue Sep 01 13:03:09 2009 -0700
    60.3 @@ -248,12 +248,13 @@
    60.4          public void run() {
    60.5              Invoker.GroupAndInvokeCount myGroupAndInvokeCount =
    60.6                  Invoker.getGroupAndInvokeCount();
    60.7 +            final boolean isPooledThread = (myGroupAndInvokeCount != null);
    60.8              boolean replaceMe = false;
    60.9              Event ev;
   60.10              try {
   60.11                  for (;;) {
   60.12                      // reset invoke count
   60.13 -                    if (myGroupAndInvokeCount != null)
   60.14 +                    if (isPooledThread)
   60.15                          myGroupAndInvokeCount.resetInvokeCount();
   60.16  
   60.17                      try {
   60.18 @@ -289,7 +290,7 @@
   60.19  
   60.20                      // process event
   60.21                      try {
   60.22 -                        ev.channel().onEvent(ev.events());
   60.23 +                        ev.channel().onEvent(ev.events(), isPooledThread);
   60.24                      } catch (Error x) {
   60.25                          replaceMe = true; throw x;
   60.26                      } catch (RuntimeException x) {
    61.1 --- a/src/solaris/classes/sun/nio/ch/Port.java	Mon Aug 24 17:26:09 2009 -0700
    61.2 +++ b/src/solaris/classes/sun/nio/ch/Port.java	Tue Sep 01 13:03:09 2009 -0700
    61.3 @@ -49,7 +49,7 @@
    61.4       * Implemented by clients registered with this port.
    61.5       */
    61.6      interface PollableChannel extends Closeable {
    61.7 -        void onEvent(int events);
    61.8 +        void onEvent(int events, boolean mayInvokeDirect);
    61.9      }
   61.10  
   61.11      // maps fd to "pollable" channel
   61.12 @@ -121,7 +121,7 @@
   61.13      final Object attachForeignChannel(final Channel channel, FileDescriptor fd) {
   61.14          int fdVal = IOUtil.fdVal(fd);
   61.15          register(fdVal, new PollableChannel() {
   61.16 -            public void onEvent(int events) { }
   61.17 +            public void onEvent(int events, boolean mayInvokeDirect) { }
   61.18              public void close() throws IOException {
   61.19                  channel.close();
   61.20              }
    62.1 --- a/src/solaris/classes/sun/nio/ch/SolarisEventPort.java	Mon Aug 24 17:26:09 2009 -0700
    62.2 +++ b/src/solaris/classes/sun/nio/ch/SolarisEventPort.java	Tue Sep 01 13:03:09 2009 -0700
    62.3 @@ -151,12 +151,13 @@
    62.4          public void run() {
    62.5              Invoker.GroupAndInvokeCount myGroupAndInvokeCount =
    62.6                  Invoker.getGroupAndInvokeCount();
    62.7 +            final boolean isPooledThread = (myGroupAndInvokeCount != null);
    62.8              boolean replaceMe = false;
    62.9              long address = unsafe.allocateMemory(SIZEOF_PORT_EVENT);
   62.10              try {
   62.11                  for (;;) {
   62.12                      // reset invoke count
   62.13 -                    if (myGroupAndInvokeCount != null)
   62.14 +                    if (isPooledThread)
   62.15                          myGroupAndInvokeCount.resetInvokeCount();
   62.16  
   62.17                      // wait for I/O completion event
   62.18 @@ -205,7 +206,7 @@
   62.19                      if (ch != null) {
   62.20                          replaceMe = true;
   62.21                          // no need to translate events
   62.22 -                        ch.onEvent(events);
   62.23 +                        ch.onEvent(events, isPooledThread);
   62.24                      }
   62.25                  }
   62.26              } finally {
    63.1 --- a/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java	Mon Aug 24 17:26:09 2009 -0700
    63.2 +++ b/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java	Tue Sep 01 13:03:09 2009 -0700
    63.3 @@ -59,10 +59,13 @@
    63.4      private final Object updateLock = new Object();
    63.5  
    63.6      // pending accept
    63.7 -    private PendingFuture<AsynchronousSocketChannel,Object> pendingAccept;
    63.8 +    private boolean acceptPending;
    63.9 +    private CompletionHandler<AsynchronousSocketChannel,Object> acceptHandler;
   63.10 +    private Object acceptAttachment;
   63.11 +    private PendingFuture<AsynchronousSocketChannel,Object> acceptFuture;
   63.12  
   63.13      // context for permission check when security manager set
   63.14 -    private AccessControlContext acc;
   63.15 +    private AccessControlContext acceptAcc;
   63.16  
   63.17  
   63.18      UnixAsynchronousServerSocketChannelImpl(Port port)
   63.19 @@ -83,15 +86,6 @@
   63.20          port.register(fdVal, this);
   63.21      }
   63.22  
   63.23 -    // returns and clears the result of a pending accept
   63.24 -    private PendingFuture<AsynchronousSocketChannel,Object> grabPendingAccept() {
   63.25 -        synchronized (updateLock) {
   63.26 -            PendingFuture<AsynchronousSocketChannel,Object> result = pendingAccept;
   63.27 -            pendingAccept = null;
   63.28 -            return result;
   63.29 -        }
   63.30 -    }
   63.31 -
   63.32      @Override
   63.33      void implClose() throws IOException {
   63.34          // remove the mapping
   63.35 @@ -101,17 +95,27 @@
   63.36          nd.close(fd);
   63.37  
   63.38          // if there is a pending accept then complete it
   63.39 -        final PendingFuture<AsynchronousSocketChannel,Object> result =
   63.40 -            grabPendingAccept();
   63.41 -        if (result != null) {
   63.42 -            // discard the stack trace as otherwise it may appear that implClose
   63.43 -            // has thrown the exception.
   63.44 -            AsynchronousCloseException x = new AsynchronousCloseException();
   63.45 -            x.setStackTrace(new StackTraceElement[0]);
   63.46 -            result.setFailure(x);
   63.47 +        CompletionHandler<AsynchronousSocketChannel,Object> handler;
   63.48 +        Object att;
   63.49 +        PendingFuture<AsynchronousSocketChannel,Object> future;
   63.50 +        synchronized (updateLock) {
   63.51 +            if (!acceptPending)
   63.52 +                return;  // no pending accept
   63.53 +            acceptPending = false;
   63.54 +            handler = acceptHandler;
   63.55 +            att = acceptAttachment;
   63.56 +            future = acceptFuture;
   63.57 +        }
   63.58  
   63.59 +        // discard the stack trace as otherwise it may appear that implClose
   63.60 +        // has thrown the exception.
   63.61 +        AsynchronousCloseException x = new AsynchronousCloseException();
   63.62 +        x.setStackTrace(new StackTraceElement[0]);
   63.63 +        if (handler == null) {
   63.64 +            future.setFailure(x);
   63.65 +        } else {
   63.66              // invoke by submitting task rather than directly
   63.67 -            Invoker.invokeIndirectly(result.handler(), result);
   63.68 +            Invoker.invokeIndirectly(this, handler, att, null, x);
   63.69          }
   63.70      }
   63.71  
   63.72 @@ -124,15 +128,17 @@
   63.73       * Invoked by event handling thread when listener socket is polled
   63.74       */
   63.75      @Override
   63.76 -    public void onEvent(int events) {
   63.77 -        PendingFuture<AsynchronousSocketChannel,Object> result = grabPendingAccept();
   63.78 -        if (result == null)
   63.79 -            return; // may have been grabbed by asynchronous close
   63.80 +    public void onEvent(int events, boolean mayInvokeDirect) {
   63.81 +        synchronized (updateLock) {
   63.82 +            if (!acceptPending)
   63.83 +                return;  // may have been grabbed by asynchronous close
   63.84 +            acceptPending = false;
   63.85 +        }
   63.86  
   63.87          // attempt to accept connection
   63.88          FileDescriptor newfd = new FileDescriptor();
   63.89          InetSocketAddress[] isaa = new InetSocketAddress[1];
   63.90 -        boolean accepted = false;
   63.91 +        Throwable exc = null;
   63.92          try {
   63.93              begin();
   63.94              int n = accept0(this.fd, newfd, isaa);
   63.95 @@ -140,49 +146,52 @@
   63.96              // spurious wakeup, is this possible?
   63.97              if (n == IOStatus.UNAVAILABLE) {
   63.98                  synchronized (updateLock) {
   63.99 -                    this.pendingAccept = result;
  63.100 +                    acceptPending = true;
  63.101                  }
  63.102                  port.startPoll(fdVal, Port.POLLIN);
  63.103                  return;
  63.104              }
  63.105  
  63.106 -            // connection accepted
  63.107 -            accepted = true;
  63.108 -
  63.109          } catch (Throwable x) {
  63.110              if (x instanceof ClosedChannelException)
  63.111                  x = new AsynchronousCloseException();
  63.112 -            enableAccept();
  63.113 -            result.setFailure(x);
  63.114 +            exc = x;
  63.115          } finally {
  63.116              end();
  63.117          }
  63.118  
  63.119          // Connection accepted so finish it when not holding locks.
  63.120          AsynchronousSocketChannel child = null;
  63.121 -        if (accepted) {
  63.122 +        if (exc == null) {
  63.123              try {
  63.124 -                child = finishAccept(newfd, isaa[0], acc);
  63.125 -                enableAccept();
  63.126 -                result.setResult(child);
  63.127 +                child = finishAccept(newfd, isaa[0], acceptAcc);
  63.128              } catch (Throwable x) {
  63.129 -                enableAccept();
  63.130                  if (!(x instanceof IOException) && !(x instanceof SecurityException))
  63.131                      x = new IOException(x);
  63.132 -                result.setFailure(x);
  63.133 +                exc = x;
  63.134              }
  63.135          }
  63.136  
  63.137 -        // if an async cancel has already cancelled the operation then
  63.138 -        // close the new channel so as to free resources
  63.139 -        if (child != null && result.isCancelled()) {
  63.140 -            try {
  63.141 -                child.close();
  63.142 -            } catch (IOException ignore) { }
  63.143 +        // copy field befores accept is re-renabled
  63.144 +        CompletionHandler<AsynchronousSocketChannel,Object> handler = acceptHandler;
  63.145 +        Object att = acceptAttachment;
  63.146 +        PendingFuture<AsynchronousSocketChannel,Object> future = acceptFuture;
  63.147 +
  63.148 +        // re-enable accepting and invoke handler
  63.149 +        enableAccept();
  63.150 +
  63.151 +        if (handler == null) {
  63.152 +            future.setResult(child, exc);
  63.153 +            // if an async cancel has already cancelled the operation then
  63.154 +            // close the new channel so as to free resources
  63.155 +            if (child != null && future.isCancelled()) {
  63.156 +                try {
  63.157 +                    child.close();
  63.158 +                } catch (IOException ignore) { }
  63.159 +            }
  63.160 +        } else {
  63.161 +            Invoker.invoke(this, handler, att, child, exc);
  63.162          }
  63.163 -
  63.164 -        // invoke the handler
  63.165 -        Invoker.invoke(result.handler(), result);
  63.166      }
  63.167  
  63.168      /**
  63.169 @@ -234,16 +243,18 @@
  63.170      }
  63.171  
  63.172      @Override
  63.173 -    @SuppressWarnings("unchecked")
  63.174 -    public <A> Future<AsynchronousSocketChannel> accept(A attachment,
  63.175 -        final CompletionHandler<AsynchronousSocketChannel,? super A> handler)
  63.176 +    Future<AsynchronousSocketChannel> implAccept(Object att,
  63.177 +        CompletionHandler<AsynchronousSocketChannel,Object> handler)
  63.178      {
  63.179          // complete immediately if channel is closed
  63.180          if (!isOpen()) {
  63.181 -            CompletedFuture<AsynchronousSocketChannel,A> result = CompletedFuture
  63.182 -                .withFailure(this, new ClosedChannelException(), attachment);
  63.183 -            Invoker.invokeIndirectly(handler, result);
  63.184 -            return result;
  63.185 +            Throwable e = new ClosedChannelException();
  63.186 +            if (handler == null) {
  63.187 +                return CompletedFuture.withFailure(e);
  63.188 +            } else {
  63.189 +                Invoker.invoke(this, handler, att, null, e);
  63.190 +                return null;
  63.191 +            }
  63.192          }
  63.193          if (localAddress == null)
  63.194              throw new NotYetBoundException();
  63.195 @@ -258,25 +269,31 @@
  63.196              throw new AcceptPendingException();
  63.197  
  63.198          // attempt accept
  63.199 -        AbstractFuture<AsynchronousSocketChannel,A> result = null;
  63.200          FileDescriptor newfd = new FileDescriptor();
  63.201          InetSocketAddress[] isaa = new InetSocketAddress[1];
  63.202 +        Throwable exc = null;
  63.203          try {
  63.204              begin();
  63.205  
  63.206              int n = accept0(this.fd, newfd, isaa);
  63.207              if (n == IOStatus.UNAVAILABLE) {
  63.208 -                // no connection to accept
  63.209 -                result = new PendingFuture<AsynchronousSocketChannel,A>(this, handler, attachment);
  63.210  
  63.211                  // need calling context when there is security manager as
  63.212                  // permission check may be done in a different thread without
  63.213                  // any application call frames on the stack
  63.214 -                synchronized (this) {
  63.215 -                    this.acc = (System.getSecurityManager() == null) ?
  63.216 +                PendingFuture<AsynchronousSocketChannel,Object> result = null;
  63.217 +                synchronized (updateLock) {
  63.218 +                    if (handler == null) {
  63.219 +                        this.acceptHandler = null;
  63.220 +                        result = new PendingFuture<AsynchronousSocketChannel,Object>(this);
  63.221 +                        this.acceptFuture = result;
  63.222 +                    } else {
  63.223 +                        this.acceptHandler = handler;
  63.224 +                        this.acceptAttachment = att;
  63.225 +                    }
  63.226 +                    this.acceptAcc = (System.getSecurityManager() == null) ?
  63.227                          null : AccessController.getContext();
  63.228 -                    this.pendingAccept =
  63.229 -                        (PendingFuture<AsynchronousSocketChannel,Object>)result;
  63.230 +                    this.acceptPending = true;
  63.231                  }
  63.232  
  63.233                  // register for connections
  63.234 @@ -287,25 +304,30 @@
  63.235              // accept failed
  63.236              if (x instanceof ClosedChannelException)
  63.237                  x = new AsynchronousCloseException();
  63.238 -            result = CompletedFuture.withFailure(this, x, attachment);
  63.239 +            exc = x;
  63.240          } finally {
  63.241              end();
  63.242          }
  63.243  
  63.244 -        // connection accepted immediately
  63.245 -        if (result == null) {
  63.246 +        AsynchronousSocketChannel child = null;
  63.247 +        if (exc == null) {
  63.248 +            // connection accepted immediately
  63.249              try {
  63.250 -                AsynchronousSocketChannel ch = finishAccept(newfd, isaa[0], null);
  63.251 -                result = CompletedFuture.withResult(this, ch, attachment);
  63.252 +                child = finishAccept(newfd, isaa[0], null);
  63.253              } catch (Throwable x) {
  63.254 -                result = CompletedFuture.withFailure(this, x, attachment);
  63.255 +                exc = x;
  63.256              }
  63.257          }
  63.258  
  63.259 -        // re-enable accepting and invoke handler
  63.260 +        // re-enable accepting before invoking handler
  63.261          enableAccept();
  63.262 -        Invoker.invokeIndirectly(handler, result);
  63.263 -        return result;
  63.264 +
  63.265 +        if (handler == null) {
  63.266 +            return CompletedFuture.withResult(child, exc);
  63.267 +        } else {
  63.268 +            Invoker.invokeIndirectly(this, handler, att, child, exc);
  63.269 +            return null;
  63.270 +        }
  63.271      }
  63.272  
  63.273      // -- Native methods --
    64.1 --- a/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java	Mon Aug 24 17:26:09 2009 -0700
    64.2 +++ b/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java	Tue Sep 01 13:03:09 2009 -0700
    64.3 @@ -61,20 +61,33 @@
    64.4      private final Object updateLock = new Object();
    64.5  
    64.6      // pending connect (updateLock)
    64.7 -    private PendingFuture<Void,Object> pendingConnect;
    64.8 +    private boolean connectPending;
    64.9 +    private CompletionHandler<Void,Object> connectHandler;
   64.10 +    private Object connectAttachment;
   64.11 +    private PendingFuture<Void,Object> connectFuture;
   64.12  
   64.13 -    // pending remote address (statLock)
   64.14 +    // pending remote address (stateLock)
   64.15      private SocketAddress pendingRemote;
   64.16  
   64.17      // pending read (updateLock)
   64.18 +    private boolean readPending;
   64.19 +    private boolean isScatteringRead;
   64.20 +    private ByteBuffer readBuffer;
   64.21      private ByteBuffer[] readBuffers;
   64.22 -    private boolean scatteringRead;
   64.23 -    private PendingFuture<Number,Object> pendingRead;
   64.24 +    private CompletionHandler<Number,Object> readHandler;
   64.25 +    private Object readAttachment;
   64.26 +    private PendingFuture<Number,Object> readFuture;
   64.27 +    private Future<?> readTimer;
   64.28  
   64.29      // pending write (updateLock)
   64.30 +    private boolean writePending;
   64.31 +    private boolean isGatheringWrite;
   64.32 +    private ByteBuffer writeBuffer;
   64.33      private ByteBuffer[] writeBuffers;
   64.34 -    private boolean gatheringWrite;
   64.35 -    private PendingFuture<Number,Object> pendingWrite;
   64.36 +    private CompletionHandler<Number,Object> writeHandler;
   64.37 +    private Object writeAttachment;
   64.38 +    private PendingFuture<Number,Object> writeFuture;
   64.39 +    private Future<?> writeTimer;
   64.40  
   64.41  
   64.42      UnixAsynchronousSocketChannelImpl(Port port)
   64.43 @@ -128,43 +141,36 @@
   64.44      private void updateEvents() {
   64.45          assert Thread.holdsLock(updateLock);
   64.46          int events = 0;
   64.47 -        if (pendingRead != null)
   64.48 +        if (readPending)
   64.49              events |= Port.POLLIN;
   64.50 -        if (pendingConnect != null || pendingWrite != null)
   64.51 +        if (connectPending || writePending)
   64.52              events |= Port.POLLOUT;
   64.53          if (events != 0)
   64.54              port.startPoll(fdVal, events);
   64.55      }
   64.56  
   64.57 -    /**
   64.58 -     * Invoked by event handler thread when file descriptor is polled
   64.59 -     */
   64.60 -    @Override
   64.61 -    public void onEvent(int events) {
   64.62 -        boolean readable = (events & Port.POLLIN) > 0;
   64.63 -        boolean writable = (events & Port.POLLOUT) > 0;
   64.64 -        if ((events & (Port.POLLERR | Port.POLLHUP)) > 0) {
   64.65 -            readable = true;
   64.66 -            writable = true;
   64.67 -        }
   64.68 -
   64.69 -        PendingFuture<Void,Object> connectResult = null;
   64.70 -        PendingFuture<Number,Object> readResult = null;
   64.71 -        PendingFuture<Number,Object> writeResult = null;
   64.72 +    // invoke to finish read and/or write operations
   64.73 +    private void finish(boolean mayInvokeDirect,
   64.74 +                        boolean readable,
   64.75 +                        boolean writable)
   64.76 +    {
   64.77 +        boolean finishRead = false;
   64.78 +        boolean finishWrite = false;
   64.79 +        boolean finishConnect = false;
   64.80  
   64.81          // map event to pending result
   64.82          synchronized (updateLock) {
   64.83 -            if (readable && (pendingRead != null)) {
   64.84 -                readResult = pendingRead;
   64.85 -                pendingRead = null;
   64.86 +            if (readable && this.readPending) {
   64.87 +                this.readPending = false;
   64.88 +                finishRead = true;
   64.89              }
   64.90              if (writable) {
   64.91 -                if (pendingWrite != null) {
   64.92 -                    writeResult = pendingWrite;
   64.93 -                    pendingWrite = null;
   64.94 -                } else if (pendingConnect != null) {
   64.95 -                    connectResult = pendingConnect;
   64.96 -                    pendingConnect = null;
   64.97 +                if (this.writePending) {
   64.98 +                    this.writePending = false;
   64.99 +                    finishWrite = true;
  64.100 +                } else if (this.connectPending) {
  64.101 +                    this.connectPending = false;
  64.102 +                    finishConnect = true;
  64.103                  }
  64.104              }
  64.105          }
  64.106 @@ -172,36 +178,32 @@
  64.107          // complete the I/O operation. Special case for when channel is
  64.108          // ready for both reading and writing. In that case, submit task to
  64.109          // complete write if write operation has a completion handler.
  64.110 -        if (readResult != null) {
  64.111 -            if (writeResult != null)
  64.112 -                finishWrite(writeResult, false);
  64.113 -            finishRead(readResult, true);
  64.114 +        if (finishRead) {
  64.115 +            if (finishWrite)
  64.116 +                finishWrite(false);
  64.117 +            finishRead(mayInvokeDirect);
  64.118              return;
  64.119          }
  64.120 -        if (writeResult != null) {
  64.121 -            finishWrite(writeResult, true);
  64.122 +        if (finishWrite) {
  64.123 +            finishWrite(mayInvokeDirect);
  64.124          }
  64.125 -        if (connectResult != null) {
  64.126 -            finishConnect(connectResult, true);
  64.127 +        if (finishConnect) {
  64.128 +            finishConnect(mayInvokeDirect);
  64.129          }
  64.130      }
  64.131  
  64.132 -    // returns and clears the result of a pending read
  64.133 -    PendingFuture<Number,Object> grabPendingRead() {
  64.134 -        synchronized (updateLock) {
  64.135 -            PendingFuture<Number,Object> result = pendingRead;
  64.136 -            pendingRead = null;
  64.137 -            return result;
  64.138 +    /**
  64.139 +     * Invoked by event handler thread when file descriptor is polled
  64.140 +     */
  64.141 +    @Override
  64.142 +    public void onEvent(int events, boolean mayInvokeDirect) {
  64.143 +        boolean readable = (events & Port.POLLIN) > 0;
  64.144 +        boolean writable = (events & Port.POLLOUT) > 0;
  64.145 +        if ((events & (Port.POLLERR | Port.POLLHUP)) > 0) {
  64.146 +            readable = true;
  64.147 +            writable = true;
  64.148          }
  64.149 -    }
  64.150 -
  64.151 -    // returns and clears the result of a pending write
  64.152 -    PendingFuture<Number,Object> grabPendingWrite() {
  64.153 -        synchronized (updateLock) {
  64.154 -            PendingFuture<Number,Object> result = pendingWrite;
  64.155 -            pendingWrite = null;
  64.156 -            return result;
  64.157 -        }
  64.158 +        finish(mayInvokeDirect, readable, writable);
  64.159      }
  64.160  
  64.161      @Override
  64.162 @@ -213,26 +215,7 @@
  64.163          nd.close(fd);
  64.164  
  64.165          // All outstanding I/O operations are required to fail
  64.166 -        final PendingFuture<Void,Object> readyToConnect;
  64.167 -        final PendingFuture<Number,Object> readyToRead;
  64.168 -        final PendingFuture<Number,Object> readyToWrite;
  64.169 -        synchronized (updateLock) {
  64.170 -            readyToConnect = pendingConnect;
  64.171 -            pendingConnect = null;
  64.172 -            readyToRead = pendingRead;
  64.173 -            pendingRead = null;
  64.174 -            readyToWrite = pendingWrite;
  64.175 -            pendingWrite = null;
  64.176 -        }
  64.177 -        if (readyToConnect != null) {
  64.178 -            finishConnect(readyToConnect, false);
  64.179 -        }
  64.180 -        if (readyToRead != null) {
  64.181 -            finishRead(readyToRead, false);
  64.182 -        }
  64.183 -        if (readyToWrite != null) {
  64.184 -            finishWrite(readyToWrite, false);
  64.185 -        }
  64.186 +        finish(false, true, true);
  64.187      }
  64.188  
  64.189      @Override
  64.190 @@ -240,9 +223,9 @@
  64.191          if (task.getContext() == OpType.CONNECT)
  64.192              killConnect();
  64.193          if (task.getContext() == OpType.READ)
  64.194 -            killConnect();
  64.195 +            killReading();
  64.196          if (task.getContext() == OpType.WRITE)
  64.197 -            killConnect();
  64.198 +            killWriting();
  64.199      }
  64.200  
  64.201      // -- connect --
  64.202 @@ -255,15 +238,12 @@
  64.203          }
  64.204      }
  64.205  
  64.206 -    private void finishConnect(PendingFuture<Void,Object> result,
  64.207 -                               boolean invokeDirect)
  64.208 -    {
  64.209 +    private void finishConnect(boolean mayInvokeDirect) {
  64.210          Throwable e = null;
  64.211          try {
  64.212              begin();
  64.213              checkConnect(fdVal);
  64.214              setConnected();
  64.215 -            result.setResult(null);
  64.216          } catch (Throwable x) {
  64.217              if (x instanceof ClosedChannelException)
  64.218                  x = new AsynchronousCloseException();
  64.219 @@ -276,26 +256,38 @@
  64.220              try {
  64.221                  close();
  64.222              } catch (IOException ignore) { }
  64.223 -            result.setFailure(e);
  64.224          }
  64.225 -        if (invokeDirect) {
  64.226 -            Invoker.invoke(result.handler(), result);
  64.227 +
  64.228 +
  64.229 +        // invoke handler and set result
  64.230 +        CompletionHandler<Void,Object> handler = connectHandler;
  64.231 +        Object att = connectAttachment;
  64.232 +        PendingFuture<Void,Object> future = connectFuture;
  64.233 +        if (handler == null) {
  64.234 +            future.setResult(null, e);
  64.235          } else {
  64.236 -            Invoker.invokeIndirectly(result.handler(), result);
  64.237 +            if (mayInvokeDirect) {
  64.238 +                Invoker.invokeUnchecked(handler, att, null, e);
  64.239 +            } else {
  64.240 +                Invoker.invokeIndirectly(this, handler, att, null, e);
  64.241 +            }
  64.242          }
  64.243      }
  64.244  
  64.245      @Override
  64.246      @SuppressWarnings("unchecked")
  64.247 -    public <A> Future<Void> connect(SocketAddress remote,
  64.248 -                                    A attachment,
  64.249 -                                    CompletionHandler<Void,? super A> handler)
  64.250 +    <A> Future<Void> implConnect(SocketAddress remote,
  64.251 +                                 A attachment,
  64.252 +                                 CompletionHandler<Void,? super A> handler)
  64.253      {
  64.254          if (!isOpen()) {
  64.255 -            CompletedFuture<Void,A> result = CompletedFuture
  64.256 -                .withFailure(this, new ClosedChannelException(), attachment);
  64.257 -            Invoker.invoke(handler, result);
  64.258 -            return result;
  64.259 +            Throwable e = new ClosedChannelException();
  64.260 +            if (handler == null) {
  64.261 +                return CompletedFuture.withFailure(e);
  64.262 +            } else {
  64.263 +                Invoker.invoke(this, handler, attachment, null, e);
  64.264 +                return null;
  64.265 +            }
  64.266          }
  64.267  
  64.268          InetSocketAddress isa = Net.checkAddress(remote);
  64.269 @@ -317,7 +309,6 @@
  64.270              notifyBeforeTcpConnect = (localAddress == null);
  64.271          }
  64.272  
  64.273 -        AbstractFuture<Void,A> result = null;
  64.274          Throwable e = null;
  64.275          try {
  64.276              begin();
  64.277 @@ -327,15 +318,21 @@
  64.278              int n = Net.connect(fd, isa.getAddress(), isa.getPort());
  64.279              if (n == IOStatus.UNAVAILABLE) {
  64.280                  // connection could not be established immediately
  64.281 -                result = new PendingFuture<Void,A>(this, handler, attachment, OpType.CONNECT);
  64.282 +                PendingFuture<Void,A> result = null;
  64.283                  synchronized (updateLock) {
  64.284 -                    this.pendingConnect = (PendingFuture<Void,Object>)result;
  64.285 +                    if (handler == null) {
  64.286 +                        result = new PendingFuture<Void,A>(this, OpType.CONNECT);
  64.287 +                        this.connectFuture = (PendingFuture<Void,Object>)result;
  64.288 +                    } else {
  64.289 +                        this.connectHandler = (CompletionHandler<Void,Object>)handler;
  64.290 +                        this.connectAttachment = attachment;
  64.291 +                    }
  64.292 +                    this.connectPending = true;
  64.293                      updateEvents();
  64.294                  }
  64.295                  return result;
  64.296              }
  64.297              setConnected();
  64.298 -            result = CompletedFuture.withResult(this, null, attachment);
  64.299          } catch (Throwable x) {
  64.300              if (x instanceof ClosedChannelException)
  64.301                  x = new AsynchronousCloseException();
  64.302 @@ -349,84 +346,111 @@
  64.303              try {
  64.304                  close();
  64.305              } catch (IOException ignore) { }
  64.306 -            result = CompletedFuture.withFailure(this, e, attachment);
  64.307          }
  64.308 -
  64.309 -        Invoker.invoke(handler, result);
  64.310 -        return result;
  64.311 +        if (handler == null) {
  64.312 +            return CompletedFuture.withResult(null, e);
  64.313 +        } else {
  64.314 +            Invoker.invoke(this, handler, attachment, null, e);
  64.315 +            return null;
  64.316 +        }
  64.317      }
  64.318  
  64.319      // -- read --
  64.320  
  64.321 -    @SuppressWarnings("unchecked")
  64.322 -    private void finishRead(PendingFuture<Number,Object> result,
  64.323 -                            boolean invokeDirect)
  64.324 -    {
  64.325 +    private void finishRead(boolean mayInvokeDirect) {
  64.326          int n = -1;
  64.327 -        PendingFuture<Number,Object> pending = null;
  64.328 +        Throwable exc = null;
  64.329 +
  64.330 +        // copy fields as we can't access them after reading is re-enabled.
  64.331 +        boolean scattering = isScatteringRead;
  64.332 +        CompletionHandler<Number,Object> handler = readHandler;
  64.333 +        Object att = readAttachment;
  64.334 +        PendingFuture<Number,Object> future = readFuture;
  64.335 +        Future<?> timeout = readTimer;
  64.336 +
  64.337          try {
  64.338              begin();
  64.339  
  64.340 -            ByteBuffer[] dsts = readBuffers;
  64.341 -            if (dsts.length == 1) {
  64.342 -                n = IOUtil.read(fd, dsts[0], -1, nd, null);
  64.343 +            if (scattering) {
  64.344 +                n = (int)IOUtil.read(fd, readBuffers, nd);
  64.345              } else {
  64.346 -                n = (int)IOUtil.read(fd, dsts, nd);
  64.347 +                n = IOUtil.read(fd, readBuffer, -1, nd, null);
  64.348              }
  64.349              if (n == IOStatus.UNAVAILABLE) {
  64.350                  // spurious wakeup, is this possible?
  64.351 -                pending = result;
  64.352 +                synchronized (updateLock) {
  64.353 +                    readPending = true;
  64.354 +                }
  64.355                  return;
  64.356              }
  64.357  
  64.358 -            // allow buffer(s) to be GC'ed.
  64.359 -            readBuffers = null;
  64.360 +            // allow objects to be GC'ed.
  64.361 +            this.readBuffer = null;
  64.362 +            this.readBuffers = null;
  64.363 +            this.readAttachment = null;
  64.364  
  64.365              // allow another read to be initiated
  64.366 -            boolean wasScatteringRead = scatteringRead;
  64.367              enableReading();
  64.368  
  64.369 -            // result is Integer or Long
  64.370 -            if (wasScatteringRead) {
  64.371 -                result.setResult(Long.valueOf(n));
  64.372 -            } else {
  64.373 -                result.setResult(Integer.valueOf(n));
  64.374 -            }
  64.375 -
  64.376          } catch (Throwable x) {
  64.377              enableReading();
  64.378              if (x instanceof ClosedChannelException)
  64.379                  x = new AsynchronousCloseException();
  64.380 -            result.setFailure(x);
  64.381 +            exc = x;
  64.382          } finally {
  64.383              // restart poll in case of concurrent write
  64.384              synchronized (updateLock) {
  64.385 -                if (pending != null)
  64.386 -                    this.pendingRead = pending;
  64.387                  updateEvents();
  64.388              }
  64.389              end();
  64.390          }
  64.391  
  64.392 -        if (invokeDirect) {
  64.393 -            Invoker.invoke(result.handler(), result);
  64.394 +        // cancel the associated timer
  64.395 +        if (timeout != null)
  64.396 +            timeout.cancel(false);
  64.397 +
  64.398 +        // create result
  64.399 +        Number result = (exc != null) ? null : (scattering) ?
  64.400 +            (Number)Long.valueOf(n) : (Number)Integer.valueOf(n);
  64.401 +
  64.402 +        // invoke handler or set result
  64.403 +        if (handler == null) {
  64.404 +            future.setResult(result, exc);
  64.405          } else {
  64.406 -            Invoker.invokeIndirectly(result.handler(), result);
  64.407 +            if (mayInvokeDirect) {
  64.408 +                Invoker.invokeUnchecked(handler, att, result, exc);
  64.409 +            } else {
  64.410 +                Invoker.invokeIndirectly(this, handler, att, result, exc);
  64.411 +            }
  64.412          }
  64.413      }
  64.414  
  64.415      private Runnable readTimeoutTask = new Runnable() {
  64.416          public void run() {
  64.417 -            PendingFuture<Number,Object> result = grabPendingRead();
  64.418 -            if (result == null)
  64.419 -                return;     // already completed
  64.420 +            CompletionHandler<Number,Object> handler = null;
  64.421 +            Object att = null;
  64.422 +            PendingFuture<Number,Object> future = null;
  64.423 +
  64.424 +            synchronized (updateLock) {
  64.425 +                if (!readPending)
  64.426 +                    return;
  64.427 +                readPending = false;
  64.428 +                handler = readHandler;
  64.429 +                att = readAttachment;
  64.430 +                future = readFuture;
  64.431 +            }
  64.432  
  64.433              // kill further reading before releasing waiters
  64.434              enableReading(true);
  64.435  
  64.436 -            // set completed and invoke handler
  64.437 -            result.setFailure(new InterruptedByTimeoutException());
  64.438 -            Invoker.invokeIndirectly(result.handler(), result);
  64.439 +            // invoke handler or set result
  64.440 +            Exception exc = new InterruptedByTimeoutException();
  64.441 +            if (handler == null) {
  64.442 +                future.setFailure(exc);
  64.443 +            } else {
  64.444 +                AsynchronousChannel ch = UnixAsynchronousSocketChannelImpl.this;
  64.445 +                Invoker.invokeIndirectly(ch, handler, att, null, exc);
  64.446 +            }
  64.447          }
  64.448      };
  64.449  
  64.450 @@ -435,8 +459,9 @@
  64.451       */
  64.452      @Override
  64.453      @SuppressWarnings("unchecked")
  64.454 -    <V extends Number,A> Future<V> readImpl(ByteBuffer[] dsts,
  64.455 -                                            boolean isScatteringRead,
  64.456 +    <V extends Number,A> Future<V> implRead(boolean isScatteringRead,
  64.457 +                                            ByteBuffer dst,
  64.458 +                                            ByteBuffer[] dsts,
  64.459                                              long timeout,
  64.460                                              TimeUnit unit,
  64.461                                              A attachment,
  64.462 @@ -450,144 +475,178 @@
  64.463          boolean invokeDirect = false;
  64.464          boolean attemptRead = false;
  64.465          if (!disableSynchronousRead) {
  64.466 -            myGroupAndInvokeCount = Invoker.getGroupAndInvokeCount();
  64.467 -            invokeDirect = Invoker.mayInvokeDirect(myGroupAndInvokeCount, port);
  64.468 -            attemptRead = (handler == null) || invokeDirect ||
  64.469 -                !port.isFixedThreadPool();  // okay to attempt read with user thread pool
  64.470 +            if (handler == null) {
  64.471 +                attemptRead = true;
  64.472 +            } else {
  64.473 +                myGroupAndInvokeCount = Invoker.getGroupAndInvokeCount();
  64.474 +                invokeDirect = Invoker.mayInvokeDirect(myGroupAndInvokeCount, port);
  64.475 +                // okay to attempt read with user thread pool
  64.476 +                attemptRead = invokeDirect || !port.isFixedThreadPool();
  64.477 +            }
  64.478          }
  64.479  
  64.480 -        AbstractFuture<V,A> result;
  64.481 +        int n = IOStatus.UNAVAILABLE;
  64.482 +        Throwable exc = null;
  64.483 +        boolean pending = false;
  64.484 +
  64.485          try {
  64.486              begin();
  64.487  
  64.488 -            int n;
  64.489              if (attemptRead) {
  64.490                  if (isScatteringRead) {
  64.491                      n = (int)IOUtil.read(fd, dsts, nd);
  64.492                  } else {
  64.493 -                    n = IOUtil.read(fd, dsts[0], -1, nd, null);
  64.494 +                    n = IOUtil.read(fd, dst, -1, nd, null);
  64.495                  }
  64.496 -            } else {
  64.497 -                n = IOStatus.UNAVAILABLE;
  64.498              }
  64.499  
  64.500              if (n == IOStatus.UNAVAILABLE) {
  64.501 -                result = new PendingFuture<V,A>(this, handler, attachment, OpType.READ);
  64.502 -
  64.503 -                // update evetns so that read will complete asynchronously
  64.504 +                PendingFuture<V,A> result = null;
  64.505                  synchronized (updateLock) {
  64.506 +                    this.isScatteringRead = isScatteringRead;
  64.507 +                    this.readBuffer = dst;
  64.508                      this.readBuffers = dsts;
  64.509 -                    this.scatteringRead = isScatteringRead;
  64.510 -                    this.pendingRead = (PendingFuture<Number,Object>)result;
  64.511 +                    if (handler == null) {
  64.512 +                        this.readHandler = null;
  64.513 +                        result = new PendingFuture<V,A>(this, OpType.READ);
  64.514 +                        this.readFuture = (PendingFuture<Number,Object>)result;
  64.515 +                        this.readAttachment = null;
  64.516 +                    } else {
  64.517 +                        this.readHandler = (CompletionHandler<Number,Object>)handler;
  64.518 +                        this.readAttachment = attachment;
  64.519 +                        this.readFuture = null;
  64.520 +                    }
  64.521 +                    if (timeout > 0L) {
  64.522 +                        this.readTimer = port.schedule(readTimeoutTask, timeout, unit);
  64.523 +                    }
  64.524 +                    this.readPending = true;
  64.525                      updateEvents();
  64.526                  }
  64.527 -
  64.528 -                // schedule timeout
  64.529 -                if (timeout > 0L) {
  64.530 -                    Future<?> timeoutTask =
  64.531 -                        port.schedule(readTimeoutTask, timeout, unit);
  64.532 -                    ((PendingFuture<V,A>)result).setTimeoutTask(timeoutTask);
  64.533 -                }
  64.534 +                pending = true;
  64.535                  return result;
  64.536              }
  64.537 -
  64.538 -            // data available
  64.539 -            enableReading();
  64.540 -
  64.541 -            // result type is Long or Integer
  64.542 -            if (isScatteringRead) {
  64.543 -                result = (CompletedFuture<V,A>)CompletedFuture
  64.544 -                    .withResult(this, Long.valueOf(n), attachment);
  64.545 -            } else {
  64.546 -                result = (CompletedFuture<V,A>)CompletedFuture
  64.547 -                    .withResult(this, Integer.valueOf(n), attachment);
  64.548 -            }
  64.549          } catch (Throwable x) {
  64.550 -            enableReading();
  64.551              if (x instanceof ClosedChannelException)
  64.552                  x = new AsynchronousCloseException();
  64.553 -            result = CompletedFuture.withFailure(this, x, attachment);
  64.554 +            exc = x;
  64.555          } finally {
  64.556 +            if (!pending)
  64.557 +                enableReading();
  64.558              end();
  64.559          }
  64.560  
  64.561 -        if (invokeDirect) {
  64.562 -            Invoker.invokeDirect(myGroupAndInvokeCount, handler, result);
  64.563 +        Number result = (exc != null) ? null : (isScatteringRead) ?
  64.564 +            (Number)Long.valueOf(n) : (Number)Integer.valueOf(n);
  64.565 +
  64.566 +        // read completed immediately
  64.567 +        if (handler != null) {
  64.568 +            if (invokeDirect) {
  64.569 +                Invoker.invokeDirect(myGroupAndInvokeCount, handler, attachment, (V)result, exc);
  64.570 +            } else {
  64.571 +                Invoker.invokeIndirectly(this, handler, attachment, (V)result, exc);
  64.572 +            }
  64.573 +            return null;
  64.574          } else {
  64.575 -            Invoker.invokeIndirectly(handler, result);
  64.576 +            return CompletedFuture.withResult((V)result, exc);
  64.577          }
  64.578 -        return result;
  64.579      }
  64.580  
  64.581      // -- write --
  64.582  
  64.583 -    private void finishWrite(PendingFuture<Number,Object> result,
  64.584 -                             boolean invokeDirect)
  64.585 -    {
  64.586 -        PendingFuture<Number,Object> pending = null;
  64.587 +    private void finishWrite(boolean mayInvokeDirect) {
  64.588 +        int n = -1;
  64.589 +        Throwable exc = null;
  64.590 +
  64.591 +        // copy fields as we can't access them after reading is re-enabled.
  64.592 +        boolean gathering = this.isGatheringWrite;
  64.593 +        CompletionHandler<Number,Object> handler = this.writeHandler;
  64.594 +        Object att = this.writeAttachment;
  64.595 +        PendingFuture<Number,Object> future = this.writeFuture;
  64.596 +        Future<?> timer = this.writeTimer;
  64.597 +
  64.598          try {
  64.599              begin();
  64.600  
  64.601 -            ByteBuffer[] srcs = writeBuffers;
  64.602 -            int n;
  64.603 -            if (srcs.length == 1) {
  64.604 -                n = IOUtil.write(fd, srcs[0], -1, nd, null);
  64.605 +            if (gathering) {
  64.606 +                n = (int)IOUtil.write(fd, writeBuffers, nd);
  64.607              } else {
  64.608 -                n = (int)IOUtil.write(fd, srcs, nd);
  64.609 +                n = IOUtil.write(fd, writeBuffer, -1, nd, null);
  64.610              }
  64.611              if (n == IOStatus.UNAVAILABLE) {
  64.612                  // spurious wakeup, is this possible?
  64.613 -                pending = result;
  64.614 +                synchronized (updateLock) {
  64.615 +                    writePending = true;
  64.616 +                }
  64.617                  return;
  64.618              }
  64.619  
  64.620 -            // allow buffer(s) to be GC'ed.
  64.621 -            writeBuffers = null;
  64.622 +            // allow objects to be GC'ed.
  64.623 +            this.writeBuffer = null;
  64.624 +            this.writeBuffers = null;
  64.625 +            this.writeAttachment = null;
  64.626  
  64.627              // allow another write to be initiated
  64.628 -            boolean wasGatheringWrite = gatheringWrite;
  64.629              enableWriting();
  64.630  
  64.631 -            // result is a Long or Integer
  64.632 -            if (wasGatheringWrite) {
  64.633 -                result.setResult(Long.valueOf(n));
  64.634 -            } else {
  64.635 -                result.setResult(Integer.valueOf(n));
  64.636 -            }
  64.637 -
  64.638          } catch (Throwable x) {
  64.639              enableWriting();
  64.640              if (x instanceof ClosedChannelException)
  64.641                  x = new AsynchronousCloseException();
  64.642 -            result.setFailure(x);
  64.643 +            exc = x;
  64.644          } finally {
  64.645 -            // restart poll in case of concurrent read
  64.646 -            synchronized (this) {
  64.647 -                if (pending != null)
  64.648 -                    this.pendingWrite = pending;
  64.649 +            // restart poll in case of concurrent write
  64.650 +            synchronized (updateLock) {
  64.651                  updateEvents();
  64.652              }
  64.653              end();
  64.654          }
  64.655 -        if (invokeDirect) {
  64.656 -            Invoker.invoke(result.handler(), result);
  64.657 +
  64.658 +        // cancel the associated timer
  64.659 +        if (timer != null)
  64.660 +            timer.cancel(false);
  64.661 +
  64.662 +        // create result
  64.663 +        Number result = (exc != null) ? null : (gathering) ?
  64.664 +            (Number)Long.valueOf(n) : (Number)Integer.valueOf(n);
  64.665 +
  64.666 +        // invoke handler or set result
  64.667 +        if (handler == null) {
  64.668 +            future.setResult(result, exc);
  64.669          } else {
  64.670 -            Invoker.invokeIndirectly(result.handler(), result);
  64.671 +            if (mayInvokeDirect) {
  64.672 +                Invoker.invokeUnchecked(handler, att, result, exc);
  64.673 +            } else {
  64.674 +                Invoker.invokeIndirectly(this, handler, att, result, exc);
  64.675 +            }
  64.676          }
  64.677      }
  64.678  
  64.679      private Runnable writeTimeoutTask = new Runnable() {
  64.680          public void run() {
  64.681 -            PendingFuture<Number,Object> result = grabPendingWrite();
  64.682 -            if (result == null)
  64.683 -                return;     // already completed
  64.684 +            CompletionHandler<Number,Object> handler = null;
  64.685 +            Object att = null;
  64.686 +            PendingFuture<Number,Object> future = null;
  64.687 +
  64.688 +            synchronized (updateLock) {
  64.689 +                if (!writePending)
  64.690 +                    return;
  64.691 +                writePending = false;
  64.692 +                handler = writeHandler;
  64.693 +                att = writeAttachment;
  64.694 +                future = writeFuture;
  64.695 +            }
  64.696  
  64.697              // kill further writing before releasing waiters
  64.698              enableWriting(true);
  64.699  
  64.700 -            // set completed and invoke handler
  64.701 -            result.setFailure(new InterruptedByTimeoutException());
  64.702 -            Invoker.invokeIndirectly(result.handler(), result);
  64.703 +            // invoke handler or set result
  64.704 +            Exception exc = new InterruptedByTimeoutException();
  64.705 +            if (handler != null) {
  64.706 +                Invoker.invokeIndirectly(UnixAsynchronousSocketChannelImpl.this,
  64.707 +                    handler, att, null, exc);
  64.708 +            } else {
  64.709 +                future.setFailure(exc);
  64.710 +            }
  64.711          }
  64.712      };
  64.713  
  64.714 @@ -596,8 +655,9 @@
  64.715       */
  64.716      @Override
  64.717      @SuppressWarnings("unchecked")
  64.718 -    <V extends Number,A> Future<V> writeImpl(ByteBuffer[] srcs,
  64.719 -                                             boolean isGatheringWrite,
  64.720 +    <V extends Number,A> Future<V> implWrite(boolean isGatheringWrite,
  64.721 +                                             ByteBuffer src,
  64.722 +                                             ByteBuffer[] srcs,
  64.723                                               long timeout,
  64.724                                               TimeUnit unit,
  64.725                                               A attachment,
  64.726 @@ -607,66 +667,72 @@
  64.727              Invoker.getGroupAndInvokeCount();
  64.728          boolean invokeDirect = Invoker.mayInvokeDirect(myGroupAndInvokeCount, port);
  64.729          boolean attemptWrite = (handler == null) || invokeDirect ||
  64.730 -            !port.isFixedThreadPool();  // okay to attempt read with user thread pool
  64.731 +            !port.isFixedThreadPool();  // okay to attempt write with user thread pool
  64.732  
  64.733 -        AbstractFuture<V,A> result;
  64.734 +        int n = IOStatus.UNAVAILABLE;
  64.735 +        Throwable exc = null;
  64.736 +        boolean pending = false;
  64.737 +
  64.738          try {
  64.739              begin();
  64.740  
  64.741 -            int n;
  64.742              if (attemptWrite) {
  64.743                  if (isGatheringWrite) {
  64.744                      n = (int)IOUtil.write(fd, srcs, nd);
  64.745                  } else {
  64.746 -                    n = IOUtil.write(fd, srcs[0], -1, nd, null);
  64.747 +                    n = IOUtil.write(fd, src, -1, nd, null);
  64.748                  }
  64.749 -            } else {
  64.750 -                n = IOStatus.UNAVAILABLE;
  64.751              }
  64.752  
  64.753              if (n == IOStatus.UNAVAILABLE) {
  64.754 -                result = new PendingFuture<V,A>(this, handler, attachment, OpType.WRITE);
  64.755 -
  64.756 -                // update evetns so that read will complete asynchronously
  64.757 +                PendingFuture<V,A> result = null;
  64.758                  synchronized (updateLock) {
  64.759 +                    this.isGatheringWrite = isGatheringWrite;
  64.760 +                    this.writeBuffer = src;
  64.761                      this.writeBuffers = srcs;
  64.762 -                    this.gatheringWrite = isGatheringWrite;
  64.763 -                    this.pendingWrite = (PendingFuture<Number,Object>)result;
  64.764 +                    if (handler == null) {
  64.765 +                        this.writeHandler = null;
  64.766 +                        result = new PendingFuture<V,A>(this, OpType.WRITE);
  64.767 +                        this.writeFuture = (PendingFuture<Number,Object>)result;
  64.768 +                        this.writeAttachment = null;
  64.769 +                    } else {
  64.770 +                        this.writeHandler = (CompletionHandler<Number,Object>)handler;
  64.771 +                        this.writeAttachment = attachment;
  64.772 +                        this.writeFuture = null;
  64.773 +                    }
  64.774 +                    if (timeout > 0L) {
  64.775 +                        this.writeTimer = port.schedule(writeTimeoutTask, timeout, unit);
  64.776 +                    }
  64.777 +                    this.writePending = true;
  64.778                      updateEvents();
  64.779                  }
  64.780 -
  64.781 -                // schedule timeout
  64.782 -                if (timeout > 0L) {
  64.783 -                    Future<?> timeoutTask =
  64.784 -                        port.schedule(writeTimeoutTask, timeout, unit);
  64.785 -                    ((PendingFuture<V,A>)result).setTimeoutTask(timeoutTask);
  64.786 -                }
  64.787 +                pending = true;
  64.788                  return result;
  64.789              }
  64.790 -
  64.791 -            // data available
  64.792 -            enableWriting();
  64.793 -            if (isGatheringWrite) {
  64.794 -                result = (CompletedFuture<V,A>)CompletedFuture
  64.795 -                    .withResult(this, Long.valueOf(n), attachment);
  64.796 -            } else {
  64.797 -                result = (CompletedFuture<V,A>)CompletedFuture
  64.798 -                    .withResult(this, Integer.valueOf(n), attachment);
  64.799 -            }
  64.800          } catch (Throwable x) {
  64.801 -            enableWriting();
  64.802              if (x instanceof ClosedChannelException)
  64.803                  x = new AsynchronousCloseException();
  64.804 -            result = CompletedFuture.withFailure(this, x, attachment);
  64.805 +            exc = x;
  64.806          } finally {
  64.807 +            if (!pending)
  64.808 +                enableWriting();
  64.809              end();
  64.810          }
  64.811 -        if (invokeDirect) {
  64.812 -            Invoker.invokeDirect(myGroupAndInvokeCount, handler, result);
  64.813 +
  64.814 +        Number result = (exc != null) ? null : (isGatheringWrite) ?
  64.815 +            (Number)Long.valueOf(n) : (Number)Integer.valueOf(n);
  64.816 +
  64.817 +        // write completed immediately
  64.818 +        if (handler != null) {
  64.819 +            if (invokeDirect) {
  64.820 +                Invoker.invokeDirect(myGroupAndInvokeCount, handler, attachment, (V)result, exc);
  64.821 +            } else {
  64.822 +                Invoker.invokeIndirectly(this, handler, attachment, (V)result, exc);
  64.823 +            }
  64.824 +            return null;
  64.825          } else {
  64.826 -            Invoker.invokeIndirectly(handler, result);
  64.827 +            return CompletedFuture.withResult((V)result, exc);
  64.828          }
  64.829 -        return result;
  64.830      }
  64.831  
  64.832      // -- Native methods --
    65.1 --- a/src/solaris/classes/sun/nio/fs/UnixPath.java	Mon Aug 24 17:26:09 2009 -0700
    65.2 +++ b/src/solaris/classes/sun/nio/fs/UnixPath.java	Tue Sep 01 13:03:09 2009 -0700
    65.3 @@ -65,9 +65,6 @@
    65.4      // array of offsets of elements in path (created lazily)
    65.5      private volatile int[] offsets;
    65.6  
    65.7 -    // file permissions (created lazily)
    65.8 -    private volatile FilePermission[] perms;
    65.9 -
   65.10      UnixPath(UnixFileSystem fs, byte[] path) {
   65.11          this.fs = fs;
   65.12          this.path = path;
   65.13 @@ -768,45 +765,23 @@
   65.14          }
   65.15      }
   65.16  
   65.17 -    // create file permissions used for read and write checks
   65.18 -    private void checkReadOrWrite(boolean checkRead) {
   65.19 -        SecurityManager sm = System.getSecurityManager();
   65.20 -        if (sm == null)
   65.21 -            return;
   65.22 -        if (perms == null) {
   65.23 -            synchronized (this) {
   65.24 -                if (perms == null) {
   65.25 -                    FilePermission[] p = new FilePermission[2];
   65.26 -                    String pathForPermCheck = getPathForPermissionCheck();
   65.27 -                    p[0] = new FilePermission(pathForPermCheck,
   65.28 -                        SecurityConstants.FILE_READ_ACTION);
   65.29 -                    p[1] = new FilePermission(pathForPermCheck,
   65.30 -                        SecurityConstants.FILE_WRITE_ACTION);
   65.31 -                    perms = p;
   65.32 -                }
   65.33 -            }
   65.34 -        }
   65.35 -        if (checkRead) {
   65.36 -            sm.checkPermission(perms[0]);
   65.37 -        } else {
   65.38 -            sm.checkPermission(perms[1]);
   65.39 -        }
   65.40 -    }
   65.41  
   65.42      void checkRead() {
   65.43 -        checkReadOrWrite(true);
   65.44 +        SecurityManager sm = System.getSecurityManager();
   65.45 +        if (sm != null)
   65.46 +            sm.checkRead(getPathForPermissionCheck());
   65.47      }
   65.48  
   65.49      void checkWrite() {
   65.50 -        checkReadOrWrite(false);
   65.51 +        SecurityManager sm = System.getSecurityManager();
   65.52 +        if (sm != null)
   65.53 +            sm.checkWrite(getPathForPermissionCheck());
   65.54      }
   65.55  
   65.56      void checkDelete() {
   65.57          SecurityManager sm = System.getSecurityManager();
   65.58 -        if (sm != null) {
   65.59 -            // permission not cached
   65.60 +        if (sm != null)
   65.61              sm.checkDelete(getPathForPermissionCheck());
   65.62 -        }
   65.63      }
   65.64  
   65.65      @Override
    66.1 --- a/src/windows/classes/sun/nio/ch/Iocp.java	Mon Aug 24 17:26:09 2009 -0700
    66.2 +++ b/src/windows/classes/sun/nio/ch/Iocp.java	Tue Sep 01 13:03:09 2009 -0700
    66.3 @@ -34,6 +34,8 @@
    66.4  import java.util.concurrent.*;
    66.5  import java.util.concurrent.locks.ReadWriteLock;
    66.6  import java.util.concurrent.locks.ReentrantReadWriteLock;
    66.7 +import java.security.AccessController;
    66.8 +import sun.security.action.GetPropertyAction;
    66.9  import sun.misc.Unsafe;
   66.10  
   66.11  /**
   66.12 @@ -44,6 +46,7 @@
   66.13  class Iocp extends AsynchronousChannelGroupImpl {
   66.14      private static final Unsafe unsafe = Unsafe.getUnsafe();
   66.15      private static final long INVALID_HANDLE_VALUE  = -1L;
   66.16 +    private static final boolean supportsThreadAgnosticIo;
   66.17  
   66.18      // maps completion key to channel
   66.19      private final ReadWriteLock keyToChannelLock = new ReentrantReadWriteLock();
   66.20 @@ -87,6 +90,13 @@
   66.21          <V,A> PendingFuture<V,A> getByOverlapped(long overlapped);
   66.22      }
   66.23  
   66.24 +    /**
   66.25 +     * Indicates if this operating system supports thread agnostic I/O.
   66.26 +     */
   66.27 +    static boolean supportsThreadAgnosticIo() {
   66.28 +        return supportsThreadAgnosticIo;
   66.29 +    }
   66.30 +
   66.31      // release all resources
   66.32      void implClose() {
   66.33          synchronized (this) {
   66.34 @@ -216,8 +226,9 @@
   66.35              } while ((key == 0) || keyToChannel.containsKey(key));
   66.36  
   66.37              // associate with I/O completion port
   66.38 -            if (handle != 0L)
   66.39 +            if (handle != 0L) {
   66.40                  createIoCompletionPort(handle, port, key, 0);
   66.41 +            }
   66.42  
   66.43              // setup mapping
   66.44              keyToChannel.put(key, ch);
   66.45 @@ -282,7 +293,7 @@
   66.46          /**
   66.47           * Invoked if the I/O operation completes successfully.
   66.48           */
   66.49 -        public void completed(int bytesTransferred);
   66.50 +        public void completed(int bytesTransferred, boolean canInvokeDirect);
   66.51  
   66.52          /**
   66.53           * Invoked if the I/O operation fails.
   66.54 @@ -305,6 +316,7 @@
   66.55          public void run() {
   66.56              Invoker.GroupAndInvokeCount myGroupAndInvokeCount =
   66.57                  Invoker.getGroupAndInvokeCount();
   66.58 +            boolean canInvokeDirect = (myGroupAndInvokeCount != null);
   66.59              CompletionStatus ioResult = new CompletionStatus();
   66.60              boolean replaceMe = false;
   66.61  
   66.62 @@ -382,7 +394,7 @@
   66.63                      ResultHandler rh = (ResultHandler)result.getContext();
   66.64                      replaceMe = true; // (if error/exception then replace thread)
   66.65                      if (error == 0) {
   66.66 -                        rh.completed(ioResult.bytesTransferred());
   66.67 +                        rh.completed(ioResult.bytesTransferred(), canInvokeDirect);
   66.68                      } else {
   66.69                          rh.failed(error, translateErrorToIOException(error));
   66.70                      }
   66.71 @@ -433,5 +445,11 @@
   66.72      static {
   66.73          Util.load();
   66.74          initIDs();
   66.75 +
   66.76 +        // thread agnostic I/O on Vista/2008 or newer
   66.77 +        String osversion = AccessController.doPrivileged(
   66.78 +            new GetPropertyAction("os.version"));
   66.79 +        String vers[] = osversion.split("\\.");
   66.80 +        supportsThreadAgnosticIo = Integer.parseInt(vers[0]) >= 6;
   66.81      }
   66.82  }
    67.1 --- a/src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java	Mon Aug 24 17:26:09 2009 -0700
    67.2 +++ b/src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java	Tue Sep 01 13:03:09 2009 -0700
    67.3 @@ -146,10 +146,12 @@
    67.4          // waits until all I/O operations have completed
    67.5          ioCache.close();
    67.6  
    67.7 -        // disassociate from port and shutdown thread pool if not default
    67.8 +        // disassociate from port
    67.9          iocp.disassociate(completionKey);
   67.10 +
   67.11 +        // for the non-default group close the port
   67.12          if (!isDefaultIocp)
   67.13 -            iocp.shutdown();
   67.14 +            iocp.detachFromThreadPool();
   67.15      }
   67.16  
   67.17      @Override
   67.18 @@ -258,14 +260,18 @@
   67.19              }
   67.20  
   67.21              // invoke completion handler
   67.22 -            Invoker.invoke(result.handler(), result);
   67.23 +            Invoker.invoke(result);
   67.24          }
   67.25  
   67.26          @Override
   67.27 -        public void completed(int bytesTransferred) {
   67.28 +        public void completed(int bytesTransferred, boolean canInvokeDirect) {
   67.29              // release waiters and invoke completion handler
   67.30              result.setResult(fli);
   67.31 -            Invoker.invoke(result.handler(), result);
   67.32 +            if (canInvokeDirect) {
   67.33 +                Invoker.invokeUnchecked(result);
   67.34 +            } else {
   67.35 +                Invoker.invoke(result);
   67.36 +            }
   67.37          }
   67.38  
   67.39          @Override
   67.40 @@ -279,16 +285,16 @@
   67.41              } else {
   67.42                  result.setFailure(new AsynchronousCloseException());
   67.43              }
   67.44 -            Invoker.invoke(result.handler(), result);
   67.45 +            Invoker.invoke(result);
   67.46          }
   67.47      }
   67.48  
   67.49      @Override
   67.50 -    public <A> Future<FileLock> lock(long position,
   67.51 -                                     long size,
   67.52 -                                     boolean shared,
   67.53 -                                     A attachment,
   67.54 -                                     CompletionHandler<FileLock,? super A> handler)
   67.55 +    <A> Future<FileLock> implLock(final long position,
   67.56 +                                  final long size,
   67.57 +                                  final boolean shared,
   67.58 +                                  A attachment,
   67.59 +                                  final CompletionHandler<FileLock,? super A> handler)
   67.60      {
   67.61          if (shared && !reading)
   67.62              throw new NonReadableChannelException();
   67.63 @@ -298,10 +304,11 @@
   67.64          // add to lock table
   67.65          FileLockImpl fli = addToFileLockTable(position, size, shared);
   67.66          if (fli == null) {
   67.67 -            CompletedFuture<FileLock,A> result = CompletedFuture
   67.68 -                .withFailure(this, new ClosedChannelException(), attachment);
   67.69 -            Invoker.invoke(handler, result);
   67.70 -            return result;
   67.71 +            Throwable exc = new ClosedChannelException();
   67.72 +            if (handler == null)
   67.73 +                return CompletedFuture.withFailure(exc);
   67.74 +            Invoker.invoke(this, handler, attachment, null, exc);
   67.75 +            return null;
   67.76          }
   67.77  
   67.78          // create Future and task that will be invoked to acquire lock
   67.79 @@ -310,13 +317,20 @@
   67.80          LockTask lockTask = new LockTask<A>(position, fli, result);
   67.81          result.setContext(lockTask);
   67.82  
   67.83 -        // initiate I/O (can only be done from thread in thread pool)
   67.84 -        try {
   67.85 -            Invoker.invokeOnThreadInThreadPool(this, lockTask);
   67.86 -        } catch (ShutdownChannelGroupException e) {
   67.87 -            // rollback
   67.88 -            removeFromFileLockTable(fli);
   67.89 -            throw e;
   67.90 +        // initiate I/O
   67.91 +        if (Iocp.supportsThreadAgnosticIo()) {
   67.92 +            lockTask.run();
   67.93 +        } else {
   67.94 +            boolean executed = false;
   67.95 +            try {
   67.96 +                Invoker.invokeOnThreadInThreadPool(this, lockTask);
   67.97 +                executed = true;
   67.98 +            } finally {
   67.99 +                if (!executed) {
  67.100 +                    // rollback
  67.101 +                    removeFromFileLockTable(fli);
  67.102 +                }
  67.103 +            }
  67.104          }
  67.105          return result;
  67.106      }
  67.107 @@ -461,14 +475,14 @@
  67.108              releaseBufferIfSubstituted();
  67.109  
  67.110              // invoke completion handler
  67.111 -            Invoker.invoke(result.handler(), result);
  67.112 +            Invoker.invoke(result);
  67.113          }
  67.114  
  67.115          /**
  67.116           * Executed when the I/O has completed
  67.117           */
  67.118          @Override
  67.119 -        public void completed(int bytesTransferred) {
  67.120 +        public void completed(int bytesTransferred, boolean canInvokeDirect) {
  67.121              updatePosition(bytesTransferred);
  67.122  
  67.123              // return direct buffer to cache if substituted
  67.124 @@ -476,14 +490,18 @@
  67.125  
  67.126              // release waiters and invoke completion handler
  67.127              result.setResult(bytesTransferred);
  67.128 -            Invoker.invoke(result.handler(), result);
  67.129 +            if (canInvokeDirect) {
  67.130 +                Invoker.invokeUnchecked(result);
  67.131 +            } else {
  67.132 +                Invoker.invoke(result);
  67.133 +            }
  67.134          }
  67.135  
  67.136          @Override
  67.137          public void failed(int error, IOException x) {
  67.138              // if EOF detected asynchronously then it is reported as error
  67.139              if (error == ERROR_HANDLE_EOF) {
  67.140 -                completed(-1);
  67.141 +                completed(-1, false);
  67.142              } else {
  67.143                  // return direct buffer to cache if substituted
  67.144                  releaseBufferIfSubstituted();
  67.145 @@ -494,16 +512,16 @@
  67.146                  } else {
  67.147                      result.setFailure(new AsynchronousCloseException());
  67.148                  }
  67.149 -                Invoker.invoke(result.handler(), result);
  67.150 +                Invoker.invoke(result);
  67.151              }
  67.152          }
  67.153      }
  67.154  
  67.155      @Override
  67.156 -    public <A> Future<Integer> read(ByteBuffer dst,
  67.157 -                                    long position,
  67.158 -                                    A attachment,
  67.159 -                                    CompletionHandler<Integer,? super A> handler)
  67.160 +    <A> Future<Integer> implRead(ByteBuffer dst,
  67.161 +                                 long position,
  67.162 +                                 A attachment,
  67.163 +                                 CompletionHandler<Integer,? super A> handler)
  67.164      {
  67.165          if (!reading)
  67.166              throw new NonReadableChannelException();
  67.167 @@ -514,10 +532,11 @@
  67.168  
  67.169          // check if channel is closed
  67.170          if (!isOpen()) {
  67.171 -            CompletedFuture<Integer,A> result = CompletedFuture
  67.172 -                .withFailure(this, new ClosedChannelException(), attachment);
  67.173 -            Invoker.invoke(handler, result);
  67.174 -            return result;
  67.175 +            Throwable exc = new ClosedChannelException();
  67.176 +            if (handler == null)
  67.177 +                return CompletedFuture.withFailure(exc);
  67.178 +            Invoker.invoke(this, handler, attachment, null, exc);
  67.179 +            return null;
  67.180          }
  67.181  
  67.182          int pos = dst.position();
  67.183 @@ -527,10 +546,10 @@
  67.184  
  67.185          // no space remaining
  67.186          if (rem == 0) {
  67.187 -            CompletedFuture<Integer,A> result =
  67.188 -                CompletedFuture.withResult(this, 0, attachment);
  67.189 -            Invoker.invoke(handler, result);
  67.190 -            return result;
  67.191 +            if (handler == null)
  67.192 +                return CompletedFuture.withResult(0);
  67.193 +            Invoker.invoke(this, handler, attachment, 0, null);
  67.194 +            return null;
  67.195          }
  67.196  
  67.197          // create Future and task that initiates read
  67.198 @@ -539,8 +558,12 @@
  67.199          ReadTask readTask = new ReadTask<A>(dst, pos, rem, position, result);
  67.200          result.setContext(readTask);
  67.201  
  67.202 -        // initiate I/O (can only be done from thread in thread pool)
  67.203 -        Invoker.invokeOnThreadInThreadPool(this, readTask);
  67.204 +        // initiate I/O
  67.205 +        if (Iocp.supportsThreadAgnosticIo()) {
  67.206 +            readTask.run();
  67.207 +        } else {
  67.208 +            Invoker.invokeOnThreadInThreadPool(this, readTask);
  67.209 +        }
  67.210          return result;
  67.211      }
  67.212  
  67.213 @@ -639,14 +662,14 @@
  67.214              }
  67.215  
  67.216              // invoke completion handler
  67.217 -            Invoker.invoke(result.handler(), result);
  67.218 +            Invoker.invoke(result);
  67.219          }
  67.220  
  67.221          /**
  67.222           * Executed when the I/O has completed
  67.223           */
  67.224          @Override
  67.225 -        public void completed(int bytesTransferred) {
  67.226 +        public void completed(int bytesTransferred, boolean canInvokeDirect) {
  67.227              updatePosition(bytesTransferred);
  67.228  
  67.229              // return direct buffer to cache if substituted
  67.230 @@ -654,7 +677,11 @@
  67.231  
  67.232              // release waiters and invoke completion handler
  67.233              result.setResult(bytesTransferred);
  67.234 -            Invoker.invoke(result.handler(), result);
  67.235 +            if (canInvokeDirect) {
  67.236 +                Invoker.invokeUnchecked(result);
  67.237 +            } else {
  67.238 +                Invoker.invoke(result);
  67.239 +            }
  67.240          }
  67.241  
  67.242          @Override
  67.243 @@ -668,15 +695,14 @@
  67.244              } else {
  67.245                  result.setFailure(new AsynchronousCloseException());
  67.246              }
  67.247 -            Invoker.invoke(result.handler(), result);
  67.248 +            Invoker.invoke(result);
  67.249          }
  67.250      }
  67.251  
  67.252 -    @Override
  67.253 -    public <A> Future<Integer> write(ByteBuffer src,
  67.254 -                                     long position,
  67.255 -                                     A attachment,
  67.256 -                                     CompletionHandler<Integer,? super A> handler)
  67.257 +    <A> Future<Integer> implWrite(ByteBuffer src,
  67.258 +                                  long position,
  67.259 +                                  A attachment,
  67.260 +                                  CompletionHandler<Integer,? super A> handler)
  67.261      {
  67.262          if (!writing)
  67.263              throw new NonWritableChannelException();
  67.264 @@ -685,10 +711,11 @@
  67.265  
  67.266          // check if channel is closed
  67.267          if (!isOpen()) {
  67.268 -            CompletedFuture<Integer,A> result = CompletedFuture
  67.269 -                .withFailure(this, new ClosedChannelException(), attachment);
  67.270 -            Invoker.invoke(handler, result);
  67.271 -            return result;
  67.272 +           Throwable exc = new ClosedChannelException();
  67.273 +            if (handler == null)
  67.274 +                return CompletedFuture.withFailure(exc);
  67.275 +            Invoker.invoke(this, handler, attachment, null, exc);
  67.276 +            return null;
  67.277          }
  67.278  
  67.279          int pos = src.position();
  67.280 @@ -698,10 +725,10 @@
  67.281  
  67.282          // nothing to write
  67.283          if (rem == 0) {
  67.284 -            CompletedFuture<Integer,A> result =
  67.285 -                CompletedFuture.withResult(this, 0, attachment);
  67.286 -            Invoker.invoke(handler, result);
  67.287 -            return result;
  67.288 +            if (handler == null)
  67.289 +                return CompletedFuture.withResult(0);
  67.290 +            Invoker.invoke(this, handler, attachment, 0, null);
  67.291 +            return null;
  67.292          }
  67.293  
  67.294          // create Future and task to initiate write
  67.295 @@ -710,8 +737,12 @@
  67.296          WriteTask writeTask = new WriteTask<A>(src, pos, rem, position, result);
  67.297          result.setContext(writeTask);
  67.298  
  67.299 -        // initiate I/O (can only be done from thread in thread pool)
  67.300 -        Invoker.invokeOnThreadInThreadPool(this, writeTask);
  67.301 +        // initiate I/O
  67.302 +        if (Iocp.supportsThreadAgnosticIo()) {
  67.303 +            writeTask.run();
  67.304 +        } else {
  67.305 +            Invoker.invokeOnThreadInThreadPool(this, writeTask);
  67.306 +        }
  67.307          return result;
  67.308      }
  67.309  
    68.1 --- a/src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java	Mon Aug 24 17:26:09 2009 -0700
    68.2 +++ b/src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java	Tue Sep 01 13:03:09 2009 -0700
    68.3 @@ -113,14 +113,14 @@
    68.4      /**
    68.5       * Task to initiate accept operation and to handle result.
    68.6       */
    68.7 -    private class AcceptTask<A> implements Runnable, Iocp.ResultHandler {
    68.8 +    private class AcceptTask implements Runnable, Iocp.ResultHandler {
    68.9          private final WindowsAsynchronousSocketChannelImpl channel;
   68.10          private final AccessControlContext acc;
   68.11 -        private final PendingFuture<AsynchronousSocketChannel,A> result;
   68.12 +        private final PendingFuture<AsynchronousSocketChannel,Object> result;
   68.13  
   68.14          AcceptTask(WindowsAsynchronousSocketChannelImpl channel,
   68.15                     AccessControlContext acc,
   68.16 -                   PendingFuture<AsynchronousSocketChannel,A> result)
   68.17 +                   PendingFuture<AsynchronousSocketChannel,Object> result)
   68.18          {
   68.19              this.channel = channel;
   68.20              this.acc = acc;
   68.21 @@ -222,14 +222,14 @@
   68.22              }
   68.23  
   68.24              // invoke completion handler
   68.25 -            Invoker.invokeIndirectly(result.handler(), result);
   68.26 +            Invoker.invokeIndirectly(result);
   68.27          }
   68.28  
   68.29          /**
   68.30           * Executed when the I/O has completed
   68.31           */
   68.32          @Override
   68.33 -        public void completed(int bytesTransferred) {
   68.34 +        public void completed(int bytesTransferred, boolean canInvokeDirect) {
   68.35              try {
   68.36                  // connection accept after group has shutdown
   68.37                  if (iocp.isShutdown()) {
   68.38 @@ -269,7 +269,7 @@
   68.39              }
   68.40  
   68.41              // invoke handler (but not directly)
   68.42 -            Invoker.invokeIndirectly(result.handler(), result);
   68.43 +            Invoker.invokeIndirectly(result);
   68.44          }
   68.45  
   68.46          @Override
   68.47 @@ -283,19 +283,20 @@
   68.48              } else {
   68.49                  result.setFailure(new AsynchronousCloseException());
   68.50              }
   68.51 -            Invoker.invokeIndirectly(result.handler(), result);
   68.52 +            Invoker.invokeIndirectly(result);
   68.53          }
   68.54      }
   68.55  
   68.56      @Override
   68.57 -    public <A> Future<AsynchronousSocketChannel> accept(A attachment,
   68.58 -        final CompletionHandler<AsynchronousSocketChannel,? super A> handler)
   68.59 +    Future<AsynchronousSocketChannel> implAccept(Object attachment,
   68.60 +        final CompletionHandler<AsynchronousSocketChannel,Object> handler)
   68.61      {
   68.62          if (!isOpen()) {
   68.63 -            CompletedFuture<AsynchronousSocketChannel,A> result = CompletedFuture
   68.64 -                .withFailure(this, new ClosedChannelException(), attachment);
   68.65 -            Invoker.invokeIndirectly(handler, result);
   68.66 -            return result;
   68.67 +            Throwable exc = new ClosedChannelException();
   68.68 +            if (handler == null)
   68.69 +                return CompletedFuture.withFailure(exc);
   68.70 +            Invoker.invokeIndirectly(this, handler, attachment, null, exc);
   68.71 +            return null;
   68.72          }
   68.73          if (isAcceptKilled())
   68.74              throw new RuntimeException("Accept not allowed due to cancellation");
   68.75 @@ -319,10 +320,10 @@
   68.76              end();
   68.77          }
   68.78          if (ioe != null) {
   68.79 -            CompletedFuture<AsynchronousSocketChannel,A> result =
   68.80 -                CompletedFuture.withFailure(this, ioe, attachment);
   68.81 -            Invoker.invokeIndirectly(handler, result);
   68.82 -            return result;
   68.83 +            if (handler == null)
   68.84 +                return CompletedFuture.withFailure(ioe);
   68.85 +            Invoker.invokeIndirectly(this, handler, attachment, null, ioe);
   68.86 +            return null;
   68.87          }
   68.88  
   68.89          // need calling context when there is security manager as
   68.90 @@ -331,20 +332,21 @@
   68.91          AccessControlContext acc = (System.getSecurityManager() == null) ?
   68.92              null : AccessController.getContext();
   68.93  
   68.94 -        PendingFuture<AsynchronousSocketChannel,A> result =
   68.95 -            new PendingFuture<AsynchronousSocketChannel,A>(this, handler, attachment);
   68.96 -        AcceptTask task = new AcceptTask<A>(ch, acc, result);
   68.97 +        PendingFuture<AsynchronousSocketChannel,Object> result =
   68.98 +            new PendingFuture<AsynchronousSocketChannel,Object>(this, handler, attachment);
   68.99 +        AcceptTask task = new AcceptTask(ch, acc, result);
  68.100          result.setContext(task);
  68.101  
  68.102          // check and set flag to prevent concurrent accepting
  68.103          if (!accepting.compareAndSet(false, true))
  68.104              throw new AcceptPendingException();
  68.105  
  68.106 -        // initiate accept. As I/O operations are tied to the initiating thread
  68.107 -        // then it will only be invoked direcly if this thread is in the thread
  68.108 -        // pool. If this thread is not in the thread pool when a task is
  68.109 -        // submitted to initiate the accept.
  68.110 -        Invoker.invokeOnThreadInThreadPool(this, task);
  68.111 +        // initiate I/O
  68.112 +        if (Iocp.supportsThreadAgnosticIo()) {
  68.113 +            task.run();
  68.114 +        } else {
  68.115 +            Invoker.invokeOnThreadInThreadPool(this, task);
  68.116 +        }
  68.117          return result;
  68.118      }
  68.119  
    69.1 --- a/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java	Mon Aug 24 17:26:09 2009 -0700
    69.2 +++ b/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java	Tue Sep 01 13:03:09 2009 -0700
    69.3 @@ -250,14 +250,14 @@
    69.4                  closeChannel();
    69.5                  result.setFailure(toIOException(exc));
    69.6              }
    69.7 -            Invoker.invoke(result.handler(), result);
    69.8 +            Invoker.invoke(result);
    69.9          }
   69.10  
   69.11          /**
   69.12           * Invoked by handler thread when connection established.
   69.13           */
   69.14          @Override
   69.15 -        public void completed(int bytesTransferred) {
   69.16 +        public void completed(int bytesTransferred, boolean canInvokeDirect) {
   69.17              Throwable exc = null;
   69.18              try {
   69.19                  begin();
   69.20 @@ -276,7 +276,11 @@
   69.21                  result.setFailure(toIOException(exc));
   69.22              }
   69.23  
   69.24 -            Invoker.invoke(result.handler(), result);
   69.25 +            if (canInvokeDirect) {
   69.26 +                Invoker.invokeUnchecked(result);
   69.27 +            } else {
   69.28 +                Invoker.invoke(result);
   69.29 +            }
   69.30          }
   69.31  
   69.32          /**
   69.33 @@ -290,20 +294,21 @@
   69.34              } else {
   69.35                  result.setFailure(new AsynchronousCloseException());
   69.36              }
   69.37 -            Invoker.invoke(result.handler(), result);
   69.38 +            Invoker.invoke(result);
   69.39          }
   69.40      }
   69.41  
   69.42      @Override
   69.43 -    public <A> Future<Void> connect(SocketAddress remote,
   69.44 -                                    A attachment,
   69.45 -                                    CompletionHandler<Void,? super A> handler)
   69.46 +    <A> Future<Void> implConnect(SocketAddress remote,
   69.47 +                                 A attachment,
   69.48 +                                 CompletionHandler<Void,? super A> handler)
   69.49      {
   69.50          if (!isOpen()) {
   69.51 -            CompletedFuture<Void,A> result = CompletedFuture
   69.52 -                .withFailure(this, new ClosedChannelException(), attachment);
   69.53 -            Invoker.invoke(handler, result);
   69.54 -            return result;
   69.55 +            Throwable exc = new ClosedChannelException();
   69.56 +            if (handler == null)
   69.57 +                return CompletedFuture.withFailure(exc);
   69.58 +            Invoker.invoke(this, handler, attachment, null, exc);
   69.59 +            return null;
   69.60          }
   69.61  
   69.62          InetSocketAddress isa = Net.checkAddress(remote);
   69.63 @@ -337,10 +342,10 @@
   69.64              try {
   69.65                  close();
   69.66              } catch (IOException ignore) { }
   69.67 -            CompletedFuture<Void,A> result = CompletedFuture
   69.68 -                .withFailure(this, bindException, attachment);
   69.69 -            Invoker.invoke(handler, result);
   69.70 -            return result;
   69.71 +            if (handler == null)
   69.72 +                return CompletedFuture.withFailure(bindException);
   69.73 +            Invoker.invoke(this, handler, attachment, null, bindException);
   69.74 +            return null;
   69.75          }
   69.76  
   69.77          // setup task
   69.78 @@ -349,8 +354,12 @@
   69.79          ConnectTask task = new ConnectTask<A>(isa, result);
   69.80          result.setContext(task);
   69.81  
   69.82 -        // initiate I/O (can only be done from thread in thread pool)
   69.83 -        Invoker.invokeOnThreadInThreadPool(this, task);
   69.84 +        // initiate I/O
   69.85 +        if (Iocp.supportsThreadAgnosticIo()) {
   69.86 +            task.run();
   69.87 +        } else {
   69.88 +            Invoker.invokeOnThreadInThreadPool(this, task);
   69.89 +        }
   69.90          return result;
   69.91      }
   69.92  
   69.93 @@ -514,7 +523,7 @@
   69.94              }
   69.95  
   69.96              // invoke completion handler
   69.97 -            Invoker.invoke(result.handler(), result);
   69.98 +            Invoker.invoke(result);
   69.99          }
  69.100  
  69.101          /**
  69.102 @@ -522,7 +531,7 @@
  69.103           */
  69.104          @Override
  69.105          @SuppressWarnings("unchecked")
  69.106 -        public void completed(int bytesTransferred) {
  69.107 +        public void completed(int bytesTransferred, boolean canInvokeDirect) {
  69.108              if (bytesTransferred == 0) {
  69.109                  bytesTransferred = -1;  // EOF
  69.110              } else {
  69.111 @@ -543,7 +552,11 @@
  69.112                      result.setResult((V)Integer.valueOf(bytesTransferred));
  69.113                  }
  69.114              }
  69.115 -            Invoker.invoke(result.handler(), result);
  69.116 +            if (canInvokeDirect) {
  69.117 +                Invoker.invokeUnchecked(result);
  69.118 +            } else {
  69.119 +                Invoker.invoke(result);
  69.120 +            }
  69.121          }
  69.122  
  69.123          @Override
  69.124 @@ -561,7 +574,7 @@
  69.125                  enableReading();
  69.126                  result.setFailure(x);
  69.127              }
  69.128 -            Invoker.invoke(result.handler(), result);
  69.129 +            Invoker.invoke(result);
  69.130          }
  69.131  
  69.132          /**
  69.133 @@ -579,13 +592,14 @@
  69.134              }
  69.135  
  69.136              // invoke handler without any locks
  69.137 -            Invoker.invoke(result.handler(), result);
  69.138 +            Invoker.invoke(result);
  69.139          }
  69.140      }
  69.141  
  69.142      @Override
  69.143 -    <V extends Number,A> Future<V> readImpl(ByteBuffer[] bufs,
  69.144 -                                            boolean scatteringRead,
  69.145 +    <V extends Number,A> Future<V> implRead(boolean isScatteringRead,
  69.146 +                                            ByteBuffer dst,
  69.147 +                                            ByteBuffer[] dsts,
  69.148                                              long timeout,
  69.149                                              TimeUnit unit,
  69.150                                              A attachment,
  69.151 @@ -594,7 +608,14 @@
  69.152          // setup task
  69.153          PendingFuture<V,A> result =
  69.154              new PendingFuture<V,A>(this, handler, attachment);
  69.155 -        final ReadTask readTask = new ReadTask<V,A>(bufs, scatteringRead, result);
  69.156 +        ByteBuffer[] bufs;
  69.157 +        if (isScatteringRead) {
  69.158 +            bufs = dsts;
  69.159 +        } else {
  69.160 +            bufs = new ByteBuffer[1];
  69.161 +            bufs[0] = dst;
  69.162 +        }
  69.163 +        final ReadTask readTask = new ReadTask<V,A>(bufs, isScatteringRead, result);
  69.164          result.setContext(readTask);
  69.165  
  69.166          // schedule timeout
  69.167 @@ -607,8 +628,12 @@
  69.168              result.setTimeoutTask(timeoutTask);
  69.169          }
  69.170  
  69.171 -        // initiate I/O (can only be done from thread in thread pool)
  69.172 -        Invoker.invokeOnThreadInThreadPool(this, readTask);
  69.173 +        // initiate I/O
  69.174 +        if (Iocp.supportsThreadAgnosticIo()) {
  69.175 +            readTask.run();
  69.176 +        } else {
  69.177 +            Invoker.invokeOnThreadInThreadPool(this, readTask);
  69.178 +        }
  69.179          return result;
  69.180      }
  69.181  
  69.182 @@ -710,7 +735,7 @@
  69.183          }
  69.184  
  69.185          @Override
  69.186 -        @SuppressWarnings("unchecked")
  69.187 +        //@SuppressWarnings("unchecked")
  69.188          public void run() {
  69.189              long overlapped = 0L;
  69.190              boolean prepared = false;
  69.191 @@ -759,7 +784,7 @@
  69.192              }
  69.193  
  69.194              // invoke completion handler
  69.195 -            Invoker.invoke(result.handler(), result);
  69.196 +            Invoker.invoke(result);
  69.197          }
  69.198  
  69.199          /**
  69.200 @@ -767,7 +792,7 @@
  69.201           */
  69.202          @Override
  69.203          @SuppressWarnings("unchecked")
  69.204 -        public void completed(int bytesTransferred) {
  69.205 +        public void completed(int bytesTransferred, boolean canInvokeDirect) {
  69.206              updateBuffers(bytesTransferred);
  69.207  
  69.208              // return direct buffer to cache if substituted
  69.209 @@ -784,7 +809,11 @@
  69.210                      result.setResult((V)Integer.valueOf(bytesTransferred));
  69.211                  }
  69.212              }
  69.213 -            Invoker.invoke(result.handler(), result);
  69.214 +            if (canInvokeDirect) {
  69.215 +                Invoker.invokeUnchecked(result);
  69.216 +            } else {
  69.217 +                Invoker.invoke(result);
  69.218 +            }
  69.219          }
  69.220  
  69.221          @Override
  69.222 @@ -802,7 +831,7 @@
  69.223                  enableWriting();
  69.224                  result.setFailure(x);
  69.225              }
  69.226 -            Invoker.invoke(result.handler(), result);
  69.227 +            Invoker.invoke(result);
  69.228          }
  69.229  
  69.230          /**
  69.231 @@ -820,13 +849,14 @@
  69.232              }
  69.233  
  69.234              // invoke handler without any locks
  69.235 -            Invoker.invoke(result.handler(), result);
  69.236 +            Invoker.invoke(result);
  69.237          }
  69.238      }
  69.239  
  69.240      @Override
  69.241 -    <V extends Number,A> Future<V> writeImpl(ByteBuffer[] bufs,
  69.242 -                                             boolean gatheringWrite,
  69.243 +    <V extends Number,A> Future<V> implWrite(boolean gatheringWrite,
  69.244 +                                             ByteBuffer src,
  69.245 +                                             ByteBuffer[] srcs,
  69.246                                               long timeout,
  69.247                                               TimeUnit unit,
  69.248                                               A attachment,
  69.249 @@ -835,6 +865,13 @@
  69.250          // setup task
  69.251          PendingFuture<V,A> result =
  69.252              new PendingFuture<V,A>(this, handler, attachment);
  69.253 +        ByteBuffer[] bufs;
  69.254 +        if (gatheringWrite) {
  69.255 +            bufs = srcs;
  69.256 +        } else {
  69.257 +            bufs = new ByteBuffer[1];
  69.258 +            bufs[0] = src;
  69.259 +        }
  69.260          final WriteTask writeTask = new WriteTask<V,A>(bufs, gatheringWrite, result);
  69.261          result.setContext(writeTask);
  69.262  
  69.263 @@ -849,7 +886,12 @@
  69.264          }
  69.265  
  69.266          // initiate I/O (can only be done from thread in thread pool)
  69.267 -        Invoker.invokeOnThreadInThreadPool(this, writeTask);
  69.268 +        // initiate I/O
  69.269 +        if (Iocp.supportsThreadAgnosticIo()) {
  69.270 +            writeTask.run();
  69.271 +        } else {
  69.272 +            Invoker.invokeOnThreadInThreadPool(this, writeTask);
  69.273 +        }
  69.274          return result;
  69.275      }
  69.276  
    70.1 --- a/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java	Mon Aug 24 17:26:09 2009 -0700
    70.2 +++ b/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java	Tue Sep 01 13:03:09 2009 -0700
    70.3 @@ -46,6 +46,7 @@
    70.4  
    70.5          @Override
    70.6          public WindowsFileAttributes readAttributes() throws IOException {
    70.7 +            file.checkRead();
    70.8              try {
    70.9                  return WindowsFileAttributes.get(file, followLinks);
   70.10              } catch (WindowsException x) {
    71.1 --- a/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java	Mon Aug 24 17:26:09 2009 -0700
    71.2 +++ b/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java	Tue Sep 01 13:03:09 2009 -0700
    71.3 @@ -246,8 +246,8 @@
    71.4          long lastWriteTime = unsafe.getLong(address + OFFSETOF_FIND_DATA_LASTWRITETIME);
    71.5          long size = ((long)(unsafe.getInt(address + OFFSETOF_FIND_DATA_SIZEHIGH)) << 32)
    71.6              + (unsafe.getInt(address + OFFSETOF_FIND_DATA_SIZELOW) & 0xFFFFFFFFL);
    71.7 -        int reparseTag = ((fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) != 0) ?
    71.8 -            + unsafe.getInt(address + OFFSETOF_FIND_DATA_RESERVED0) : 0;
    71.9 +        int reparseTag = isReparsePoint(fileAttrs) ?
   71.10 +            unsafe.getInt(address + OFFSETOF_FIND_DATA_RESERVED0) : 0;
   71.11          return new WindowsFileAttributes(fileAttrs,
   71.12                                           creationTime,
   71.13                                           lastAccessTime,
   71.14 @@ -275,7 +275,7 @@
   71.15              int reparseTag = 0;
   71.16              int fileAttrs = unsafe
   71.17                  .getInt(address + OFFSETOF_FILE_INFORMATION_ATTRIBUTES);
   71.18 -            if ((fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
   71.19 +            if (isReparsePoint(fileAttrs)) {
   71.20                  int size = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
   71.21                  NativeBuffer reparseBuffer = NativeBuffers.getNativeBuffer(size);
   71.22                  try {
   71.23 @@ -311,7 +311,7 @@
   71.24                  // just return the attributes
   71.25                  int fileAttrs = unsafe
   71.26                      .getInt(address + OFFSETOF_FILE_ATTRIBUTE_DATA_ATTRIBUTES);
   71.27 -                if ((fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) == 0)
   71.28 +                if (!isReparsePoint(fileAttrs))
   71.29                      return fromFileAttributeData(address, 0);
   71.30              } catch (WindowsException x) {
   71.31                  if (x.lastError() != ERROR_SHARING_VIOLATION)
   71.32 @@ -358,7 +358,7 @@
   71.33      }
   71.34  
   71.35      /**
   71.36 -     * Returns true if the attribtues are of the same file - both files must
   71.37 +     * Returns true if the attributes are of the same file - both files must
   71.38       * be open.
   71.39       */
   71.40      static boolean isSameFile(WindowsFileAttributes attrs1,
   71.41 @@ -370,6 +370,13 @@
   71.42                 (attrs1.fileIndexLow == attrs2.fileIndexLow);
   71.43      }
   71.44  
   71.45 +    /**
   71.46 +     * Returns true if the attributes are of a file with a reparse point.
   71.47 +     */
   71.48 +    static boolean isReparsePoint(int attributes) {
   71.49 +        return (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
   71.50 +    }
   71.51 +
   71.52      // package-private
   71.53      int attributes() {
   71.54          return fileAttrs;
   71.55 @@ -420,7 +427,7 @@
   71.56  
   71.57      // package private
   71.58      boolean isReparsePoint() {
   71.59 -        return (fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
   71.60 +        return isReparsePoint(fileAttrs);
   71.61      }
   71.62  
   71.63      boolean isDirectoryLink() {
    72.1 --- a/src/windows/classes/sun/nio/fs/WindowsFileSystem.java	Mon Aug 24 17:26:09 2009 -0700
    72.2 +++ b/src/windows/classes/sun/nio/fs/WindowsFileSystem.java	Tue Sep 01 13:03:09 2009 -0700
    72.3 @@ -283,25 +283,15 @@
    72.4              }
    72.5          }
    72.6  
    72.7 -        // match in uppercase
    72.8 -        StringBuilder sb = new StringBuilder(expr.length());
    72.9 -        for (int i=0; i<expr.length(); i++) {
   72.10 -            sb.append(Character.toUpperCase(expr.charAt(i)));
   72.11 -        }
   72.12 -        expr = sb.toString();
   72.13 +        // match in unicode_case_insensitive
   72.14 +        final Pattern pattern = Pattern.compile(expr,
   72.15 +            Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
   72.16  
   72.17          // return matcher
   72.18 -        final Pattern pattern = Pattern.compile(expr);
   72.19          return new PathMatcher() {
   72.20              @Override
   72.21              public boolean matches(Path path) {
   72.22 -                // match in uppercase
   72.23 -                String s = path.toString();
   72.24 -                StringBuilder sb = new StringBuilder(s.length());
   72.25 -                for (int i=0; i<s.length(); i++) {
   72.26 -                    sb.append( Character.toUpperCase(s.charAt(i)) );
   72.27 -                }
   72.28 -                return pattern.matcher(sb).matches();
   72.29 +                return pattern.matcher(path.toString()).matches();
   72.30              }
   72.31          };
   72.32      }
    73.1 --- a/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java	Mon Aug 24 17:26:09 2009 -0700
    73.2 +++ b/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java	Tue Sep 01 13:03:09 2009 -0700
    73.3 @@ -63,6 +63,30 @@
    73.4      }
    73.5  
    73.6      /**
    73.7 +     * Returns the final path (all symbolic links resolved) or null if this
    73.8 +     * operation is not supported.
    73.9 +     */
   73.10 +    private static String getFinalPath(WindowsPath input) throws IOException {
   73.11 +        long h = 0;
   73.12 +        try {
   73.13 +            h = input.openForReadAttributeAccess(true);
   73.14 +        } catch (WindowsException x) {
   73.15 +            x.rethrowAsIOException(input);
   73.16 +        }
   73.17 +        try {
   73.18 +            return stripPrefix(GetFinalPathNameByHandle(h));
   73.19 +        } catch (WindowsException x) {
   73.20 +            // ERROR_INVALID_LEVEL is the error returned when not supported
   73.21 +            // (a sym link to file on FAT32 or Samba server for example)
   73.22 +            if (x.lastError() != ERROR_INVALID_LEVEL)
   73.23 +                x.rethrowAsIOException(input);
   73.24 +        } finally {
   73.25 +            CloseHandle(h);
   73.26 +        }
   73.27 +        return null;
   73.28 +    }
   73.29 +
   73.30 +    /**
   73.31       * Returns the final path of a given path as a String. This should be used
   73.32       * prior to calling Win32 system calls that do not follow links.
   73.33       */
   73.34 @@ -70,7 +94,6 @@
   73.35          throws IOException
   73.36      {
   73.37          WindowsFileSystem fs = input.getFileSystem();
   73.38 -
   73.39          try {
   73.40              // if not following links then don't need final path
   73.41              if (!followLinks || !fs.supportsLinks())
   73.42 @@ -84,25 +107,10 @@
   73.43              x.rethrowAsIOException(input);
   73.44          }
   73.45  
   73.46 -        // The file is a symbolic link so we open it and try to get the
   73.47 -        // normalized path. This should succeed on NTFS but may fail if there
   73.48 -        // is a link to a non-NFTS file system.
   73.49 -        long h = 0;
   73.50 -        try {
   73.51 -            h = input.openForReadAttributeAccess(true);
   73.52 -        } catch (WindowsException x) {
   73.53 -            x.rethrowAsIOException(input);
   73.54 -        }
   73.55 -        try {
   73.56 -            return stripPrefix(GetFinalPathNameByHandle(h));
   73.57 -        } catch (WindowsException x) {
   73.58 -            // ERROR_INVALID_LEVEL is the error returned when not supported by
   73.59 -            // the file system
   73.60 -            if (x.lastError() != ERROR_INVALID_LEVEL)
   73.61 -                x.rethrowAsIOException(input);
   73.62 -        } finally {
   73.63 -            CloseHandle(h);
   73.64 -        }
   73.65 +        // The file is a symbolic link so attempt to get the final path
   73.66 +        String result = getFinalPath(input);
   73.67 +        if (result != null)
   73.68 +            return result;
   73.69  
   73.70          // Fallback: read target of link, resolve against parent, and repeat
   73.71          // until file is not a link.
   73.72 @@ -149,31 +157,9 @@
   73.73          throws IOException
   73.74      {
   73.75          WindowsFileSystem fs = input.getFileSystem();
   73.76 -        if (!fs.supportsLinks())
   73.77 +        if (resolveLinks && !fs.supportsLinks())
   73.78              resolveLinks = false;
   73.79  
   73.80 -        // On Vista use GetFinalPathNameByHandle. This should succeed on NTFS
   73.81 -        // but may fail if there is a link to a non-NFTS file system.
   73.82 -        if (resolveLinks) {
   73.83 -            long h = 0;
   73.84 -            try {
   73.85 -                h = input.openForReadAttributeAccess(true);
   73.86 -            } catch (WindowsException x) {
   73.87 -                x.rethrowAsIOException(input);
   73.88 -            }
   73.89 -            try {
   73.90 -                return stripPrefix(GetFinalPathNameByHandle(h));
   73.91 -            } catch (WindowsException x) {
   73.92 -                if (x.lastError() != ERROR_INVALID_LEVEL)
   73.93 -                    x.rethrowAsIOException(input);
   73.94 -            } finally {
   73.95 -                CloseHandle(h);
   73.96 -            }
   73.97 -        }
   73.98 -
   73.99 -        // Not resolving links or we are on Windows Vista (or newer) with a
  73.100 -        // link to non-NFTS file system.
  73.101 -
  73.102          // Start with absolute path
  73.103          String path = null;
  73.104          try {
  73.105 @@ -183,15 +169,12 @@
  73.106          }
  73.107  
  73.108          // Collapse "." and ".."
  73.109 -        try {
  73.110 -            path = GetFullPathName(path);
  73.111 -        } catch (WindowsException x) {
  73.112 -            x.rethrowAsIOException(input);
  73.113 -        }
  73.114 -
  73.115 -        // eliminate all symbolic links
  73.116 -        if (resolveLinks) {
  73.117 -            path = resolveAllLinks(WindowsPath.createFromNormalizedPath(fs, path));
  73.118 +        if (path.indexOf('.') >= 0) {
  73.119 +            try {
  73.120 +                path = GetFullPathName(path);
  73.121 +            } catch (WindowsException x) {
  73.122 +                x.rethrowAsIOException(input);
  73.123 +            }
  73.124          }
  73.125  
  73.126          // string builder to build up components of path
  73.127 @@ -229,12 +212,15 @@
  73.128              throw new AssertionError("path type not recognized");
  73.129          }
  73.130  
  73.131 -        // check root directory exists
  73.132 -        try {
  73.133 -            FirstFile fileData = FindFirstFile(sb.toString() + "*");
  73.134 -            FindClose(fileData.handle());
  73.135 -        } catch (WindowsException x) {
  73.136 -            x.rethrowAsIOException(path);
  73.137 +        // if the result is only a root component then we simply check it exists
  73.138 +        if (start >= path.length()) {
  73.139 +            String result = sb.toString();
  73.140 +            try {
  73.141 +                GetFileAttributes(result);
  73.142 +            } catch (WindowsException x) {
  73.143 +                x.rethrowAsIOException(path);
  73.144 +            }
  73.145 +            return result;
  73.146          }
  73.147  
  73.148          // iterate through each component to get its actual name in the
  73.149 @@ -246,13 +232,28 @@
  73.150              String search = sb.toString() + path.substring(curr, end);
  73.151              try {
  73.152                  FirstFile fileData = FindFirstFile(addLongPathPrefixIfNeeded(search));
  73.153 -                try {
  73.154 -                    sb.append(fileData.name());
  73.155 -                    if (next != -1) {
  73.156 -                        sb.append('\\');
  73.157 +                FindClose(fileData.handle());
  73.158 +
  73.159 +                // if a reparse point is encountered then we must return the
  73.160 +                // final path.
  73.161 +                if (resolveLinks &&
  73.162 +                    WindowsFileAttributes.isReparsePoint(fileData.attributes()))
  73.163 +                {
  73.164 +                    String result = getFinalPath(input);
  73.165 +                    if (result == null) {
  73.166 +                        // Fallback to slow path, usually because there is a sym
  73.167 +                        // link to a file system that doesn't support sym links.
  73.168 +                        WindowsPath resolved = resolveAllLinks(
  73.169 +                            WindowsPath.createFromNormalizedPath(fs, path));
  73.170 +                        result = getRealPath(resolved, false);
  73.171                      }
  73.172 -                } finally {
  73.173 -                    FindClose(fileData.handle());
  73.174 +                    return result;
  73.175 +                }
  73.176 +
  73.177 +                // add the name to the result
  73.178 +                sb.append(fileData.name());
  73.179 +                if (next != -1) {
  73.180 +                    sb.append('\\');
  73.181                  }
  73.182              } catch (WindowsException e) {
  73.183                  e.rethrowAsIOException(path);
  73.184 @@ -342,7 +343,7 @@
  73.185      /**
  73.186       * Resolve all symbolic-links in a given absolute and normalized path
  73.187       */
  73.188 -    private static String resolveAllLinks(WindowsPath path)
  73.189 +    private static WindowsPath resolveAllLinks(WindowsPath path)
  73.190          throws IOException
  73.191      {
  73.192          assert path.isAbsolute();
  73.193 @@ -401,7 +402,7 @@
  73.194              }
  73.195          }
  73.196  
  73.197 -        return path.toString();
  73.198 +        return path;
  73.199      }
  73.200  
  73.201      /**
    74.1 --- a/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java	Mon Aug 24 17:26:09 2009 -0700
    74.2 +++ b/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java	Tue Sep 01 13:03:09 2009 -0700
    74.3 @@ -180,10 +180,12 @@
    74.4      static class FirstFile {
    74.5          private long handle;
    74.6          private String name;
    74.7 +        private int attributes;
    74.8  
    74.9          private FirstFile() { }
   74.10          public long handle()    { return handle; }
   74.11          public String name()    { return name; }
   74.12 +        public int attributes() { return attributes; }
   74.13      }
   74.14      private static native void FindFirstFile0(long lpFileName, FirstFile obj)
   74.15          throws WindowsException;
    75.1 --- a/src/windows/native/java/io/WinNTFileSystem_md.c	Mon Aug 24 17:26:09 2009 -0700
    75.2 +++ b/src/windows/native/java/io/WinNTFileSystem_md.c	Tue Sep 01 13:03:09 2009 -0700
    75.3 @@ -51,13 +51,25 @@
    75.4      jfieldID path;
    75.5  } ids;
    75.6  
    75.7 +/**
    75.8 + * GetFinalPathNameByHandle is available on Windows Vista and newer
    75.9 + */
   75.10 +typedef BOOL (WINAPI* GetFinalPathNameByHandleProc) (HANDLE, LPWSTR, DWORD, DWORD);
   75.11 +static GetFinalPathNameByHandleProc GetFinalPathNameByHandle_func;
   75.12 +
   75.13  JNIEXPORT void JNICALL
   75.14  Java_java_io_WinNTFileSystem_initIDs(JNIEnv *env, jclass cls)
   75.15  {
   75.16 +    HANDLE handle;
   75.17      jclass fileClass = (*env)->FindClass(env, "java/io/File");
   75.18      if (!fileClass) return;
   75.19      ids.path =
   75.20               (*env)->GetFieldID(env, fileClass, "path", "Ljava/lang/String;");
   75.21 +    handle = LoadLibrary("kernel32");
   75.22 +    if (handle != NULL) {
   75.23 +        GetFinalPathNameByHandle_func = (GetFinalPathNameByHandleProc)
   75.24 +            GetProcAddress(handle, "GetFinalPathNameByHandleW");
   75.25 +    }
   75.26  }
   75.27  
   75.28  /* -- Path operations -- */
   75.29 @@ -65,6 +77,138 @@
   75.30  extern int wcanonicalize(const WCHAR *path, WCHAR *out, int len);
   75.31  extern int wcanonicalizeWithPrefix(const WCHAR *canonicalPrefix, const WCHAR *pathWithCanonicalPrefix, WCHAR *out, int len);
   75.32  
   75.33 +/**
   75.34 + * Retrieves the fully resolved (final) path for the given path or NULL
   75.35 + * if the function fails.
   75.36 + */
   75.37 +static WCHAR* getFinalPath(const WCHAR *path)
   75.38 +{
   75.39 +    HANDLE h;
   75.40 +    WCHAR *result;
   75.41 +    DWORD error;
   75.42 +
   75.43 +    /* Need Windows Vista or newer to get the final path */
   75.44 +    if (GetFinalPathNameByHandle_func == NULL)
   75.45 +        return NULL;
   75.46 +
   75.47 +    h = CreateFileW(path,
   75.48 +                    FILE_READ_ATTRIBUTES,
   75.49 +                    FILE_SHARE_DELETE |
   75.50 +                        FILE_SHARE_READ | FILE_SHARE_WRITE,
   75.51 +                    NULL,
   75.52 +                    OPEN_EXISTING,
   75.53 +                    FILE_FLAG_BACKUP_SEMANTICS,
   75.54 +                    NULL);
   75.55 +    if (h == INVALID_HANDLE_VALUE)
   75.56 +        return NULL;
   75.57 +
   75.58 +    /**
   75.59 +     * Allocate a buffer for the resolved path. For a long path we may need
   75.60 +     * to allocate a larger buffer.
   75.61 +     */
   75.62 +    result = (WCHAR*)malloc(MAX_PATH * sizeof(WCHAR));
   75.63 +    if (result != NULL) {
   75.64 +        DWORD len = (*GetFinalPathNameByHandle_func)(h, result, MAX_PATH, 0);
   75.65 +        if (len >= MAX_PATH) {
   75.66 +            /* retry with a buffer of the right size */
   75.67 +            result = (WCHAR*)realloc(result, (len+1) * sizeof(WCHAR));
   75.68 +            if (result != NULL) {
   75.69 +                len = (*GetFinalPathNameByHandle_func)(h, result, len, 0);
   75.70 +            } else {
   75.71 +                len = 0;
   75.72 +            }
   75.73 +        }
   75.74 +        if (len > 0) {
   75.75 +            /**
   75.76 +             * Strip prefix (should be \\?\ or \\?\UNC)
   75.77 +             */
   75.78 +            if (result[0] == L'\\' && result[1] == L'\\' &&
   75.79 +                result[2] == L'?' && result[3] == L'\\')
   75.80 +            {
   75.81 +                int isUnc = (result[4] == L'U' &&
   75.82 +                             result[5] == L'N' &&
   75.83 +                             result[6] == L'C');
   75.84 +                int prefixLen = (isUnc) ? 7 : 4;
   75.85 +                /* actual result length (includes terminator) */
   75.86 +                int resultLen = len - prefixLen + (isUnc ? 1 : 0) + 1;
   75.87 +
   75.88 +                /* copy result without prefix into new buffer */
   75.89 +                WCHAR *tmp = (WCHAR*)malloc(resultLen * sizeof(WCHAR));
   75.90 +                if (tmp == NULL) {
   75.91 +                    len = 0;
   75.92 +                } else {
   75.93 +                    WCHAR *p = result;
   75.94 +                    p += prefixLen;
   75.95 +                    if (isUnc) {
   75.96 +                        WCHAR *p2 = tmp;
   75.97 +                        p2[0] = L'\\';
   75.98 +                        p2++;
   75.99 +                        wcscpy(p2, p);
  75.100 +                    } else {
  75.101 +                        wcscpy(tmp, p);
  75.102 +                    }
  75.103 +                    free(result);
  75.104 +                    result = tmp;
  75.105 +                }
  75.106 +            }
  75.107 +        }
  75.108 +
  75.109 +        /* unable to get final path */
  75.110 +        if (len == 0 && result != NULL) {
  75.111 +            free(result);
  75.112 +            result = NULL;
  75.113 +        }
  75.114 +    }
  75.115 +
  75.116 +    error = GetLastError();
  75.117 +    if (CloseHandle(h))
  75.118 +        SetLastError(error);
  75.119 +    return result;
  75.120 +}
  75.121 +
  75.122 +/**
  75.123 + * Retrieves file information for the specified file. If the file is
  75.124 + * symbolic link then the information on fully resolved target is
  75.125 + * returned.
  75.126 + */
  75.127 +static BOOL getFileInformation(const WCHAR *path,
  75.128 +                               BY_HANDLE_FILE_INFORMATION *finfo)
  75.129 +{
  75.130 +    BOOL result;
  75.131 +    DWORD error;
  75.132 +    HANDLE h = CreateFileW(path,
  75.133 +                           FILE_READ_ATTRIBUTES,
  75.134 +                           FILE_SHARE_DELETE |
  75.135 +                               FILE_SHARE_READ | FILE_SHARE_WRITE,
  75.136 +                           NULL,
  75.137 +                           OPEN_EXISTING,
  75.138 +                           FILE_FLAG_BACKUP_SEMANTICS,
  75.139 +                           NULL);
  75.140 +    if (h == INVALID_HANDLE_VALUE)
  75.141 +        return FALSE;
  75.142 +    result = GetFileInformationByHandle(h, finfo);
  75.143 +    error = GetLastError();
  75.144 +    if (CloseHandle(h))
  75.145 +        SetLastError(error);
  75.146 +    return result;
  75.147 +}
  75.148 +
  75.149 +/**
  75.150 + * If the given attributes are the attributes of a reparse point, then
  75.151 + * read and return the attributes of the final target.
  75.152 + */
  75.153 +DWORD getFinalAttributesIfReparsePoint(WCHAR *path, DWORD a)
  75.154 +{
  75.155 +    if ((a != INVALID_FILE_ATTRIBUTES) &&
  75.156 +        ((a & FILE_ATTRIBUTE_REPARSE_POINT) != 0))
  75.157 +    {
  75.158 +        BY_HANDLE_FILE_INFORMATION finfo;
  75.159 +        BOOL res = getFileInformation(path, &finfo);
  75.160 +        a = (res) ? finfo.dwFileAttributes : INVALID_FILE_ATTRIBUTES;
  75.161 +    }
  75.162 +    return a;
  75.163 +}
  75.164 +
  75.165  JNIEXPORT jstring JNICALL
  75.166  Java_java_io_WinNTFileSystem_canonicalize0(JNIEnv *env, jobject this,
  75.167                                             jstring pathname)
  75.168 @@ -202,12 +346,15 @@
  75.169          return rv;
  75.170      if (!isReservedDeviceNameW(pathbuf)) {
  75.171          if (GetFileAttributesExW(pathbuf, GetFileExInfoStandard, &wfad)) {
  75.172 -            rv = (java_io_FileSystem_BA_EXISTS
  75.173 -                  | ((wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  75.174 -                     ? java_io_FileSystem_BA_DIRECTORY
  75.175 -                     : java_io_FileSystem_BA_REGULAR)
  75.176 -                  | ((wfad.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
  75.177 -                     ? java_io_FileSystem_BA_HIDDEN : 0));
  75.178 +            DWORD a = getFinalAttributesIfReparsePoint(pathbuf, wfad.dwFileAttributes);
  75.179 +            if (a != INVALID_FILE_ATTRIBUTES) {
  75.180 +                rv = (java_io_FileSystem_BA_EXISTS
  75.181 +                    | ((a & FILE_ATTRIBUTE_DIRECTORY)
  75.182 +                        ? java_io_FileSystem_BA_DIRECTORY
  75.183 +                        : java_io_FileSystem_BA_REGULAR)
  75.184 +                    | ((a & FILE_ATTRIBUTE_HIDDEN)
  75.185 +                        ? java_io_FileSystem_BA_HIDDEN : 0));
  75.186 +            }
  75.187          } else { /* pagefile.sys is a special case */
  75.188              if (GetLastError() == ERROR_SHARING_VIOLATION) {
  75.189                  rv = java_io_FileSystem_BA_EXISTS;
  75.190 @@ -234,6 +381,7 @@
  75.191      if (pathbuf == NULL)
  75.192          return JNI_FALSE;
  75.193      attr = GetFileAttributesW(pathbuf);
  75.194 +    attr = getFinalAttributesIfReparsePoint(pathbuf, attr);
  75.195      free(pathbuf);
  75.196      if (attr == INVALID_FILE_ATTRIBUTES)
  75.197          return JNI_FALSE;
  75.198 @@ -272,6 +420,20 @@
  75.199      if (pathbuf == NULL)
  75.200          return JNI_FALSE;
  75.201      a = GetFileAttributesW(pathbuf);
  75.202 +
  75.203 +    /* if reparse point, get final target */
  75.204 +    if ((a != INVALID_FILE_ATTRIBUTES) &&
  75.205 +        ((a & FILE_ATTRIBUTE_REPARSE_POINT) != 0))
  75.206 +    {
  75.207 +        WCHAR *fp = getFinalPath(pathbuf);
  75.208 +        if (fp == NULL) {
  75.209 +            a = INVALID_FILE_ATTRIBUTES;
  75.210 +        } else {
  75.211 +            free(pathbuf);
  75.212 +            pathbuf = fp;
  75.213 +            a = GetFileAttributesW(pathbuf);
  75.214 +        }
  75.215 +    }
  75.216      if (a != INVALID_FILE_ATTRIBUTES) {
  75.217          if (enable)
  75.218              a =  a & ~FILE_ATTRIBUTE_READONLY;
  75.219 @@ -305,7 +467,7 @@
  75.220                      /* Open existing or fail */
  75.221                      OPEN_EXISTING,
  75.222                      /* Backup semantics for directories */
  75.223 -                    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
  75.224 +                    FILE_FLAG_BACKUP_SEMANTICS,
  75.225                      /* No template file */
  75.226                      NULL);
  75.227      if (h != INVALID_HANDLE_VALUE) {
  75.228 @@ -332,7 +494,16 @@
  75.229      if (GetFileAttributesExW(pathbuf,
  75.230                               GetFileExInfoStandard,
  75.231                               &wfad)) {
  75.232 -        rv = wfad.nFileSizeHigh * ((jlong)MAXDWORD + 1) + wfad.nFileSizeLow;
  75.233 +        if ((wfad.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0) {
  75.234 +            rv = wfad.nFileSizeHigh * ((jlong)MAXDWORD + 1) + wfad.nFileSizeLow;
  75.235 +        } else {
  75.236 +            /* file is a reparse point so read attributes of final target */
  75.237 +            BY_HANDLE_FILE_INFORMATION finfo;
  75.238 +            if (getFileInformation(pathbuf, &finfo)) {
  75.239 +                rv = finfo.nFileSizeHigh * ((jlong)MAXDWORD + 1) +
  75.240 +                    finfo.nFileSizeLow;
  75.241 +            }
  75.242 +        }
  75.243      } else {
  75.244          if (GetLastError() == ERROR_SHARING_VIOLATION) {
  75.245              /* The error is "share violation", which means the file/dir
  75.246 @@ -360,31 +531,29 @@
  75.247      if (pathbuf == NULL)
  75.248          return JNI_FALSE;
  75.249      h = CreateFileW(
  75.250 -        pathbuf,                             /* Wide char path name */
  75.251 -        GENERIC_READ | GENERIC_WRITE,  /* Read and write permission */
  75.252 +        pathbuf,                              /* Wide char path name */
  75.253 +        GENERIC_READ | GENERIC_WRITE,         /* Read and write permission */
  75.254          FILE_SHARE_READ | FILE_SHARE_WRITE,   /* File sharing flags */
  75.255 -        NULL,                                /* Security attributes */
  75.256 -        CREATE_NEW,                         /* creation disposition */
  75.257 -        FILE_ATTRIBUTE_NORMAL,              /* flags and attributes */
  75.258 +        NULL,                                 /* Security attributes */
  75.259 +        CREATE_NEW,                           /* creation disposition */
  75.260 +        FILE_ATTRIBUTE_NORMAL |
  75.261 +            FILE_FLAG_OPEN_REPARSE_POINT,     /* flags and attributes */
  75.262          NULL);
  75.263  
  75.264      if (h == INVALID_HANDLE_VALUE) {
  75.265          DWORD error = GetLastError();
  75.266          if ((error != ERROR_FILE_EXISTS) && (error != ERROR_ALREADY_EXISTS)) {
  75.267 -
  75.268 -            // If a directory by the named path already exists,
  75.269 -            // return false (behavior of solaris and linux) instead of
  75.270 -            // throwing an exception
  75.271 -            DWORD fattr = GetFileAttributesW(pathbuf);
  75.272 -            if ((fattr == INVALID_FILE_ATTRIBUTES) ||
  75.273 -                    (fattr & ~FILE_ATTRIBUTE_DIRECTORY)) {
  75.274 +            // return false rather than throwing an exception when there is
  75.275 +            // an existing file.
  75.276 +            DWORD a = GetFileAttributesW(pathbuf);
  75.277 +            if (a == INVALID_FILE_ATTRIBUTES) {
  75.278                  SetLastError(error);
  75.279                  JNU_ThrowIOExceptionWithLastError(env, "Could not open file");
  75.280              }
  75.281           }
  75.282           free(pathbuf);
  75.283           return JNI_FALSE;
  75.284 -    }
  75.285 +        }
  75.286      free(pathbuf);
  75.287      CloseHandle(h);
  75.288      return JNI_TRUE;
  75.289 @@ -396,9 +565,9 @@
  75.290      /* Returns 0 on success */
  75.291      DWORD a;
  75.292  
  75.293 -    SetFileAttributesW(path, 0);
  75.294 +    SetFileAttributesW(path, FILE_ATTRIBUTE_NORMAL);
  75.295      a = GetFileAttributesW(path);
  75.296 -    if (a == ((DWORD)-1)) {
  75.297 +    if (a == INVALID_FILE_ATTRIBUTES) {
  75.298          return 1;
  75.299      } else if (a & FILE_ATTRIBUTE_DIRECTORY) {
  75.300          return !RemoveDirectoryW(path);
  75.301 @@ -578,8 +747,13 @@
  75.302      HANDLE h;
  75.303      if (pathbuf == NULL)
  75.304          return JNI_FALSE;
  75.305 -    h = CreateFileW(pathbuf, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
  75.306 -                    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
  75.307 +    h = CreateFileW(pathbuf,
  75.308 +                    FILE_WRITE_ATTRIBUTES,
  75.309 +                    FILE_SHARE_READ | FILE_SHARE_WRITE,
  75.310 +                    NULL,
  75.311 +                    OPEN_EXISTING,
  75.312 +                    FILE_FLAG_BACKUP_SEMANTICS,
  75.313 +                    0);
  75.314      if (h != INVALID_HANDLE_VALUE) {
  75.315          LARGE_INTEGER modTime;
  75.316          FILETIME t;
  75.317 @@ -607,6 +781,21 @@
  75.318      if (pathbuf == NULL)
  75.319          return JNI_FALSE;
  75.320      a = GetFileAttributesW(pathbuf);
  75.321 +
  75.322 +    /* if reparse point, get final target */
  75.323 +    if ((a != INVALID_FILE_ATTRIBUTES) &&
  75.324 +        ((a & FILE_ATTRIBUTE_REPARSE_POINT) != 0))
  75.325 +    {
  75.326 +        WCHAR *fp = getFinalPath(pathbuf);
  75.327 +        if (fp == NULL) {
  75.328 +            a = INVALID_FILE_ATTRIBUTES;
  75.329 +        } else {
  75.330 +            free(pathbuf);
  75.331 +            pathbuf = fp;
  75.332 +            a = GetFileAttributesW(pathbuf);
  75.333 +        }
  75.334 +    }
  75.335 +
  75.336      if (a != INVALID_FILE_ATTRIBUTES) {
  75.337          if (SetFileAttributesW(pathbuf, a | FILE_ATTRIBUTE_READONLY))
  75.338          rv = JNI_TRUE;
    76.1 --- a/src/windows/native/sun/nio/ch/Iocp.c	Mon Aug 24 17:26:09 2009 -0700
    76.2 +++ b/src/windows/native/sun/nio/ch/Iocp.c	Tue Sep 01 13:03:09 2009 -0700
    76.3 @@ -58,6 +58,16 @@
    76.4      completionStatus_overlapped = (*env)->GetFieldID(env, clazz, "overlapped", "J");
    76.5  }
    76.6  
    76.7 +JNIEXPORT jint JNICALL
    76.8 +Java_sun_nio_ch_Iocp_osMajorVersion(JNIEnv* env, jclass this)
    76.9 +{
   76.10 +    OSVERSIONINFOEX ver;
   76.11 +    ver.dwOSVersionInfoSize = sizeof(ver);
   76.12 +    GetVersionEx((OSVERSIONINFO *) &ver);
   76.13 +    return (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) ?
   76.14 +        (jint)(ver.dwMajorVersion) : (jint)0;
   76.15 +}
   76.16 +
   76.17  JNIEXPORT jlong JNICALL
   76.18  Java_sun_nio_ch_Iocp_createIoCompletionPort(JNIEnv* env, jclass this,
   76.19      jlong handle, jlong existingPort, jint completionKey, jint concurrency)
    77.1 --- a/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c	Mon Aug 24 17:26:09 2009 -0700
    77.2 +++ b/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c	Tue Sep 01 13:03:09 2009 -0700
    77.3 @@ -48,6 +48,7 @@
    77.4   */
    77.5  static jfieldID findFirst_handle;
    77.6  static jfieldID findFirst_name;
    77.7 +static jfieldID findFirst_attributes;
    77.8  
    77.9  static jfieldID findStream_handle;
   77.10  static jfieldID findStream_name;
   77.11 @@ -134,6 +135,7 @@
   77.12      }
   77.13      findFirst_handle = (*env)->GetFieldID(env, clazz, "handle", "J");
   77.14      findFirst_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
   77.15 +    findFirst_attributes = (*env)->GetFieldID(env, clazz, "attributes", "I");
   77.16  
   77.17      clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstStream");
   77.18      if (clazz == NULL) {
   77.19 @@ -371,6 +373,7 @@
   77.20              return;
   77.21          (*env)->SetLongField(env, obj, findFirst_handle, ptr_to_jlong(handle));
   77.22          (*env)->SetObjectField(env, obj, findFirst_name, name);
   77.23 +        (*env)->SetIntField(env, obj, findFirst_attributes, data.dwFileAttributes);
   77.24      } else {
   77.25          throwWindowsException(env, GetLastError());
   77.26      }
   77.27 @@ -387,7 +390,7 @@
   77.28      if (handle == INVALID_HANDLE_VALUE) {
   77.29          throwWindowsException(env, GetLastError());
   77.30      }
   77.31 -        return ptr_to_jlong(handle);
   77.32 +    return ptr_to_jlong(handle);
   77.33  }
   77.34  
   77.35  JNIEXPORT jstring JNICALL
    78.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.2 +++ b/test/com/sun/security/auth/callback/TextCallbackHandler/Password.java	Tue Sep 01 13:03:09 2009 -0700
    78.3 @@ -0,0 +1,47 @@
    78.4 +/*
    78.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    78.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    78.7 + *
    78.8 + * This code is free software; you can redistribute it and/or modify it
    78.9 + * under the terms of the GNU General Public License version 2 only, as
   78.10 + * published by the Free Software Foundation.
   78.11 + *
   78.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   78.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   78.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   78.15 + * version 2 for more details (a copy is included in the LICENSE file that
   78.16 + * accompanied this code).
   78.17 + *
   78.18 + * You should have received a copy of the GNU General Public License version
   78.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   78.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   78.21 + *
   78.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   78.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   78.24 + * have any questions.
   78.25 + */
   78.26 +
   78.27 +/*
   78.28 + * @test
   78.29 + * @bug 6825240
   78.30 + * @summary Password.readPassword() echos the input when System.Console is null
   78.31 + * @ignore run these by hand
   78.32 + */
   78.33 +
   78.34 +import com.sun.security.auth.callback.TextCallbackHandler;
   78.35 +import javax.security.auth.callback.*;
   78.36 +
   78.37 +public class Password {
   78.38 +   public static void main(String args[]) throws Exception {
   78.39 +        TextCallbackHandler h = new TextCallbackHandler();
   78.40 +        PasswordCallback nc = new PasswordCallback("Invisible: ", false);
   78.41 +        PasswordCallback nc2 = new PasswordCallback("Visible: ", true);
   78.42 +
   78.43 +        System.out.println("Two passwords will be prompted for. The first one " +
   78.44 +                "should have echo off, the second one on. Otherwise, this test fails");
   78.45 +        Callback[] callbacks = { nc, nc2 };
   78.46 +        h.handle(callbacks);
   78.47 +        System.out.println("You input " + new String(nc.getPassword()) +
   78.48 +                " and " + new String(nc2.getPassword()));
   78.49 +   }
   78.50 +}
    79.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.2 +++ b/test/java/io/File/SymLinks.java	Tue Sep 01 13:03:09 2009 -0700
    79.3 @@ -0,0 +1,380 @@
    79.4 +/*
    79.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    79.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    79.7 + *
    79.8 + * This code is free software; you can redistribute it and/or modify it
    79.9 + * under the terms of the GNU General Public License version 2 only, as
   79.10 + * published by the Free Software Foundation.
   79.11 + *
   79.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   79.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   79.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   79.15 + * version 2 for more details (a copy is included in the LICENSE file that
   79.16 + * accompanied this code).
   79.17 + *
   79.18 + * You should have received a copy of the GNU General Public License version
   79.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   79.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   79.21 + *
   79.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   79.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   79.24 + * have any questions.
   79.25 + */
   79.26 +
   79.27 +/* @test
   79.28 + * @bug 6595866
   79.29 + * @summary Test java.io.File operations with sym links
   79.30 + */
   79.31 +
   79.32 +import java.io.*;
   79.33 +import java.nio.file.Path;
   79.34 +import java.nio.file.attribute.*;
   79.35 +import static java.nio.file.LinkOption.*;
   79.36 +
   79.37 +public class SymLinks {
   79.38 +    final static PrintStream out = System.out;
   79.39 +
   79.40 +    final static File top = new File(System.getProperty("test.dir", "."));
   79.41 +
   79.42 +    // files used by the test
   79.43 +
   79.44 +    final static File file              = new File(top, "foofile");
   79.45 +    final static File link2file         = new File(top, "link2file");
   79.46 +    final static File link2link2file    = new File(top, "link2link2file");
   79.47 +
   79.48 +    final static File dir               = new File(top, "foodir");
   79.49 +    final static File link2dir          = new File(top, "link2dir");
   79.50 +    final static File link2link2dir     = new File(top, "link2link2dir");
   79.51 +
   79.52 +    final static File link2nobody       = new File(top, "link2nobody");
   79.53 +    final static File link2link2nobody  = new File(top, "link2link2nobody");
   79.54 +
   79.55 +    /**
   79.56 +     * Setup files, directories, and sym links used by test.
   79.57 +     */
   79.58 +    static void setup() throws IOException {
   79.59 +        // link2link2file -> link2file -> foofile
   79.60 +        FileOutputStream fos = new FileOutputStream(file);
   79.61 +        try {
   79.62 +            fos.write(new byte[16*1024]);
   79.63 +        } finally {
   79.64 +            fos.close();
   79.65 +        }
   79.66 +        mklink(link2file, file);
   79.67 +        mklink(link2link2file, link2file);
   79.68 +
   79.69 +        // link2link2dir -> link2dir -> dir
   79.70 +        assertTrue(dir.mkdir());
   79.71 +        mklink(link2dir, dir);
   79.72 +        mklink(link2link2dir, link2dir);
   79.73 +
   79.74 +        // link2link2nobody -> link2nobody -> <does-not-exist>
   79.75 +        mklink(link2nobody, new File(top, "DoesNotExist"));
   79.76 +        mklink(link2link2nobody, link2nobody);
   79.77 +    }
   79.78 +
   79.79 +    /**
   79.80 +     * Remove files, directories, and sym links used by test.
   79.81 +     */
   79.82 +    static void cleanup() throws IOException {
   79.83 +        if (file != null)
   79.84 +            file.delete();
   79.85 +        if (link2file != null)
   79.86 +            link2file.toPath().deleteIfExists();
   79.87 +        if (link2link2file != null)
   79.88 +            link2link2file.toPath().deleteIfExists();
   79.89 +        if (dir != null)
   79.90 +            dir.delete();
   79.91 +        if (link2dir != null)
   79.92 +            link2dir.toPath().deleteIfExists();
   79.93 +        if (link2link2dir != null)
   79.94 +            link2link2dir.toPath().deleteIfExists();
   79.95 +        if (link2nobody != null)
   79.96 +            link2nobody.toPath().deleteIfExists();
   79.97 +        if (link2link2nobody != null)
   79.98 +            link2link2nobody.toPath().deleteIfExists();
   79.99 +    }
  79.100 +
  79.101 +    /**
  79.102 +     * Creates a sym link source->target
  79.103 +     */
  79.104 +    static void mklink(File source, File target) throws IOException {
  79.105 +        source.toPath().createSymbolicLink(target.toPath());
  79.106 +    }
  79.107 +
  79.108 +    /**
  79.109 +     * Returns true if the "link" exists and is a sym link.
  79.110 +     */
  79.111 +    static boolean isSymLink(File link) {
  79.112 +         try {
  79.113 +            BasicFileAttributes attrs =
  79.114 +                Attributes.readBasicFileAttributes(link.toPath(), NOFOLLOW_LINKS);
  79.115 +            return attrs.isSymbolicLink();
  79.116 +         } catch (IOException x) {
  79.117 +             return false;
  79.118 +         }
  79.119 +    }
  79.120 +
  79.121 +    /**
  79.122 +     * Returns the last modified time of a sym link.
  79.123 +     */
  79.124 +    static long lastModifiedOfSymLink(File link) throws IOException {
  79.125 +        BasicFileAttributes attrs =
  79.126 +            Attributes.readBasicFileAttributes(link.toPath(), NOFOLLOW_LINKS);
  79.127 +        assertTrue(attrs.isSymbolicLink());
  79.128 +        return attrs.lastModifiedTime().toMillis();
  79.129 +    }
  79.130 +
  79.131 +    /**
  79.132 +     * Returns true if sym links are supported on the file system where
  79.133 +     * "dir" exists.
  79.134 +     */
  79.135 +    static boolean supportsSymLinks(File dir) {
  79.136 +        Path link = dir.toPath().resolve("link");
  79.137 +        Path target = dir.toPath().resolve("target");
  79.138 +        try {
  79.139 +            link.createSymbolicLink(target);
  79.140 +            link.delete();
  79.141 +            return true;
  79.142 +        } catch (UnsupportedOperationException x) {
  79.143 +            return false;
  79.144 +        } catch (IOException x) {
  79.145 +            return false;
  79.146 +        }
  79.147 +    }
  79.148 +
  79.149 +    static void assertTrue(boolean v) {
  79.150 +        if (!v) throw new RuntimeException("Test failed");
  79.151 +    }
  79.152 +
  79.153 +    static void assertFalse(boolean v) {
  79.154 +        assertTrue(!v);
  79.155 +    }
  79.156 +
  79.157 +    static void header(String h) {
  79.158 +        out.println();
  79.159 +        out.println();
  79.160 +        out.println("-- " + h + " --");
  79.161 +    }
  79.162 +
  79.163 +    /**
  79.164 +     * Tests go here.
  79.165 +     */
  79.166 +    static void go() throws IOException {
  79.167 +
  79.168 +        // check setup
  79.169 +        assertTrue(file.isFile());
  79.170 +        assertTrue(isSymLink(link2file));
  79.171 +        assertTrue(isSymLink(link2link2file));
  79.172 +        assertTrue(dir.isDirectory());
  79.173 +        assertTrue(isSymLink(link2dir));
  79.174 +        assertTrue(isSymLink(link2link2dir));
  79.175 +        assertTrue(isSymLink(link2nobody));
  79.176 +        assertTrue(isSymLink(link2link2nobody));
  79.177 +
  79.178 +        header("createNewFile");
  79.179 +
  79.180 +        assertFalse(file.createNewFile());
  79.181 +        assertFalse(link2file.createNewFile());
  79.182 +        assertFalse(link2link2file.createNewFile());
  79.183 +        assertFalse(dir.createNewFile());
  79.184 +        assertFalse(link2dir.createNewFile());
  79.185 +        assertFalse(link2link2dir.createNewFile());
  79.186 +        assertFalse(link2nobody.createNewFile());
  79.187 +        assertFalse(link2link2nobody.createNewFile());
  79.188 +
  79.189 +        header("mkdir");
  79.190 +
  79.191 +        assertFalse(file.mkdir());
  79.192 +        assertFalse(link2file.mkdir());
  79.193 +        assertFalse(link2link2file.mkdir());
  79.194 +        assertFalse(dir.mkdir());
  79.195 +        assertFalse(link2dir.mkdir());
  79.196 +        assertFalse(link2link2dir.mkdir());
  79.197 +        assertFalse(link2nobody.mkdir());
  79.198 +        assertFalse(link2link2nobody.mkdir());
  79.199 +
  79.200 +        header("delete");
  79.201 +
  79.202 +        File link = new File(top, "mylink");
  79.203 +        try {
  79.204 +            mklink(link, file);
  79.205 +            assertTrue(link.delete());
  79.206 +            assertTrue(!isSymLink(link));
  79.207 +            assertTrue(file.exists());
  79.208 +
  79.209 +            mklink(link, link2file);
  79.210 +            assertTrue(link.delete());
  79.211 +            assertTrue(!isSymLink(link));
  79.212 +            assertTrue(link2file.exists());
  79.213 +
  79.214 +            mklink(link, dir);
  79.215 +            assertTrue(link.delete());
  79.216 +            assertTrue(!isSymLink(link));
  79.217 +            assertTrue(dir.exists());
  79.218 +
  79.219 +            mklink(link, link2dir);
  79.220 +            assertTrue(link.delete());
  79.221 +            assertTrue(!isSymLink(link));
  79.222 +            assertTrue(link2dir.exists());
  79.223 +
  79.224 +            mklink(link, link2nobody);
  79.225 +            assertTrue(link.delete());
  79.226 +            assertTrue(!isSymLink(link));
  79.227 +            assertTrue(isSymLink(link2nobody));
  79.228 +
  79.229 +        } finally {
  79.230 +            link.toPath().deleteIfExists();
  79.231 +        }
  79.232 +
  79.233 +        header("renameTo");
  79.234 +
  79.235 +        File newlink = new File(top, "newlink");
  79.236 +        assertTrue(link2file.renameTo(newlink));
  79.237 +        try {
  79.238 +            assertTrue(file.exists());
  79.239 +            assertTrue(isSymLink(newlink));
  79.240 +            assertTrue(!isSymLink(link2file));
  79.241 +        } finally {
  79.242 +            newlink.renameTo(link2file);  // restore link
  79.243 +        }
  79.244 +
  79.245 +        assertTrue(link2dir.renameTo(newlink));
  79.246 +        try {
  79.247 +            assertTrue(dir.exists());
  79.248 +            assertTrue(isSymLink(newlink));
  79.249 +            assertTrue(!isSymLink(link2dir));
  79.250 +        } finally {
  79.251 +            newlink.renameTo(link2dir);  // restore link
  79.252 +        }
  79.253 +
  79.254 +        header("list");
  79.255 +
  79.256 +        final String name = "entry";
  79.257 +        File entry = new File(dir, name);
  79.258 +        try {
  79.259 +            assertTrue(dir.list().length == 0);   // directory should be empty
  79.260 +            assertTrue(link2dir.list().length == 0);
  79.261 +            assertTrue(link2link2dir.list().length == 0);
  79.262 +
  79.263 +            assertTrue(entry.createNewFile());
  79.264 +            assertTrue(dir.list().length == 1);
  79.265 +            assertTrue(dir.list()[0].equals(name));
  79.266 +
  79.267 +            // access directory by following links
  79.268 +            assertTrue(link2dir.list().length == 1);
  79.269 +            assertTrue(link2dir.list()[0].equals(name));
  79.270 +            assertTrue(link2link2dir.list().length == 1);
  79.271 +            assertTrue(link2link2dir.list()[0].equals(name));
  79.272 +
  79.273 +            // files that are not directories
  79.274 +            assertTrue(link2file.list() == null);
  79.275 +            assertTrue(link2nobody.list() == null);
  79.276 +
  79.277 +        } finally {
  79.278 +            entry.delete();
  79.279 +        }
  79.280 +
  79.281 +        header("isXXX");
  79.282 +
  79.283 +        assertTrue(file.isFile());
  79.284 +        assertTrue(link2file.isFile());
  79.285 +        assertTrue(link2link2file.isFile());
  79.286 +
  79.287 +        assertTrue(dir.isDirectory());
  79.288 +        assertTrue(link2dir.isDirectory());
  79.289 +        assertTrue(link2link2dir.isDirectory());
  79.290 +
  79.291 +        // on Windows we test with the DOS hidden attribute set
  79.292 +        if (System.getProperty("os.name").startsWith("Windows")) {
  79.293 +            DosFileAttributeView view = file.toPath()
  79.294 +                .getFileAttributeView(DosFileAttributeView.class);
  79.295 +            view.setHidden(true);
  79.296 +            try {
  79.297 +                assertTrue(file.isHidden());
  79.298 +                assertTrue(link2file.isHidden());
  79.299 +                assertTrue(link2link2file.isHidden());
  79.300 +            } finally {
  79.301 +                view.setHidden(false);
  79.302 +            }
  79.303 +            assertFalse(file.isHidden());
  79.304 +            assertFalse(link2file.isHidden());
  79.305 +            assertFalse(link2link2file.isHidden());
  79.306 +        }
  79.307 +
  79.308 +        header("length");
  79.309 +
  79.310 +        long len = file.length();
  79.311 +        assertTrue(len > 0L);
  79.312 +        // these tests should follow links
  79.313 +        assertTrue(link2file.length() == len);
  79.314 +        assertTrue(link2link2file.length() == len);
  79.315 +        assertTrue(link2nobody.length() == 0L);
  79.316 +
  79.317 +        header("lastModified / setLastModified");
  79.318 +
  79.319 +        // need time to diff between link and file
  79.320 +        long origLastModified = file.lastModified();
  79.321 +        assertTrue(origLastModified != 0L);
  79.322 +        try { Thread.sleep(2000); } catch (InterruptedException x) { }
  79.323 +        file.setLastModified(System.currentTimeMillis());
  79.324 +
  79.325 +        long lastModified = file.lastModified();
  79.326 +        assertTrue(lastModified != origLastModified);
  79.327 +        assertTrue(lastModifiedOfSymLink(link2file) != lastModified);
  79.328 +        assertTrue(lastModifiedOfSymLink(link2link2file) != lastModified);
  79.329 +        assertTrue(link2file.lastModified() == lastModified);
  79.330 +        assertTrue(link2link2file.lastModified() == lastModified);
  79.331 +        assertTrue(link2nobody.lastModified() == 0L);
  79.332 +
  79.333 +        origLastModified = dir.lastModified();
  79.334 +        assertTrue(origLastModified != 0L);
  79.335 +        dir.setLastModified(0L);
  79.336 +        assertTrue(dir.lastModified() == 0L);
  79.337 +        assertTrue(link2dir.lastModified() == 0L);
  79.338 +        assertTrue(link2link2dir.lastModified() == 0L);
  79.339 +        dir.setLastModified(origLastModified);
  79.340 +
  79.341 +        header("setXXX / canXXX");
  79.342 +
  79.343 +        assertTrue(file.canRead());
  79.344 +        assertTrue(file.canWrite());
  79.345 +        assertTrue(link2file.canRead());
  79.346 +        assertTrue(link2file.canWrite());
  79.347 +        assertTrue(link2link2file.canRead());
  79.348 +        assertTrue(link2link2file.canWrite());
  79.349 +
  79.350 +        if (file.setReadOnly()) {
  79.351 +            assertFalse(file.canWrite());
  79.352 +            assertFalse(link2file.canWrite());
  79.353 +            assertFalse(link2link2file.canWrite());
  79.354 +
  79.355 +            assertTrue(file.setWritable(true));             // make writable
  79.356 +            assertTrue(file.canWrite());
  79.357 +            assertTrue(link2file.canWrite());
  79.358 +            assertTrue(link2link2file.canWrite());
  79.359 +
  79.360 +            assertTrue(link2file.setReadOnly());            // make read only
  79.361 +            assertFalse(file.canWrite());
  79.362 +            assertFalse(link2file.canWrite());
  79.363 +            assertFalse(link2link2file.canWrite());
  79.364 +
  79.365 +            assertTrue(link2link2file.setWritable(true));   // make writable
  79.366 +            assertTrue(file.canWrite());
  79.367 +            assertTrue(link2file.canWrite());
  79.368 +            assertTrue(link2link2file.canWrite());
  79.369 +        }
  79.370 +    }
  79.371 +
  79.372 +    public static void main(String[] args) throws IOException {
  79.373 +        if (supportsSymLinks(top)) {
  79.374 +            try {
  79.375 +                setup();
  79.376 +                go();
  79.377 +            } finally {
  79.378 +                cleanup();
  79.379 +            }
  79.380 +        }
  79.381 +    }
  79.382 +
  79.383 +}
    80.1 --- a/test/java/lang/String/Split.java	Mon Aug 24 17:26:09 2009 -0700
    80.2 +++ b/test/java/lang/String/Split.java	Tue Sep 01 13:03:09 2009 -0700
    80.3 @@ -23,14 +23,18 @@
    80.4  
    80.5  /**
    80.6   * @test
    80.7 + * @bug 6840246
    80.8   * @summary test String.split()
    80.9   */
   80.10 +import java.util.Arrays;
   80.11 +import java.util.Random;
   80.12  import java.util.regex.*;
   80.13  
   80.14  public class Split {
   80.15  
   80.16      public static void main(String[] args) throws Exception {
   80.17          String source = "0123456789";
   80.18 +
   80.19          for (int limit=-2; limit<3; limit++) {
   80.20              for (int x=0; x<10; x++) {
   80.21                  String[] result = source.split(Integer.toString(x), limit);
   80.22 @@ -80,5 +84,48 @@
   80.23              throw new RuntimeException("String.split failure 8");
   80.24          if (!result[0].equals(source))
   80.25              throw new RuntimeException("String.split failure 9");
   80.26 +
   80.27 +        // check fastpath of String.split()
   80.28 +        source = "0123456789abcdefgABCDEFG";
   80.29 +        Random r = new Random();
   80.30 +
   80.31 +        for (boolean doEscape: new boolean[] {false, true}) {
   80.32 +            for (int cp = 0; cp < 0x11000; cp++) {
   80.33 +                Pattern p = null;
   80.34 +                String regex = new String(Character.toChars(cp));
   80.35 +                if (doEscape)
   80.36 +                    regex = "\\" + regex;
   80.37 +                try {
   80.38 +                    p = Pattern.compile(regex);
   80.39 +                } catch (PatternSyntaxException pse) {
   80.40 +                    // illegal syntax
   80.41 +                    try {
   80.42 +                        "abc".split(regex);
   80.43 +                    } catch (PatternSyntaxException pse0) {
   80.44 +                        continue;
   80.45 +                    }
   80.46 +                    throw new RuntimeException("String.split failure 11");
   80.47 +                }
   80.48 +                int off = r.nextInt(source.length());
   80.49 +                String[] srcStrs = new String[] {
   80.50 +                    "",
   80.51 +                    source,
   80.52 +                    regex + source,
   80.53 +                    source + regex,
   80.54 +                    source.substring(0, 3)
   80.55 +                        + regex + source.substring(3, 9)
   80.56 +                        + regex + source.substring(9, 15)
   80.57 +                        + regex + source.substring(15),
   80.58 +                    source.substring(0, off) + regex + source.substring(off)
   80.59 +                };
   80.60 +                for (String src: srcStrs) {
   80.61 +                    for (int limit=-2; limit<3; limit++) {
   80.62 +                        if (!Arrays.equals(src.split(regex, limit),
   80.63 +                                           p.split(src, limit)))
   80.64 +                            throw new RuntimeException("String.split failure 12");
   80.65 +                    }
   80.66 +                }
   80.67 +            }
   80.68 +        }
   80.69      }
   80.70  }
    81.1 --- a/test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java	Mon Aug 24 17:26:09 2009 -0700
    81.2 +++ b/test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java	Tue Sep 01 13:03:09 2009 -0700
    81.3 @@ -22,7 +22,7 @@
    81.4   */
    81.5  
    81.6  /* @test
    81.7 - * @bug 4607272
    81.8 + * @bug 4607272 6842687
    81.9   * @summary Unit test for AsynchronousChannelGroup
   81.10   */
   81.11  
   81.12 @@ -50,8 +50,6 @@
   81.13              }
   81.14              public void failed(Throwable exc, Void att) {
   81.15              }
   81.16 -            public void cancelled(Void att) {
   81.17 -            }
   81.18          });
   81.19  
   81.20          int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
   81.21 @@ -97,9 +95,6 @@
   81.22                          System.out.println("Read failed (expected)");
   81.23                          latch.countDown();
   81.24                      }
   81.25 -                    public void cancelled(Void att) {
   81.26 -                        throw new RuntimeException();
   81.27 -                    }
   81.28                  });
   81.29  
   81.30                  // close channel or shutdown group
   81.31 @@ -122,9 +117,6 @@
   81.32              public void failed(Throwable exc, Void att) {
   81.33                  throw new RuntimeException(exc);
   81.34              }
   81.35 -            public void cancelled(Void att) {
   81.36 -                throw new RuntimeException();
   81.37 -            }
   81.38          });
   81.39  
   81.40          latch.await();
    82.1 --- a/test/java/nio/channels/AsynchronousChannelGroup/Identity.java	Mon Aug 24 17:26:09 2009 -0700
    82.2 +++ b/test/java/nio/channels/AsynchronousChannelGroup/Identity.java	Tue Sep 01 13:03:09 2009 -0700
    82.3 @@ -22,7 +22,7 @@
    82.4   */
    82.5  
    82.6  /* @test
    82.7 - * @bug 4607272
    82.8 + * @bug 4607272 6842687
    82.9   * @summary Unit test for AsynchronousChannelGroup
   82.10   */
   82.11  
   82.12 @@ -90,14 +90,10 @@
   82.13                      }
   82.14                      public void failed(Throwable exc, Void att) {
   82.15                      }
   82.16 -                    public void cancelled(Void att) {
   82.17 -                    }
   82.18                  });
   82.19              }
   82.20              public void failed(Throwable exc, Void att) {
   82.21              }
   82.22 -            public void cancelled(Void att) {
   82.23 -            }
   82.24          });
   82.25          int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
   82.26          SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
   82.27 @@ -141,9 +137,6 @@
   82.28              public void failed(Throwable exc, Integer groupId) {
   82.29                  fail(exc.getMessage());
   82.30              }
   82.31 -            public void cancelled(Integer groupId) {
   82.32 -                fail("I/O operation was cancelled");
   82.33 -            }
   82.34          });
   82.35  
   82.36          // wait until
    83.1 --- a/test/java/nio/channels/AsynchronousChannelGroup/Restart.java	Mon Aug 24 17:26:09 2009 -0700
    83.2 +++ b/test/java/nio/channels/AsynchronousChannelGroup/Restart.java	Tue Sep 01 13:03:09 2009 -0700
    83.3 @@ -22,7 +22,7 @@
    83.4   */
    83.5  
    83.6  /* @test
    83.7 - * @bug 4607272
    83.8 + * @bug 4607272 6842687
    83.9   * @summary Unit test for AsynchronousChannelGroup
   83.10   * @build Restart
   83.11   * @run main/othervm -XX:-UseVMInterruptibleIO Restart
   83.12 @@ -111,8 +111,6 @@
   83.13                  }
   83.14                  public void failed(Throwable exc, Void att) {
   83.15                  }
   83.16 -                public void cancelled(Void att) {
   83.17 -                }
   83.18              });
   83.19  
   83.20              // establish loopback connection which should cause completion
    84.1 --- a/test/java/nio/channels/AsynchronousChannelGroup/Unbounded.java	Mon Aug 24 17:26:09 2009 -0700
    84.2 +++ b/test/java/nio/channels/AsynchronousChannelGroup/Unbounded.java	Tue Sep 01 13:03:09 2009 -0700
    84.3 @@ -22,7 +22,7 @@
    84.4   */
    84.5  
    84.6  /* @test
    84.7 - * @bug 4607272
    84.8 + * @bug 4607272 6842687
    84.9   * @summary Unit test for AsynchronousChannelGroup
   84.10   */
   84.11  
   84.12 @@ -52,8 +52,6 @@
   84.13              }
   84.14              public void failed(Throwable exc, Void att) {
   84.15              }
   84.16 -            public void cancelled(Void att) {
   84.17 -            }
   84.18          });
   84.19          System.out.println("Listener created.");
   84.20  
   84.21 @@ -97,8 +95,6 @@
   84.22                      }
   84.23                      public void failed(Throwable exc, AsynchronousSocketChannel ch) {
   84.24                      }
   84.25 -                    public void cancelled(AsynchronousSocketChannel ch) {
   84.26 -                    }
   84.27                  });
   84.28          }
   84.29          System.out.println("All read operations outstanding.");
    85.1 --- a/test/java/nio/channels/AsynchronousDatagramChannel/Basic.java	Mon Aug 24 17:26:09 2009 -0700
    85.2 +++ b/test/java/nio/channels/AsynchronousDatagramChannel/Basic.java	Tue Sep 01 13:03:09 2009 -0700
    85.3 @@ -22,7 +22,7 @@
    85.4   */
    85.5  
    85.6  /* @test
    85.7 - * @bug 4527345
    85.8 + * @bug 4527345 6842687
    85.9   * @summary Unit test for AsynchronousDatagramChannel
   85.10   */
   85.11  
   85.12 @@ -72,8 +72,6 @@
   85.13              }
   85.14              public void failed (Throwable exc, Void att) {
   85.15              }
   85.16 -            public void cancelled(Void att) {
   85.17 -            }
   85.18          });
   85.19          Thread.sleep(2000);
   85.20          sender.send(ByteBuffer.wrap(msg), sa);
   85.21 @@ -88,8 +86,6 @@
   85.22              public void failed (Throwable exc, Void att) {
   85.23                  exception.set(exc);
   85.24              }
   85.25 -            public void cancelled(Void att) {
   85.26 -            }
   85.27          });
   85.28          Throwable result;
   85.29          while ((result = exception.get()) == null) {
   85.30 @@ -107,8 +103,6 @@
   85.31              public void failed (Throwable exc, Void att) {
   85.32                  exception.set(exc);
   85.33              }
   85.34 -            public void cancelled(Void att) {
   85.35 -            }
   85.36          });
   85.37          ch.close();
   85.38          while ((result = exception.get()) == null) {
   85.39 @@ -162,8 +156,6 @@
   85.40              }
   85.41              public void failed (Throwable exc, Void att) {
   85.42              }
   85.43 -            public void cancelled(Void att) {
   85.44 -            }
   85.45          });
   85.46          Thread.sleep(2000);
   85.47          sender.send(ByteBuffer.wrap(msg), sa);
   85.48 @@ -178,8 +170,6 @@
   85.49              public void failed (Throwable exc, Void att) {
   85.50                  exception.set(exc);
   85.51              }
   85.52 -            public void cancelled(Void att) {
   85.53 -            }
   85.54          });
   85.55          Throwable result;
   85.56          while ((result = exception.get()) == null) {
   85.57 @@ -197,8 +187,6 @@
   85.58              public void failed (Throwable exc, Void att) {
   85.59                  exception.set(exc);
   85.60              }
   85.61 -            public void cancelled(Void att) {
   85.62 -            }
   85.63          });
   85.64          ch.close();
   85.65          while ((result = exception.get()) == null) {
   85.66 @@ -246,8 +234,6 @@
   85.67              }
   85.68              public void failed (Throwable exc, Void att) {
   85.69              }
   85.70 -            public void cancelled(Void att) {
   85.71 -            }
   85.72          });
   85.73          l2.await(5, TimeUnit.SECONDS);
   85.74  
   85.75 @@ -272,8 +258,6 @@
   85.76                      throw new RuntimeException(exc);
   85.77                  }
   85.78              }
   85.79 -            public void cancelled(Void att) {
   85.80 -            }
   85.81          });
   85.82          l3.await(5, TimeUnit.SECONDS);
   85.83  
   85.84 @@ -323,8 +307,6 @@
   85.85              }
   85.86              public void failed (Throwable exc, Void att) {
   85.87              }
   85.88 -            public void cancelled(Void att) {
   85.89 -            }
   85.90          });
   85.91          l2.await(5, TimeUnit.SECONDS);
   85.92  
   85.93 @@ -340,7 +322,7 @@
   85.94          reader.close();
   85.95      }
   85.96  
   85.97 -    static void cancelAndCheck(Future<?> result, CountDownLatch latch)
   85.98 +    static void cancelAndCheck(Future<?> result)
   85.99          throws InterruptedException
  85.100      {
  85.101          boolean cancelled = result.cancel(false);
  85.102 @@ -356,37 +338,22 @@
  85.103          } catch (ExecutionException e) {
  85.104              throw new RuntimeException("Should not fail");
  85.105          }
  85.106 -
  85.107 -        // make sure that completion handler is invoked
  85.108 -        latch.await();
  85.109      }
  85.110  
  85.111      // basic cancel tests
  85.112      static void doCancelTests() throws Exception {
  85.113          InetAddress lh = InetAddress.getLocalHost();
  85.114  
  85.115 -        // timed and non-timed receive
  85.116 +        // receive
  85.117          for (int i=0; i<2; i++) {
  85.118              AsynchronousDatagramChannel ch =
  85.119                  AsynchronousDatagramChannel.open().bind(new InetSocketAddress(0));
  85.120 -            final CountDownLatch latch = new CountDownLatch(1);
  85.121 -            long timeout = (i == 0) ? 0L : 60L;
  85.122 -            Future<SocketAddress> remote = ch
  85.123 -                .receive(ByteBuffer.allocate(100), timeout, TimeUnit.SECONDS, (Void)null,
  85.124 -                    new CompletionHandler<SocketAddress,Void>() {
  85.125 -                        public void completed(SocketAddress source, Void att) {
  85.126 -                        }
  85.127 -                        public void failed (Throwable exc, Void att) {
  85.128 -                        }
  85.129 -                        public void cancelled(Void att) {
  85.130 -                            latch.countDown();
  85.131 -                        }
  85.132 -                    });
  85.133 -            cancelAndCheck(remote, latch);
  85.134 +            Future<SocketAddress> remote = ch.receive(ByteBuffer.allocate(100));
  85.135 +            cancelAndCheck(remote);
  85.136              ch.close();
  85.137          }
  85.138  
  85.139 -        // timed and non-timed read
  85.140 +        // read
  85.141          for (int i=0; i<2; i++) {
  85.142              AsynchronousDatagramChannel ch =
  85.143                  AsynchronousDatagramChannel.open().bind(new InetSocketAddress(0));
  85.144 @@ -394,18 +361,8 @@
  85.145                  ((InetSocketAddress)(ch.getLocalAddress())).getPort()));
  85.146              final CountDownLatch latch = new CountDownLatch(1);
  85.147              long timeout = (i == 0) ? 0L : 60L;
  85.148 -            Future<Integer> result = ch
  85.149 -                .read(ByteBuffer.allocate(100), timeout, TimeUnit.SECONDS, (Void)null,
  85.150 -                    new CompletionHandler<Integer,Void>() {
  85.151 -                        public void completed(Integer bytesRead, Void att) {
  85.152 -                        }
  85.153 -                        public void failed (Throwable exc, Void att) {
  85.154 -                        }
  85.155 -                        public void cancelled(Void att) {
  85.156 -                            latch.countDown();
  85.157 -                        }
  85.158 -                    });
  85.159 -            cancelAndCheck(result, latch);
  85.160 +            Future<Integer> result = ch.read(ByteBuffer.allocate(100));
  85.161 +            cancelAndCheck(result);
  85.162              ch.close();
  85.163          }
  85.164      }
    86.1 --- a/test/java/nio/channels/AsynchronousFileChannel/Basic.java	Mon Aug 24 17:26:09 2009 -0700
    86.2 +++ b/test/java/nio/channels/AsynchronousFileChannel/Basic.java	Tue Sep 01 13:03:09 2009 -0700
    86.3 @@ -22,7 +22,7 @@
    86.4   */
    86.5  
    86.6  /* @test
    86.7 - * @bug 4607272 6822643 6830721
    86.8 + * @bug 4607272 6822643 6830721 6842687
    86.9   * @summary Unit test for AsynchronousFileChannel
   86.10   */
   86.11  
   86.12 @@ -195,8 +195,6 @@
   86.13                      }
   86.14                      public void failed(Throwable exc, Void att) {
   86.15                      }
   86.16 -                    public void cancelled(Void att) {
   86.17 -                    }
   86.18                  });
   86.19                  throw new RuntimeException("OverlappingFileLockException expected");
   86.20              } catch (OverlappingFileLockException x) {
   86.21 @@ -229,8 +227,6 @@
   86.22              }
   86.23              public void failed(Throwable exc, Void att) {
   86.24              }
   86.25 -            public void cancelled(Void att) {
   86.26 -            }
   86.27          });
   86.28  
   86.29          // wait for handler to complete
   86.30 @@ -318,8 +314,6 @@
   86.31                          }
   86.32                          public void failed(Throwable exc, Void att) {
   86.33                          }
   86.34 -                        public void cancelled(Void att) {
   86.35 -                        }
   86.36                      });
   86.37                      await(latch);
   86.38  
   86.39 @@ -338,8 +332,41 @@
   86.40                  }
   86.41              } finally {
   86.42                  ch.close();
   86.43 +                executor.shutdown();
   86.44              }
   86.45          }
   86.46 +
   86.47 +
   86.48 +        // test sharing a thread pool between many channels
   86.49 +        ExecutorService executor = Executors
   86.50 +            .newFixedThreadPool(1+rand.nextInt(10), threadFactory);
   86.51 +        final int n = 50 + rand.nextInt(50);
   86.52 +        AsynchronousFileChannel[] channels = new AsynchronousFileChannel[n];
   86.53 +        try {
   86.54 +            for (int i=0; i<n; i++) {
   86.55 +                Set<StandardOpenOption> opts = EnumSet.of(WRITE);
   86.56 +                channels[i] = AsynchronousFileChannel.open(file, opts, executor);
   86.57 +                final CountDownLatch latch = new CountDownLatch(1);
   86.58 +                channels[i].write(genBuffer(), 0L, (Void)null, new CompletionHandler<Integer,Void>() {
   86.59 +                    public void completed(Integer result, Void att) {
   86.60 +                        latch.countDown();
   86.61 +                    }
   86.62 +                    public void failed(Throwable exc, Void att) {
   86.63 +                    }
   86.64 +                });
   86.65 +                await(latch);
   86.66 +
   86.67 +                // close ~half the channels
   86.68 +                if (rand.nextBoolean())
   86.69 +                    channels[i].close();
   86.70 +            }
   86.71 +        } finally {
   86.72 +            // close remaining channels
   86.73 +            for (int i=0; i<n; i++) {
   86.74 +                if (channels[i] != null) channels[i].close();
   86.75 +            }
   86.76 +            executor.shutdown();
   86.77 +        }
   86.78      }
   86.79  
   86.80      // exercise asynchronous close
   86.81 @@ -409,17 +436,7 @@
   86.82                  .open(file, WRITE, SYNC);
   86.83  
   86.84              // start write operation
   86.85 -            final CountDownLatch latch = new CountDownLatch(1);
   86.86 -            Future<Integer> res = ch.write(genBuffer(), 0L, (Void)null,
   86.87 -                new CompletionHandler<Integer,Void>() {
   86.88 -                    public void completed(Integer result, Void att) {
   86.89 -                    }
   86.90 -                    public void failed(Throwable exc, Void att) {
   86.91 -                    }
   86.92 -                    public void cancelled(Void att) {
   86.93 -                        latch.countDown();
   86.94 -                    }
   86.95 -            });
   86.96 +            Future<Integer> res = ch.write(genBuffer(), 0L);
   86.97  
   86.98              // cancel operation
   86.99              boolean cancelled = res.cancel(mayInterruptIfRunning);
  86.100 @@ -456,10 +473,6 @@
  86.101                  throw new RuntimeException(x);
  86.102              }
  86.103  
  86.104 -            // check that cancelled method is invoked
  86.105 -            if (cancelled)
  86.106 -                await(latch);
  86.107 -
  86.108              ch.close();
  86.109          }
  86.110      }
  86.111 @@ -547,8 +560,6 @@
  86.112              }
  86.113              public void failed(Throwable exc, Long position) {
  86.114              }
  86.115 -            public void cancelled(Long position) {
  86.116 -            }
  86.117          });
  86.118  
  86.119          // wait for writes to complete
  86.120 @@ -574,8 +585,6 @@
  86.121              }
  86.122              public void failed(Throwable exc, Long position) {
  86.123              }
  86.124 -            public void cancelled(Long position) {
  86.125 -            }
  86.126          });
  86.127  
  86.128          // wait for reads to complete
    87.1 --- a/test/java/nio/channels/AsynchronousFileChannel/CustomThreadPool.java	Mon Aug 24 17:26:09 2009 -0700
    87.2 +++ b/test/java/nio/channels/AsynchronousFileChannel/CustomThreadPool.java	Tue Sep 01 13:03:09 2009 -0700
    87.3 @@ -22,7 +22,7 @@
    87.4   */
    87.5  
    87.6  /* @test
    87.7 - * @bug 4607272
    87.8 + * @bug 4607272 6842687
    87.9   * @summary Unit test for java.nio.channels.AsynchronousFileChannel
   87.10   * @build CustomThreadPool MyThreadFactory
   87.11   * @run main/othervm -Djava.nio.channels.DefaultThreadPool.threadFactory=MyThreadFactory CustomThreadPool
   87.12 @@ -51,8 +51,6 @@
   87.13                  }
   87.14                  public void failed(Throwable exc, AtomicReference<Thread> invoker) {
   87.15                  }
   87.16 -                public void cancelled(AtomicReference<Thread> invoker) {
   87.17 -                }
   87.18              });
   87.19          Thread t;
   87.20          while ((t = invoker.get()) == null) {
    88.1 --- a/test/java/nio/channels/AsynchronousFileChannel/Lock.java	Mon Aug 24 17:26:09 2009 -0700
    88.2 +++ b/test/java/nio/channels/AsynchronousFileChannel/Lock.java	Tue Sep 01 13:03:09 2009 -0700
    88.3 @@ -23,7 +23,7 @@
    88.4  
    88.5  
    88.6  /* @test
    88.7 - * @bug 4607272 6814948
    88.8 + * @bug 4607272 6814948 6842687
    88.9   * @summary Unit test for AsynchronousFileChannel#lock method
   88.10   */
   88.11  
   88.12 @@ -97,7 +97,7 @@
   88.13          slave.lock(0, 10, false);
   88.14  
   88.15          // this VM acquires lock on non-overlapping range
   88.16 -        fl = ch.lock(10, 10, false, null, null).get();
   88.17 +        fl = ch.lock(10, 10, false).get();
   88.18          fl.release();
   88.19  
   88.20          // done
    89.1 --- a/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java	Mon Aug 24 17:26:09 2009 -0700
    89.2 +++ b/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java	Tue Sep 01 13:03:09 2009 -0700
    89.3 @@ -22,7 +22,7 @@
    89.4   */
    89.5  
    89.6  /* @test
    89.7 - * @bug 4607272
    89.8 + * @bug 4607272 6842687
    89.9   * @summary Unit test for AsynchronousServerSocketChannel
   89.10   * @run main/timeout=180 Basic
   89.11   */
   89.12 @@ -104,8 +104,6 @@
   89.13              public void failed(Throwable exc, Void att) {
   89.14                  exception.set(exc);
   89.15              }
   89.16 -            public void cancelled(Void att) {
   89.17 -            }
   89.18          });
   89.19  
   89.20          // check AcceptPendingException
    90.1 --- a/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Mon Aug 24 17:26:09 2009 -0700
    90.2 +++ b/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Tue Sep 01 13:03:09 2009 -0700
    90.3 @@ -22,7 +22,7 @@
    90.4   */
    90.5  
    90.6  /* @test
    90.7 - * @bug 4607272
    90.8 + * @bug 4607272 6842687
    90.9   * @summary Unit test for AsynchronousSocketChannel
   90.10   * @run main/timeout=600 Basic
   90.11   */
   90.12 @@ -187,8 +187,6 @@
   90.13              public void failed(Throwable exc, Void att) {
   90.14                  connectException.set(exc);
   90.15              }
   90.16 -            public void cancelled(Void att) {
   90.17 -            }
   90.18          });
   90.19          while (connectException.get() == null) {
   90.20              Thread.sleep(100);
   90.21 @@ -289,8 +287,6 @@
   90.22              public void failed(Throwable x, AsynchronousSocketChannel ch) {
   90.23                  writeException.set(x);
   90.24              }
   90.25 -            public void cancelled(AsynchronousSocketChannel ch) {
   90.26 -            }
   90.27          });
   90.28  
   90.29          // give time for socket buffer to fill up.
   90.30 @@ -330,18 +326,8 @@
   90.31              SocketChannel peer = server.accept();
   90.32  
   90.33              // start read operation
   90.34 -            final CountDownLatch latch = new CountDownLatch(1);
   90.35              ByteBuffer buf = ByteBuffer.allocate(1);
   90.36 -            Future<Integer> res = ch.read(buf, (Void)null,
   90.37 -                new CompletionHandler<Integer,Void>() {
   90.38 -                    public void completed(Integer result, Void att) {
   90.39 -                    }
   90.40 -                    public void failed(Throwable exc, Void att) {
   90.41 -                    }
   90.42 -                    public void cancelled(Void att) {
   90.43 -                        latch.countDown();
   90.44 -                    }
   90.45 -            });
   90.46 +            Future<Integer> res = ch.read(buf);
   90.47  
   90.48              // cancel operation
   90.49              boolean cancelled = res.cancel(mayInterruptIfRunning);
   90.50 @@ -362,8 +348,11 @@
   90.51              } catch (CancellationException x) {
   90.52              }
   90.53  
   90.54 -            // check that completion handler executed.
   90.55 -            latch.await();
   90.56 +            // check that the cancel doesn't impact writing to the channel
   90.57 +            if (!mayInterruptIfRunning) {
   90.58 +                buf = ByteBuffer.wrap("a".getBytes());
   90.59 +                ch.write(buf).get();
   90.60 +            }
   90.61  
   90.62              ch.close();
   90.63              peer.close();
   90.64 @@ -408,8 +397,6 @@
   90.65              }
   90.66              public void failed(Throwable exc, Void att) {
   90.67              }
   90.68 -            public void cancelled(Void att) {
   90.69 -            }
   90.70          });
   90.71  
   90.72          latch.await();
   90.73 @@ -460,8 +447,6 @@
   90.74              }
   90.75              public void failed(Throwable exc, Void att) {
   90.76              }
   90.77 -            public void cancelled(Void att) {
   90.78 -            }
   90.79          });
   90.80  
   90.81          // trickle the writing
   90.82 @@ -507,26 +492,24 @@
   90.83          }
   90.84  
   90.85          // scattering read that completes ascynhronously
   90.86 -        final CountDownLatch latch = new CountDownLatch(1);
   90.87 +        final CountDownLatch l1 = new CountDownLatch(1);
   90.88          ch.read(dsts, 0, dsts.length, 0L, TimeUnit.SECONDS, (Void)null,
   90.89              new CompletionHandler<Long,Void>() {
   90.90                  public void completed(Long result, Void att) {
   90.91                      long n = result;
   90.92                      if (n <= 0)
   90.93                          throw new RuntimeException("No bytes read");
   90.94 -                    latch.countDown();
   90.95 +                    l1.countDown();
   90.96                  }
   90.97                  public void failed(Throwable exc, Void att) {
   90.98                  }
   90.99 -                public void cancelled(Void att) {
  90.100 -                }
  90.101          });
  90.102  
  90.103          // write some bytes
  90.104          sc.write(genBuffer());
  90.105  
  90.106          // read should now complete
  90.107 -        latch.await();
  90.108 +        l1.await();
  90.109  
  90.110          // write more bytes
  90.111          sc.write(genBuffer());
  90.112 @@ -535,10 +518,20 @@
  90.113          for (int i=0; i<dsts.length; i++) {
  90.114              dsts[i].rewind();
  90.115          }
  90.116 -        long n = ch
  90.117 -            .read(dsts, 0, dsts.length, 0L, TimeUnit.SECONDS, (Void)null, null).get();
  90.118 -        if (n <= 0)
  90.119 -            throw new RuntimeException("No bytes read");
  90.120 +
  90.121 +        final CountDownLatch l2 = new CountDownLatch(1);
  90.122 +        ch.read(dsts, 0, dsts.length, 0L, TimeUnit.SECONDS, (Void)null,
  90.123 +            new CompletionHandler<Long,Void>() {
  90.124 +                public void completed(Long result, Void att) {
  90.125 +                    long n = result;
  90.126 +                    if (n <= 0)
  90.127 +                        throw new RuntimeException("No bytes read");
  90.128 +                    l2.countDown();
  90.129 +                }
  90.130 +                public void failed(Throwable exc, Void att) {
  90.131 +                }
  90.132 +        });
  90.133 +        l2.await();
  90.134  
  90.135          ch.close();
  90.136          sc.close();
  90.137 @@ -574,8 +567,6 @@
  90.138              }
  90.139              public void failed(Throwable exc, Void att) {
  90.140              }
  90.141 -            public void cancelled(Void att) {
  90.142 -            }
  90.143          });
  90.144  
  90.145          // read to EOF or buffer full
  90.146 @@ -613,19 +604,29 @@
  90.147          ch.connect(server.address()).get();
  90.148          SocketChannel sc = server.accept();
  90.149  
  90.150 +        // number of bytes written
  90.151 +        final AtomicLong bytesWritten = new AtomicLong(0);
  90.152 +
  90.153          // write buffers (should complete immediately)
  90.154          ByteBuffer[] srcs = genBuffers(1);
  90.155 -        long n = ch
  90.156 -            .write(srcs, 0, srcs.length, 0L, TimeUnit.SECONDS, (Void)null, null).get();
  90.157 -        if (n <= 0)
  90.158 -            throw new RuntimeException("No bytes written");
  90.159 +        final CountDownLatch l1 = new CountDownLatch(1);
  90.160 +        ch.write(srcs, 0, srcs.length, 0L, TimeUnit.SECONDS, (Void)null,
  90.161 +            new CompletionHandler<Long,Void>() {
  90.162 +                public void completed(Long result, Void att) {
  90.163 +                    long n = result;
  90.164 +                    if (n <= 0)
  90.165 +                        throw new RuntimeException("No bytes read");
  90.166 +                    bytesWritten.addAndGet(n);
  90.167 +                    l1.countDown();
  90.168 +                }
  90.169 +                public void failed(Throwable exc, Void att) {
  90.170 +                }
  90.171 +        });
  90.172 +        l1.await();
  90.173  
  90.174          // set to true to signal that no more buffers should be written
  90.175          final AtomicBoolean continueWriting = new AtomicBoolean(true);
  90.176  
  90.177 -        // number of bytes written
  90.178 -        final AtomicLong bytesWritten = new AtomicLong(n);
  90.179 -
  90.180          // write until socket buffer is full so as to create the conditions
  90.181          // for when a write does not complete immediately
  90.182          srcs = genBuffers(1);
  90.183 @@ -644,8 +645,6 @@
  90.184                  }
  90.185                  public void failed(Throwable exc, Void att) {
  90.186                  }
  90.187 -                public void cancelled(Void att) {
  90.188 -                }
  90.189          });
  90.190  
  90.191          // give time for socket buffer to fill up.
  90.192 @@ -658,7 +657,7 @@
  90.193          ByteBuffer buf = ByteBuffer.allocateDirect(4096);
  90.194          long total = 0L;
  90.195          do {
  90.196 -            n = sc.read(buf);
  90.197 +            int n = sc.read(buf);
  90.198              if (n <= 0)
  90.199                  throw new RuntimeException("No bytes read");
  90.200              buf.rewind();
  90.201 @@ -714,15 +713,27 @@
  90.202  
  90.203          System.out.println("-- timeout when reading --");
  90.204  
  90.205 +        ByteBuffer dst = ByteBuffer.allocate(512);
  90.206 +
  90.207 +        final AtomicReference<Throwable> readException = new AtomicReference<Throwable>();
  90.208 +
  90.209          // this read should timeout
  90.210 -        ByteBuffer dst = ByteBuffer.allocate(512);
  90.211 -        try {
  90.212 -            ch.read(dst, 3, TimeUnit.SECONDS, (Void)null, null).get();
  90.213 -            throw new RuntimeException("Read did not timeout");
  90.214 -        } catch (ExecutionException x) {
  90.215 -            if (!(x.getCause() instanceof InterruptedByTimeoutException))
  90.216 -                throw new RuntimeException("InterruptedByTimeoutException expected");
  90.217 +        ch.read(dst, 3, TimeUnit.SECONDS, (Void)null,
  90.218 +            new CompletionHandler<Integer,Void>()
  90.219 +        {
  90.220 +            public void completed(Integer result, Void att) {
  90.221 +                throw new RuntimeException("Should not complete");
  90.222 +            }
  90.223 +            public void failed(Throwable exc, Void att) {
  90.224 +                readException.set(exc);
  90.225 +            }
  90.226 +        });
  90.227 +        // wait for exception
  90.228 +        while (readException.get() == null) {
  90.229 +            Thread.sleep(100);
  90.230          }
  90.231 +        if (!(readException.get() instanceof InterruptedByTimeoutException))
  90.232 +            throw new RuntimeException("InterruptedByTimeoutException expected");
  90.233  
  90.234          // after a timeout then further reading should throw unspecified runtime exception
  90.235          boolean exceptionThrown = false;
  90.236 @@ -752,8 +763,6 @@
  90.237              public void failed(Throwable exc, AsynchronousSocketChannel ch) {
  90.238                  writeException.set(exc);
  90.239              }
  90.240 -            public void cancelled(AsynchronousSocketChannel ch) {
  90.241 -            }
  90.242          });
  90.243  
  90.244          // wait for exception
    91.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    91.2 +++ b/test/java/nio/channels/AsynchronousSocketChannel/DieBeforeComplete.java	Tue Sep 01 13:03:09 2009 -0700
    91.3 @@ -0,0 +1,136 @@
    91.4 +/*
    91.5 + * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
    91.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    91.7 + *
    91.8 + * This code is free software; you can redistribute it and/or modify it
    91.9 + * under the terms of the GNU General Public License version 2 only, as
   91.10 + * published by the Free Software Foundation.
   91.11 + *
   91.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   91.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   91.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   91.15 + * version 2 for more details (a copy is included in the LICENSE file that
   91.16 + * accompanied this code).
   91.17 + *
   91.18 + * You should have received a copy of the GNU General Public License version
   91.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   91.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   91.21 + *
   91.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   91.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   91.24 + * have any questions.
   91.25 + */
   91.26 +
   91.27 +/* @test
   91.28 + * @bug 6842687
   91.29 + * @summary Unit test for AsynchronousSocketChannel/AsynchronousServerSocketChannel
   91.30 + */
   91.31 +import java.nio.ByteBuffer;
   91.32 +import java.nio.channels.*;
   91.33 +import java.net.*;
   91.34 +import java.util.concurrent.*;
   91.35 +import java.util.concurrent.atomic.AtomicReference;
   91.36 +
   91.37 +/**
   91.38 + * Initiates I/O operation on a thread that terminates before the I/O completes.
   91.39 + */
   91.40 +
   91.41 +public class DieBeforeComplete {
   91.42 +
   91.43 +    public static void main(String[] args) throws Exception {
   91.44 +        final AsynchronousServerSocketChannel listener =
   91.45 +                AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(0));
   91.46 +
   91.47 +        InetAddress lh = InetAddress.getLocalHost();
   91.48 +        int port = ((InetSocketAddress) (listener.getLocalAddress())).getPort();
   91.49 +        final SocketAddress sa = new InetSocketAddress(lh, port);
   91.50 +
   91.51 +        // -- accept --
   91.52 +
   91.53 +        // initiate accept in a thread that dies before connection is established
   91.54 +        Future<AsynchronousSocketChannel> r1 =
   91.55 +                initiateAndDie(new Task<AsynchronousSocketChannel>() {
   91.56 +            public Future<AsynchronousSocketChannel> run() {
   91.57 +                return listener.accept();
   91.58 +            }});
   91.59 +
   91.60 +        // establish and accept connection
   91.61 +        SocketChannel peer = SocketChannel.open(sa);
   91.62 +        final AsynchronousSocketChannel channel = r1.get();
   91.63 +
   91.64 +        // --- read --
   91.65 +
   91.66 +        // initiate read in a thread that dies befores bytes are available
   91.67 +        final ByteBuffer dst = ByteBuffer.allocate(100);
   91.68 +        Future<Integer> r2 = initiateAndDie(new Task<Integer>() {
   91.69 +            public Future<Integer> run() {
   91.70 +                return channel.read(dst);
   91.71 +            }});
   91.72 +
   91.73 +        // send bytes
   91.74 +        peer.write(ByteBuffer.wrap("hello".getBytes()));
   91.75 +        int nread = r2.get();
   91.76 +        if (nread <= 0)
   91.77 +            throw new RuntimeException("Should have read at least one byte");
   91.78 +
   91.79 +        // -- write --
   91.80 +
   91.81 +        // initiate writes in threads that dies
   91.82 +        boolean completedImmediately;
   91.83 +        Future<Integer> r3;
   91.84 +        do {
   91.85 +            final ByteBuffer src = ByteBuffer.wrap(new byte[10000]);
   91.86 +            r3 = initiateAndDie(new Task<Integer>() {
   91.87 +                public Future<Integer> run() {
   91.88 +                    return channel.write(src);
   91.89 +                }});
   91.90 +            try {
   91.91 +                int nsent = r3.get(5, TimeUnit.SECONDS);
   91.92 +                if (nsent <= 0)
   91.93 +                    throw new RuntimeException("Should have wrote at least one byte");
   91.94 +                completedImmediately = true;
   91.95 +            } catch (TimeoutException x) {
   91.96 +                completedImmediately = false;
   91.97 +            }
   91.98 +        } while (completedImmediately);
   91.99 +
  91.100 +        // drain connection
  91.101 +        peer.configureBlocking(false);
  91.102 +        ByteBuffer src = ByteBuffer.allocateDirect(10000);
  91.103 +        do {
  91.104 +            src.clear();
  91.105 +            nread = peer.read(src);
  91.106 +            if (nread == 0) {
  91.107 +                Thread.sleep(100);
  91.108 +                nread = peer.read(src);
  91.109 +            }
  91.110 +        } while (nread > 0);
  91.111 +
  91.112 +        // write should complete now
  91.113 +        int nsent = r3.get();
  91.114 +        if (nsent <= 0)
  91.115 +            throw new RuntimeException("Should have wrote at least one byte");
  91.116 +    }
  91.117 +
  91.118 +    static interface Task<T> {
  91.119 +        Future<T> run();
  91.120 +    }
  91.121 +
  91.122 +    static <T> Future<T> initiateAndDie(final Task<T> task) {
  91.123 +        final AtomicReference<Future<T>> result = new AtomicReference<Future<T>>();
  91.124 +        Runnable r = new Runnable() {
  91.125 +            public void run() {
  91.126 +                result.set(task.run());
  91.127 +            }
  91.128 +        };
  91.129 +        Thread t = new Thread(r);
  91.130 +        t.start();
  91.131 +        while (t.isAlive()) {
  91.132 +            try {
  91.133 +                t.join();
  91.134 +            } catch (InterruptedException x) {
  91.135 +            }
  91.136 +        }
  91.137 +        return result.get();
  91.138 +    }
  91.139 +}
    92.1 --- a/test/java/nio/channels/AsynchronousSocketChannel/StressLoopback.java	Mon Aug 24 17:26:09 2009 -0700
    92.2 +++ b/test/java/nio/channels/AsynchronousSocketChannel/StressLoopback.java	Tue Sep 01 13:03:09 2009 -0700
    92.3 @@ -22,7 +22,7 @@
    92.4   */
    92.5  
    92.6  /* @test
    92.7 - * @bug 6834246
    92.8 + * @bug 6834246 6842687
    92.9   * @summary Stress test connections through the loopback interface
   92.10   */
   92.11  
   92.12 @@ -114,8 +114,6 @@
   92.13                      exc.printStackTrace();
   92.14                      closeUnchecked(channel);
   92.15                  }
   92.16 -                public void cancelled(Void att) {
   92.17 -                }
   92.18              });
   92.19          }
   92.20  
   92.21 @@ -156,8 +154,6 @@
   92.22                      exc.printStackTrace();
   92.23                      closeUnchecked(channel);
   92.24                  }
   92.25 -                public void cancelled(Void att) {
   92.26 -                }
   92.27              });
   92.28          }
   92.29  
    93.1 --- a/test/java/nio/channels/FileChannel/ReleaseOnCloseDeadlock.java	Mon Aug 24 17:26:09 2009 -0700
    93.2 +++ b/test/java/nio/channels/FileChannel/ReleaseOnCloseDeadlock.java	Tue Sep 01 13:03:09 2009 -0700
    93.3 @@ -22,7 +22,7 @@
    93.4   */
    93.5  
    93.6  /* @test
    93.7 - * @bug 6543863
    93.8 + * @bug 6543863 6842687
    93.9   * @summary Try to cause a deadlock between (Asynchronous)FileChannel.close
   93.10   *   and FileLock.release
   93.11   */
   93.12 @@ -56,7 +56,7 @@
   93.13          AsynchronousFileChannel ch = AsynchronousFileChannel.open(file, READ, WRITE);
   93.14          for (int i=0; i<LOCK_COUNT; i++) {
   93.15              try {
   93.16 -                locks[i] = ch.lock(i, 1, true, null, null).get();
   93.17 +                locks[i] = ch.lock(i, 1, true).get();
   93.18              } catch (InterruptedException x) {
   93.19                  throw new RuntimeException(x);
   93.20              } catch (ExecutionException x) {
    94.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.2 +++ b/test/java/nio/file/Path/CheckPermissions.java	Tue Sep 01 13:03:09 2009 -0700
    94.3 @@ -0,0 +1,695 @@
    94.4 +/*
    94.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    94.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    94.7 + *
    94.8 + * This code is free software; you can redistribute it and/or modify it
    94.9 + * under the terms of the GNU General Public License version 2 only, as
   94.10 + * published by the Free Software Foundation.
   94.11 + *
   94.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   94.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   94.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   94.15 + * version 2 for more details (a copy is included in the LICENSE file that
   94.16 + * accompanied this code).
   94.17 + *
   94.18 + * You should have received a copy of the GNU General Public License version
   94.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   94.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   94.21 + *
   94.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   94.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   94.24 + * have any questions.
   94.25 + */
   94.26 +
   94.27 +/* @test
   94.28 + * @bug 6866804
   94.29 + * @summary Unit test for java.nio.file.Path
   94.30 + * @library ..
   94.31 + */
   94.32 +
   94.33 +import java.nio.ByteBuffer;
   94.34 +import java.nio.file.*;
   94.35 +import java.nio.file.attribute.*;
   94.36 +import java.nio.channels.SeekableByteChannel;
   94.37 +import java.security.Permission;
   94.38 +import java.io.*;
   94.39 +import java.util.*;
   94.40 +
   94.41 +/**
   94.42 + * Checks each method that accesses the file system does the right permission
   94.43 + * check when there is a security manager set.
   94.44 + */
   94.45 +
   94.46 +public class CheckPermissions {
   94.47 +
   94.48 +    static class Checks {
   94.49 +        private List<Permission> permissionsChecked = new ArrayList<Permission>();
   94.50 +        private Set<String>  propertiesChecked = new HashSet<String>();
   94.51 +        private List<String> readsChecked   = new ArrayList<String>();
   94.52 +        private List<String> writesChecked  = new ArrayList<String>();
   94.53 +        private List<String> deletesChecked = new ArrayList<String>();
   94.54 +        private List<String> execsChecked   = new ArrayList<String>();
   94.55 +
   94.56 +        List<Permission> permissionsChecked()  { return permissionsChecked; }
   94.57 +        Set<String> propertiesChecked()        { return propertiesChecked; }
   94.58 +        List<String> readsChecked()            { return readsChecked; }
   94.59 +        List<String> writesChecked()           { return writesChecked; }
   94.60 +        List<String> deletesChecked()          { return deletesChecked; }
   94.61 +        List<String> execsChecked()            { return execsChecked; }
   94.62 +    }
   94.63 +
   94.64 +    static ThreadLocal<Checks> myChecks =
   94.65 +        new ThreadLocal<Checks>() {
   94.66 +            @Override protected Checks initialValue() {
   94.67 +                return null;
   94.68 +            }
   94.69 +        };
   94.70 +
   94.71 +    static void prepare() {
   94.72 +        myChecks.set(new Checks());
   94.73 +    }
   94.74 +
   94.75 +    static void assertCheckPermission(Class<? extends Permission> type,
   94.76 +                                      String name)
   94.77 +    {
   94.78 +        for (Permission perm: myChecks.get().permissionsChecked()) {
   94.79 +            if (type.isInstance(perm) && perm.getName().equals(name))
   94.80 +                return;
   94.81 +        }
   94.82 +        throw new RuntimeException(type.getName() + "\"" + name + "\") not checked");
   94.83 +    }
   94.84 +
   94.85 +    static void assertCheckPropertyAccess(String key) {
   94.86 +        if (!myChecks.get().propertiesChecked().contains(key))
   94.87 +            throw new RuntimeException("Property " + key + " not checked");
   94.88 +    }
   94.89 +
   94.90 +    static void assertChecked(Path file, List<String> list) {
   94.91 +        String s = file.toString();
   94.92 +        for (String f: list) {
   94.93 +            if (f.endsWith(s))
   94.94 +                return;
   94.95 +        }
   94.96 +        throw new RuntimeException("Access not checked");
   94.97 +    }
   94.98 +
   94.99 +    static void assertCheckRead(Path file) {
  94.100 +        assertChecked(file, myChecks.get().readsChecked());
  94.101 +    }
  94.102 +
  94.103 +    static void assertCheckWrite(Path file) {
  94.104 +        assertChecked(file, myChecks.get().writesChecked());
  94.105 +    }
  94.106 +
  94.107 +    static void assertCheckDelete(Path file) {
  94.108 +        assertChecked(file, myChecks.get().deletesChecked());
  94.109 +    }
  94.110 +
  94.111 +    static void assertCheckExec(Path file) {
  94.112 +        assertChecked(file, myChecks.get().execsChecked());
  94.113 +    }
  94.114 +
  94.115 +    static class LoggingSecurityManager extends SecurityManager {
  94.116 +        static void install() {
  94.117 +            System.setSecurityManager(new LoggingSecurityManager());
  94.118 +        }
  94.119 +
  94.120 +        @Override
  94.121 +        public void checkPermission(Permission perm) {
  94.122 +            Checks checks = myChecks.get();
  94.123 +            if (checks != null)
  94.124 +                checks.permissionsChecked().add(perm);
  94.125 +        }
  94.126 +
  94.127 +        @Override
  94.128 +        public void checkPropertyAccess(String key) {
  94.129 +            Checks checks = myChecks.get();
  94.130 +            if (checks != null)
  94.131 +                checks.propertiesChecked().add(key);
  94.132 +        }
  94.133 +
  94.134 +        @Override
  94.135 +        public void checkRead(String file) {
  94.136 +            Checks checks = myChecks.get();
  94.137 +            if (checks != null)
  94.138 +                checks.readsChecked().add(file);
  94.139 +        }
  94.140 +
  94.141 +        @Override
  94.142 +        public void checkWrite(String file) {
  94.143 +            Checks checks = myChecks.get();
  94.144 +            if (checks != null)
  94.145 +                checks.writesChecked().add(file);
  94.146 +        }
  94.147 +
  94.148 +        @Override
  94.149 +        public void checkDelete(String file) {
  94.150 +            Checks checks = myChecks.get();
  94.151 +            if (checks != null)
  94.152 +                checks.deletesChecked().add(file);
  94.153 +        }
  94.154 +
  94.155 +        @Override
  94.156 +        public void checkExec(String file) {
  94.157 +            Checks checks = myChecks.get();
  94.158 +            if (checks != null)
  94.159 +                checks.execsChecked().add(file);
  94.160 +        }
  94.161 +    }
  94.162 +
  94.163 +    static void testBasicFileAttributeView(BasicFileAttributeView view, Path file)
  94.164 +        throws IOException
  94.165 +    {
  94.166 +        prepare();
  94.167 +        view.readAttributes();
  94.168 +        assertCheckRead(file);
  94.169 +
  94.170 +        prepare();
  94.171 +        FileTime now = FileTime.fromMillis(System.currentTimeMillis());
  94.172 +        view.setTimes(null, now, now);
  94.173 +        assertCheckWrite(file);
  94.174 +    }
  94.175 +
  94.176 +    static void testPosixFileAttributeView(PosixFileAttributeView view, Path file)
  94.177 +        throws IOException
  94.178 +    {
  94.179 +        prepare();
  94.180 +        PosixFileAttributes attrs = view.readAttributes();
  94.181 +        assertCheckRead(file);
  94.182 +        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
  94.183 +
  94.184 +        prepare();
  94.185 +        view.setPermissions(attrs.permissions());
  94.186 +        assertCheckWrite(file);
  94.187 +        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
  94.188 +
  94.189 +        prepare();
  94.190 +        view.setOwner(attrs.owner());
  94.191 +        assertCheckWrite(file);
  94.192 +        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
  94.193 +
  94.194 +        prepare();
  94.195 +        view.setOwner(attrs.owner());
  94.196 +        assertCheckWrite(file);
  94.197 +        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
  94.198 +    }
  94.199 +
  94.200 +    public static void main(String[] args) throws IOException {
  94.201 +        Path dir = Paths.get(System.getProperty("test.src", "."));
  94.202 +        Path file = dir.resolve("file1234").createFile();
  94.203 +        try {
  94.204 +            LoggingSecurityManager.install();
  94.205 +
  94.206 +            // -- checkAccess --
  94.207 +
  94.208 +            prepare();
  94.209 +            file.checkAccess();
  94.210 +            assertCheckRead(file);
  94.211 +
  94.212 +            prepare();
  94.213 +            file.checkAccess(AccessMode.READ);
  94.214 +            assertCheckRead(file);
  94.215 +
  94.216 +            prepare();
  94.217 +            file.checkAccess(AccessMode.WRITE);
  94.218 +            assertCheckWrite(file);
  94.219 +
  94.220 +            prepare();
  94.221 +            try {
  94.222 +                file.checkAccess(AccessMode.EXECUTE);
  94.223 +            } catch (AccessDeniedException x) { }
  94.224 +            assertCheckExec(file);
  94.225 +
  94.226 +            prepare();
  94.227 +            try {
  94.228 +                file.checkAccess(AccessMode.READ, AccessMode.WRITE, AccessMode.EXECUTE);
  94.229 +            } catch (AccessDeniedException x) { }
  94.230 +            assertCheckRead(file);
  94.231 +            assertCheckWrite(file);
  94.232 +            assertCheckExec(file);
  94.233 +
  94.234 +            // -- copyTo --
  94.235 +
  94.236 +            Path target = dir.resolve("target1234");
  94.237 +            prepare();
  94.238 +            file.copyTo(target);
  94.239 +            try {
  94.240 +                assertCheckRead(file);
  94.241 +                assertCheckWrite(target);
  94.242 +            } finally {
  94.243 +                target.delete();
  94.244 +            }
  94.245 +
  94.246 +            if (TestUtil.supportsLinks(dir)) {
  94.247 +                Path link = dir.resolve("link1234").createSymbolicLink(file);
  94.248 +                try {
  94.249 +                    prepare();
  94.250 +                    link.copyTo(target, LinkOption.NOFOLLOW_LINKS);
  94.251 +                    try {
  94.252 +                        assertCheckRead(link);
  94.253 +                        assertCheckWrite(target);
  94.254 +                        assertCheckPermission(LinkPermission.class, "symbolic");
  94.255 +                    } finally {
  94.256 +                        target.delete();
  94.257 +                    }
  94.258 +                } finally {
  94.259 +                    link.delete();
  94.260 +                }
  94.261 +            }
  94.262 +
  94.263 +            // -- createDirectory --
  94.264 +
  94.265 +            Path subdir = dir.resolve("subdir1234");
  94.266 +            prepare();
  94.267 +            subdir.createDirectory();
  94.268 +            try {
  94.269 +                assertCheckWrite(subdir);
  94.270 +            } finally {
  94.271 +                subdir.delete();
  94.272 +            }
  94.273 +
  94.274 +            // -- createFile --
  94.275 +
  94.276 +            Path fileToCreate = dir.resolve("file7890");
  94.277 +            prepare();
  94.278 +            try {
  94.279 +                fileToCreate.createFile();
  94.280 +                assertCheckWrite(fileToCreate);
  94.281 +            } finally {
  94.282 +                fileToCreate.delete();
  94.283 +            }
  94.284 +
  94.285 +            // -- createSymbolicLink --
  94.286 +
  94.287 +            if (TestUtil.supportsLinks(dir)) {
  94.288 +                prepare();
  94.289 +                Path link = dir.resolve("link1234").createSymbolicLink(file);
  94.290 +                try {
  94.291 +                    assertCheckWrite(link);
  94.292 +                    assertCheckPermission(LinkPermission.class, "symbolic");
  94.293 +                } finally {
  94.294 +                    link.delete();
  94.295 +                }
  94.296 +            }
  94.297 +
  94.298 +            // -- delete/deleteIfExists --
  94.299 +
  94.300 +            Path fileToDelete = dir.resolve("file7890");
  94.301 +
  94.302 +            fileToDelete.createFile();
  94.303 +            prepare();
  94.304 +            fileToDelete.delete();
  94.305 +            assertCheckDelete(fileToDelete);
  94.306 +
  94.307 +            fileToDelete.createFile();
  94.308 +            prepare();
  94.309 +            fileToDelete.deleteIfExists();
  94.310 +            assertCheckDelete(fileToDelete);
  94.311 +
  94.312 +            // -- exists/notExists --
  94.313 +
  94.314 +            prepare();
  94.315 +            file.exists();
  94.316 +            assertCheckRead(file);
  94.317 +
  94.318 +            prepare();
  94.319 +            file.notExists();
  94.320 +            assertCheckRead(file);
  94.321 +
  94.322 +            // -- getFileStore --
  94.323 +
  94.324 +            prepare();
  94.325 +            file.getFileStore();
  94.326 +            assertCheckRead(file);
  94.327 +            assertCheckPermission(RuntimePermission.class, "getFileStoreAttributes");
  94.328 +
  94.329 +            // -- isSameFile --
  94.330 +
  94.331 +            prepare();
  94.332 +            file.isSameFile(dir);
  94.333 +            assertCheckRead(file);
  94.334 +            assertCheckRead(dir);
  94.335 +
  94.336 +            // -- moveTo --
  94.337 +
  94.338 +            Path target2 = dir.resolve("target1234");
  94.339 +            prepare();
  94.340 +            file.moveTo(target2);
  94.341 +            try {
  94.342 +                assertCheckWrite(file);
  94.343 +                assertCheckWrite(target2);
  94.344 +            } finally {
  94.345 +                // restore file
  94.346 +                target2.moveTo(file);
  94.347 +            }
  94.348 +
  94.349 +            // -- newByteChannel --
  94.350 +
  94.351 +            SeekableByteChannel sbc;
  94.352 +
  94.353 +            prepare();
  94.354 +            sbc = file.newByteChannel();
  94.355 +            try {
  94.356 +                assertCheckRead(file);
  94.357 +            } finally {
  94.358 +                sbc.close();
  94.359 +            }
  94.360 +            prepare();
  94.361 +            sbc = file.newByteChannel(StandardOpenOption.WRITE);
  94.362 +            try {
  94.363 +                assertCheckWrite(file);
  94.364 +            } finally {
  94.365 +                sbc.close();
  94.366 +            }
  94.367 +            prepare();
  94.368 +            sbc = file.newByteChannel(StandardOpenOption.READ, StandardOpenOption.WRITE);
  94.369 +            try {
  94.370 +                assertCheckRead(file);
  94.371 +                assertCheckWrite(file);
  94.372 +            } finally {
  94.373 +                sbc.close();
  94.374 +            }
  94.375 +
  94.376 +            prepare();
  94.377 +            sbc = file.newByteChannel(StandardOpenOption.DELETE_ON_CLOSE);
  94.378 +            try {
  94.379 +                assertCheckRead(file);
  94.380 +                assertCheckDelete(file);
  94.381 +            } finally {
  94.382 +                sbc.close();
  94.383 +            }
  94.384 +            file.createFile(); // restore file
  94.385 +
  94.386 +
  94.387 +            // -- newInputStream/newOutptuStream --
  94.388 +
  94.389 +            prepare();
  94.390 +            InputStream in = file.newInputStream();
  94.391 +            try {
  94.392 +                assertCheckRead(file);
  94.393 +            } finally {
  94.394 +                in.close();
  94.395 +            }
  94.396 +            prepare();
  94.397 +            OutputStream out = file.newOutputStream();
  94.398 +            try {
  94.399 +                assertCheckWrite(file);
  94.400 +            } finally {
  94.401 +                out.close();
  94.402 +            }
  94.403 +
  94.404 +            // -- newDirectoryStream --
  94.405 +
  94.406 +            prepare();
  94.407 +            DirectoryStream<Path> stream = dir.newDirectoryStream();
  94.408 +            try {
  94.409 +                assertCheckRead(dir);
  94.410 +
  94.411 +                if (stream instanceof SecureDirectoryStream<?>) {
  94.412 +                    Path entry;
  94.413 +                    SecureDirectoryStream<Path> sds =
  94.414 +                        (SecureDirectoryStream<Path>)stream;
  94.415 +
  94.416 +                    // newByteChannel
  94.417 +                    entry = file.getName();
  94.418 +                    prepare();
  94.419 +                    sbc = sds.newByteChannel(entry, EnumSet.of(StandardOpenOption.READ));
  94.420 +                    try {
  94.421 +                        assertCheckRead(file);
  94.422 +                    } finally {
  94.423 +                        sbc.close();
  94.424 +                    }
  94.425 +                    prepare();
  94.426 +                    sbc = sds.newByteChannel(entry, EnumSet.of(StandardOpenOption.WRITE));
  94.427 +                    try {
  94.428 +                        assertCheckWrite(file);
  94.429 +                    } finally {
  94.430 +                        sbc.close();
  94.431 +                    }
  94.432 +
  94.433 +                    // deleteFile
  94.434 +                    entry = file.getName();
  94.435 +                    prepare();
  94.436 +                    sds.deleteFile(entry);
  94.437 +                    assertCheckDelete(file);
  94.438 +                    dir.resolve(entry).createFile();  // restore file
  94.439 +
  94.440 +                    // deleteDirectory
  94.441 +                    entry = Paths.get("subdir1234");
  94.442 +                    dir.resolve(entry).createDirectory();
  94.443 +                    prepare();
  94.444 +                    sds.deleteDirectory(entry);
  94.445 +                    assertCheckDelete(dir.resolve(entry));
  94.446 +
  94.447 +                    // move
  94.448 +                    entry = Paths.get("tempname1234");
  94.449 +                    prepare();
  94.450 +                    sds.move(file.getName(), sds, entry);
  94.451 +                    assertCheckWrite(file);
  94.452 +                    assertCheckWrite(dir.resolve(entry));
  94.453 +                    sds.move(entry, sds, file.getName());  // restore file
  94.454 +
  94.455 +                    // newDirectoryStream
  94.456 +                    entry = Paths.get("subdir1234");
  94.457 +                    dir.resolve(entry).createDirectory();
  94.458 +                    try {
  94.459 +                        prepare();
  94.460 +                        sds.newDirectoryStream(entry).close();
  94.461 +                        assertCheckRead(dir.resolve(entry));
  94.462 +                    } finally {
  94.463 +                        dir.resolve(entry).delete();
  94.464 +                    }
  94.465 +
  94.466 +                    // getFileAttributeView to access attributes of directory
  94.467 +                    testBasicFileAttributeView(sds
  94.468 +                        .getFileAttributeView(BasicFileAttributeView.class), dir);
  94.469 +                    testPosixFileAttributeView(sds
  94.470 +                        .getFileAttributeView(PosixFileAttributeView.class), dir);
  94.471 +
  94.472 +                    // getFileAttributeView to access attributes of entry
  94.473 +                    entry = file.getName();
  94.474 +                    testBasicFileAttributeView(sds
  94.475 +                        .getFileAttributeView(entry, BasicFileAttributeView.class), file);
  94.476 +                    testPosixFileAttributeView(sds
  94.477 +                        .getFileAttributeView(entry, PosixFileAttributeView.class), file);
  94.478 +
  94.479 +                } else {
  94.480 +                    System.out.println("SecureDirectoryStream not tested");
  94.481 +                }
  94.482 +
  94.483 +            } finally {
  94.484 +                stream.close();
  94.485 +            }
  94.486 +
  94.487 +            // -- toAbsolutePath --
  94.488 +
  94.489 +            prepare();
  94.490 +            file.getName().toAbsolutePath();
  94.491 +            assertCheckPropertyAccess("user.dir");
  94.492 +
  94.493 +            // -- toRealPath --
  94.494 +
  94.495 +            prepare();
  94.496 +            file.toRealPath(true);
  94.497 +            assertCheckRead(file);
  94.498 +
  94.499 +            prepare();
  94.500 +            file.toRealPath(false);
  94.501 +            assertCheckRead(file);
  94.502 +
  94.503 +            prepare();
  94.504 +            Paths.get(".").toRealPath(true);
  94.505 +            assertCheckPropertyAccess("user.dir");
  94.506 +
  94.507 +            prepare();
  94.508 +            Paths.get(".").toRealPath(false);
  94.509 +            assertCheckPropertyAccess("user.dir");
  94.510 +
  94.511 +            // -- register --
  94.512 +
  94.513 +            WatchService watcher = FileSystems.getDefault().newWatchService();
  94.514 +            try {
  94.515 +                prepare();
  94.516 +                dir.register(watcher, StandardWatchEventKind.ENTRY_DELETE);
  94.517 +                assertCheckRead(dir);
  94.518 +            } finally {
  94.519 +                watcher.close();
  94.520 +            }
  94.521 +
  94.522 +            // -- getAttribute/setAttribute/readAttributes --
  94.523 +
  94.524 +            prepare();
  94.525 +            file.getAttribute("size");
  94.526 +            assertCheckRead(file);
  94.527 +
  94.528 +            prepare();
  94.529 +            file.setAttribute("lastModifiedTime",
  94.530 +                FileTime.fromMillis(System.currentTimeMillis()));
  94.531 +            assertCheckWrite(file);
  94.532 +
  94.533 +            prepare();
  94.534 +            file.readAttributes("*");
  94.535 +            assertCheckRead(file);
  94.536 +
  94.537 +            // -- BasicFileAttributeView --
  94.538 +            testBasicFileAttributeView(file
  94.539 +                .getFileAttributeView(BasicFileAttributeView.class), file);
  94.540 +
  94.541 +            // -- PosixFileAttributeView --
  94.542 +
  94.543 +            {
  94.544 +                PosixFileAttributeView view =
  94.545 +                    file.getFileAttributeView(PosixFileAttributeView.class);
  94.546 +                if (view != null &&
  94.547 +                    file.getFileStore().supportsFileAttributeView(PosixFileAttributeView.class))
  94.548 +                {
  94.549 +                    testPosixFileAttributeView(view, file);
  94.550 +                } else {
  94.551 +                    System.out.println("PosixFileAttributeView not tested");
  94.552 +                }
  94.553 +            }
  94.554 +
  94.555 +            // -- DosFileAttributeView --
  94.556 +
  94.557 +            {
  94.558 +                DosFileAttributeView view =
  94.559 +                    file.getFileAttributeView(DosFileAttributeView.class);
  94.560 +                if (view != null &&
  94.561 +                    file.getFileStore().supportsFileAttributeView(DosFileAttributeView.class))
  94.562 +                {
  94.563 +                    prepare();
  94.564 +                    view.readAttributes();
  94.565 +                    assertCheckRead(file);
  94.566 +
  94.567 +                    prepare();
  94.568 +                    view.setArchive(false);
  94.569 +                    assertCheckWrite(file);
  94.570 +
  94.571 +                    prepare();
  94.572 +                    view.setHidden(false);
  94.573 +                    assertCheckWrite(file);
  94.574 +
  94.575 +                    prepare();
  94.576 +                    view.setReadOnly(false);
  94.577 +                    assertCheckWrite(file);
  94.578 +
  94.579 +                    prepare();
  94.580 +                    view.setSystem(false);
  94.581 +                    assertCheckWrite(file);
  94.582 +                } else {
  94.583 +                    System.out.println("DosFileAttributeView not tested");
  94.584 +                }
  94.585 +            }
  94.586 +
  94.587 +            // -- FileOwnerAttributeView --
  94.588 +
  94.589 +            {
  94.590 +                FileOwnerAttributeView view =
  94.591 +                    file.getFileAttributeView(FileOwnerAttributeView.class);
  94.592 +                if (view != null &&
  94.593 +                    file.getFileStore().supportsFileAttributeView(FileOwnerAttributeView.class))
  94.594 +                {
  94.595 +                    prepare();
  94.596 +                    UserPrincipal owner = view.getOwner();
  94.597 +                    assertCheckRead(file);
  94.598 +                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
  94.599 +
  94.600 +                    prepare();
  94.601 +                    view.setOwner(owner);
  94.602 +                    assertCheckWrite(file);
  94.603 +                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
  94.604 +
  94.605 +                } else {
  94.606 +                    System.out.println("FileOwnerAttributeView not tested");
  94.607 +                }
  94.608 +            }
  94.609 +
  94.610 +            // -- UserDefinedFileAttributeView --
  94.611 +
  94.612 +            {
  94.613 +                UserDefinedFileAttributeView view =
  94.614 +                    file.getFileAttributeView(UserDefinedFileAttributeView.class);
  94.615 +                if (view != null &&
  94.616 +                    file.getFileStore().supportsFileAttributeView(UserDefinedFileAttributeView.class))
  94.617 +                {
  94.618 +                    prepare();
  94.619 +                    view.write("test", ByteBuffer.wrap(new byte[100]));
  94.620 +                    assertCheckWrite(file);
  94.621 +                    assertCheckPermission(RuntimePermission.class,
  94.622 +                                               "accessUserDefinedAttributes");
  94.623 +
  94.624 +                    prepare();
  94.625 +                    view.read("test", ByteBuffer.allocate(100));
  94.626 +                    assertCheckRead(file);
  94.627 +                    assertCheckPermission(RuntimePermission.class,
  94.628 +                                               "accessUserDefinedAttributes");
  94.629 +
  94.630 +                    prepare();
  94.631 +                    view.size("test");
  94.632 +                    assertCheckRead(file);
  94.633 +                    assertCheckPermission(RuntimePermission.class,
  94.634 +                                               "accessUserDefinedAttributes");
  94.635 +
  94.636 +                    prepare();
  94.637 +                    view.list();
  94.638 +                    assertCheckRead(file);
  94.639 +                    assertCheckPermission(RuntimePermission.class,
  94.640 +                                               "accessUserDefinedAttributes");
  94.641 +
  94.642 +                    prepare();
  94.643 +                    view.delete("test");
  94.644 +                    assertCheckWrite(file);
  94.645 +                    assertCheckPermission(RuntimePermission.class,
  94.646 +                                               "accessUserDefinedAttributes");
  94.647 +                } else {
  94.648 +                    System.out.println("UserDefinedFileAttributeView not tested");
  94.649 +                }
  94.650 +            }
  94.651 +
  94.652 +            // -- AclFileAttributeView --
  94.653 +            {
  94.654 +                AclFileAttributeView view =
  94.655 +                    file.getFileAttributeView(AclFileAttributeView.class);
  94.656 +                if (view != null &&
  94.657 +                    file.getFileStore().supportsFileAttributeView(AclFileAttributeView.class))
  94.658 +                {
  94.659 +                    prepare();
  94.660 +                    List<AclEntry> acl = view.getAcl();
  94.661 +                    assertCheckRead(file);
  94.662 +                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
  94.663 +                    prepare();
  94.664 +                    view.setAcl(acl);
  94.665 +                    assertCheckWrite(file);
  94.666 +                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
  94.667 +                } else {
  94.668 +                    System.out.println("AclFileAttributeView not tested");
  94.669 +                }
  94.670 +            }
  94.671 +
  94.672 +            // -- UserPrincipalLookupService
  94.673 +
  94.674 +            UserPrincipalLookupService lookupService =
  94.675 +                FileSystems.getDefault().getUserPrincipalLookupService();
  94.676 +            UserPrincipal owner = Attributes.getOwner(file);
  94.677 +
  94.678 +            prepare();
  94.679 +            lookupService.lookupPrincipalByName(owner.getName());
  94.680 +            assertCheckPermission(RuntimePermission.class,
  94.681 +                                       "lookupUserInformation");
  94.682 +
  94.683 +            try {
  94.684 +                UserPrincipal group = Attributes.readPosixFileAttributes(file).group();
  94.685 +                prepare();
  94.686 +                lookupService.lookupPrincipalByGroupName(group.getName());
  94.687 +                assertCheckPermission(RuntimePermission.class,
  94.688 +                                           "lookupUserInformation");
  94.689 +            } catch (UnsupportedOperationException ignore) {
  94.690 +                System.out.println("lookupPrincipalByGroupName not tested");
  94.691 +            }
  94.692 +
  94.693 +
  94.694 +        } finally {
  94.695 +            file.deleteIfExists();
  94.696 +        }
  94.697 +    }
  94.698 +}
    95.1 --- a/test/java/nio/file/Path/Misc.java	Mon Aug 24 17:26:09 2009 -0700
    95.2 +++ b/test/java/nio/file/Path/Misc.java	Tue Sep 01 13:03:09 2009 -0700
    95.3 @@ -22,7 +22,7 @@
    95.4   */
    95.5  
    95.6  /* @test
    95.7 - * @bug 4313887 6838333 6866804
    95.8 + * @bug 4313887 6838333 6867101
    95.9   * @summary Unit test for java.nio.file.Path for miscellenous methods not
   95.10   *   covered by other tests
   95.11   * @library ..
    96.1 --- a/test/java/nio/file/PathMatcher/Basic.java	Mon Aug 24 17:26:09 2009 -0700
    96.2 +++ b/test/java/nio/file/PathMatcher/Basic.java	Tue Sep 01 13:03:09 2009 -0700
    96.3 @@ -22,7 +22,7 @@
    96.4   */
    96.5  
    96.6  /* @test
    96.7 - * @bug 4313887
    96.8 + * @bug 4313887 6866397
    96.9   * @summary Unit test for java.nio.file.PathMatcher
   96.10   */
   96.11  
   96.12 @@ -68,6 +68,20 @@
   96.13          }
   96.14      }
   96.15  
   96.16 +    static void assertRegExMatch(String path, String pattern) {
   96.17 +        System.out.format("Test regex pattern: %s", pattern);
   96.18 +        Path file = Paths.get(path);
   96.19 +        boolean matched =  file.getFileSystem()
   96.20 +                               .getPathMatcher("regex:" + pattern).matches(file);
   96.21 +        if (matched) {
   96.22 +            System.out.println(" OKAY");
   96.23 +        } else {
   96.24 +            System.out.println(" ==> UNEXPECTED RESULT!");
   96.25 +            failures++;
   96.26 +        }
   96.27 +    }
   96.28 +
   96.29 +
   96.30      public static void main(String[] args) {
   96.31          // basic
   96.32          assertMatch("foo.html", "foo.html");
   96.33 @@ -140,21 +154,13 @@
   96.34              assertMatch("one*two", "one\\*two");
   96.35          }
   96.36  
   96.37 +        // regex syntax
   96.38 +        assertRegExMatch("foo.html", ".*\\.html");
   96.39  
   96.40 -
   96.41 -        // regex syntax
   96.42 -        {
   96.43 -            String pattern = ".*\\.html";
   96.44 -            System.out.format("Test regex pattern: %s", pattern);
   96.45 -            Path file = Paths.get("foo.html");
   96.46 -            boolean matched =  file.getFileSystem()
   96.47 -                .getPathMatcher("regex:" + pattern).matches(file);
   96.48 -            if (matched) {
   96.49 -                System.out.println(" OKAY");
   96.50 -            } else {
   96.51 -                System.out.println(" ==> UNEXPECTED RESULT!");
   96.52 -                failures++;
   96.53 -            }
   96.54 +        if (System.getProperty("os.name").startsWith("Windows")) {
   96.55 +            assertRegExMatch("foo012", "foo\\d+");
   96.56 +            assertRegExMatch("fo o", "fo\\so");
   96.57 +            assertRegExMatch("foo", "\\w+");
   96.58          }
   96.59  
   96.60          // unknown syntax
    97.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.2 +++ b/test/java/util/prefs/CommentsInXml.java	Tue Sep 01 13:03:09 2009 -0700
    97.3 @@ -0,0 +1,60 @@
    97.4 +/*
    97.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    97.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    97.7 + *
    97.8 + * This code is free software; you can redistribute it and/or modify it
    97.9 + * under the terms of the GNU General Public License version 2 only, as
   97.10 + * published by the Free Software Foundation.
   97.11 + *
   97.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   97.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   97.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   97.15 + * version 2 for more details (a copy is included in the LICENSE file that
   97.16 + * accompanied this code).
   97.17 + *
   97.18 + * You should have received a copy of the GNU General Public License version
   97.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   97.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   97.21 + *
   97.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   97.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   97.24 + * have any questions.
   97.25 + */
   97.26 +
   97.27 +/*
   97.28 + * @test
   97.29 + * @bug 4619564
   97.30 + * @summary XMl Comments in Preferences File lead to ClassCastException
   97.31 + * @author kladko
   97.32 + */
   97.33 +
   97.34 +import java.io.*;
   97.35 +import java.util.prefs.*;
   97.36 +
   97.37 +public class CommentsInXml {
   97.38 +
   97.39 +    public static void main(String[] argv) throws Exception {
   97.40 +
   97.41 +        ByteArrayOutputStream bos = new ByteArrayOutputStream();
   97.42 +
   97.43 +        bos.write(new String(
   97.44 +            "<!DOCTYPE preferences SYSTEM                          " +
   97.45 +            "\"http://java.sun.com/dtd/preferences.dtd\">          " +
   97.46 +            "<preferences EXTERNAL_XML_VERSION=\"1.0\">            " +
   97.47 +            "  <root type=\"user\">                                " +
   97.48 +            "    <map>                                             " +
   97.49 +            "    </map>                                            " +
   97.50 +            "    <node name=\"hlrAgent\"> <!-- HLR Agent -->       " +
   97.51 +            "      <map>                                           " +
   97.52 +            "        <entry key=\"agentName\" value=\"HLRAgent\" />" +
   97.53 +            "      </map>                                          " +
   97.54 +            "    </node>                                           " +
   97.55 +            "  </root>                                             " +
   97.56 +            "</preferences>                                        "
   97.57 +        ).getBytes());
   97.58 +
   97.59 +        Preferences ur = Preferences.userRoot();
   97.60 +        ur.importPreferences(new ByteArrayInputStream(bos.toByteArray()));
   97.61 +        ur.node("hlrAgent").removeNode(); // clean
   97.62 +    }
   97.63 +}
    98.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.2 +++ b/test/java/util/prefs/ConflictInFlush.java	Tue Sep 01 13:03:09 2009 -0700
    98.3 @@ -0,0 +1,49 @@
    98.4 +/*
    98.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    98.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    98.7 + *
    98.8 + * This code is free software; you can redistribute it and/or modify it
    98.9 + * under the terms of the GNU General Public License version 2 only, as
   98.10 + * published by the Free Software Foundation.
   98.11 + *
   98.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   98.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   98.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   98.15 + * version 2 for more details (a copy is included in the LICENSE file that
   98.16 + * accompanied this code).
   98.17 + *
   98.18 + * You should have received a copy of the GNU General Public License version
   98.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   98.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   98.21 + *
   98.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   98.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   98.24 + * have any questions.
   98.25 + */
   98.26 +
   98.27 +/*
   98.28 + * @test
   98.29 + * @bug 4703132
   98.30 + * @summary flush() throws an IllegalStateException on a removed node
   98.31 + * @author Sucheta Dambalkar
   98.32 + */
   98.33 +
   98.34 +import java.util.prefs.*;
   98.35 +
   98.36 +public final class ConflictInFlush{
   98.37 +
   98.38 +    public static void main(String args[]) {
   98.39 +        Preferences root = Preferences.userRoot();
   98.40 +        try {
   98.41 +            Preferences node = root.node("1/2/3");
   98.42 +            node.flush();
   98.43 +            System.out.println("Node "+node+" has been created");
   98.44 +            System.out.println("Removing node "+node);
   98.45 +            node.removeNode();
   98.46 +            node.flush();
   98.47 +        }catch (BackingStoreException bse){
   98.48 +            bse.printStackTrace();
   98.49 +        }
   98.50 +
   98.51 +    }
   98.52 +}
    99.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.2 +++ b/test/java/util/prefs/ExportNode.java	Tue Sep 01 13:03:09 2009 -0700
    99.3 @@ -0,0 +1,53 @@
    99.4 +/*
    99.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    99.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    99.7 + *
    99.8 + * This code is free software; you can redistribute it and/or modify it
    99.9 + * under the terms of the GNU General Public License version 2 only, as
   99.10 + * published by the Free Software Foundation.
   99.11 + *
   99.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   99.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   99.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   99.15 + * version 2 for more details (a copy is included in the LICENSE file that
   99.16 + * accompanied this code).
   99.17 + *
   99.18 + * You should have received a copy of the GNU General Public License version
   99.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   99.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   99.21 + *
   99.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   99.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   99.24 + * have any questions.
   99.25 + */
   99.26 +
   99.27 +
   99.28 +/*
   99.29 + * @test
   99.30 + * @bug 4387136 4947349
   99.31 + * @summary Due to a bug in XMLSupport.putPreferencesInXml(...),
   99.32 + *          node's keys would not get exported.
   99.33 + * @author Konstantin Kladko
   99.34 + */
   99.35 +import java.util.prefs.*;
   99.36 +import java.io.*;
   99.37 +
   99.38 +public class ExportNode {
   99.39 +    public static void main(String[] args) throws
   99.40 +                                            BackingStoreException, IOException {
   99.41 +            Preferences N1 = Preferences.userRoot().node("ExportNodeTest1");
   99.42 +            N1.put("ExportNodeTestName1","ExportNodeTestValue1");
   99.43 +            Preferences N2 = N1.node("ExportNodeTest2");
   99.44 +            N2.put("ExportNodeTestName2","ExportNodeTestValue2");
   99.45 +            ByteArrayOutputStream exportStream = new ByteArrayOutputStream();
   99.46 +            N2.exportNode(exportStream);
   99.47 +
   99.48 +            // Removal of preference node should always succeed on Solaris/Linux
   99.49 +            // by successfully acquiring the appropriate file lock (4947349)
   99.50 +            N1.removeNode();
   99.51 +
   99.52 +            if (((exportStream.toString()).lastIndexOf("ExportNodeTestName2")== -1) ||
   99.53 +               ((exportStream.toString()).lastIndexOf("ExportNodeTestName1")!= -1)) {
   99.54 +            }
   99.55 +   }
   99.56 +}
   100.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   100.2 +++ b/test/java/util/prefs/ExportSubtree.java	Tue Sep 01 13:03:09 2009 -0700
   100.3 @@ -0,0 +1,95 @@
   100.4 +/*
   100.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   100.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   100.7 + *
   100.8 + * This code is free software; you can redistribute it and/or modify it
   100.9 + * under the terms of the GNU General Public License version 2 only, as
  100.10 + * published by the Free Software Foundation.
  100.11 + *
  100.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  100.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  100.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  100.15 + * version 2 for more details (a copy is included in the LICENSE file that
  100.16 + * accompanied this code).
  100.17 + *
  100.18 + * You should have received a copy of the GNU General Public License version
  100.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  100.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  100.21 + *
  100.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  100.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
  100.24 + * have any questions.
  100.25 + */
  100.26 +
  100.27 +
  100.28 +/* @test
  100.29 +   @bug 6203576 4700020
  100.30 +   @summary checks if the output of exportSubtree() is identical to
  100.31 +            the output from previous release.
  100.32 + */
  100.33 +
  100.34 +import java.io.*;
  100.35 +import java.util.prefs.*;
  100.36 +
  100.37 +public class ExportSubtree {
  100.38 +   public static void main(String[] args) throws Exception {
  100.39 +      try
  100.40 +      {
  100.41 +          //File f = new File(System.getProperty("test.src", "."), "TestPrefs.xml");
  100.42 +          ByteArrayInputStream bais = new ByteArrayInputStream(importPrefs.getBytes("utf-8"));
  100.43 +          Preferences.importPreferences(bais);
  100.44 +          ByteArrayOutputStream baos = new ByteArrayOutputStream();
  100.45 +          Preferences.userRoot().node("testExportSubtree").exportSubtree(baos);
  100.46 +          Preferences.userRoot().node("testExportSubtree").removeNode();
  100.47 +          if (!expectedResult.equals(baos.toString())) {
  100.48 +              //System.out.print(baos.toString());
  100.49 +              //System.out.print(expectedResult);
  100.50 +              throw new IOException("exportSubtree does not output expected result");
  100.51 +          }
  100.52 +      }
  100.53 +      catch( Exception e ) {
  100.54 +         e.printStackTrace();
  100.55 +      }
  100.56 +   }
  100.57 +
  100.58 +   static String ls = System.getProperty("line.separator");
  100.59 +   static String importPrefs =
  100.60 +       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  100.61 +        + "<!DOCTYPE preferences SYSTEM \"http://java.sun.com/dtd/preferences.dtd\">"
  100.62 +        + "<preferences EXTERNAL_XML_VERSION=\"1.0\">"
  100.63 +        + "  <root type=\"user\">"
  100.64 +        + "    <map>"
  100.65 +        + "      <entry key=\"key1\" value=\"value1\"/>"
  100.66 +        + "    </map>"
  100.67 +        + "    <node name=\"testExportSubtree\">"
  100.68 +        + "      <map>"
  100.69 +        + "        <entry key=\"key2\" value=\"value2\"/>"
  100.70 +        + "      </map>"
  100.71 +        + "      <node name=\"test\">"
  100.72 +        + "        <map>"
  100.73 +        + "          <entry key=\"key3\" value=\"value3\"/>"
  100.74 +        + "        </map>"
  100.75 +        + "      </node>"
  100.76 +        + "    </node>"
  100.77 +        + "  </root>"
  100.78 +        + "</preferences>";
  100.79 +
  100.80 +   static String expectedResult =
  100.81 +       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  100.82 +        + ls    +  "<!DOCTYPE preferences SYSTEM \"http://java.sun.com/dtd/preferences.dtd\">"
  100.83 +        + ls    +  "<preferences EXTERNAL_XML_VERSION=\"1.0\">"
  100.84 +        + ls    +  "  <root type=\"user\">"
  100.85 +        + ls    +  "    <map/>"
  100.86 +        + ls    +  "    <node name=\"testExportSubtree\">"
  100.87 +        + ls    +  "      <map>"
  100.88 +        + ls    +  "        <entry key=\"key2\" value=\"value2\"/>"
  100.89 +        + ls    +  "      </map>"
  100.90 +        + ls    +  "      <node name=\"test\">"
  100.91 +        + ls    +  "        <map>"
  100.92 +        + ls    +  "          <entry key=\"key3\" value=\"value3\"/>"
  100.93 +        + ls    +  "        </map>"
  100.94 +        + ls    +  "      </node>"
  100.95 +        + ls    +  "    </node>"
  100.96 +        + ls    +  "  </root>"
  100.97 +        + ls    +  "</preferences>"     + ls;
  100.98 +}
   101.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.2 +++ b/test/java/util/prefs/PrefsSpi.java	Tue Sep 01 13:03:09 2009 -0700
   101.3 @@ -0,0 +1,44 @@
   101.4 +/*
   101.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   101.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   101.7 + *
   101.8 + * This code is free software; you can redistribute it and/or modify it
   101.9 + * under the terms of the GNU General Public License version 2 only, as
  101.10 + * published by the Free Software Foundation.
  101.11 + *
  101.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  101.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  101.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  101.15 + * version 2 for more details (a copy is included in the LICENSE file that
  101.16 + * accompanied this code).
  101.17 + *
  101.18 + * You should have received a copy of the GNU General Public License version
  101.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  101.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  101.21 + *
  101.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  101.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
  101.24 + * have any questions.
  101.25 + */
  101.26 +
  101.27 +
  101.28 +import java.util.prefs.Preferences;
  101.29 +
  101.30 +/*
  101.31 + * main class used by regtest PrefsSpi.sh
  101.32 + */
  101.33 +public class PrefsSpi {
  101.34 +
  101.35 +    public static void main (String[] args) throws Exception {
  101.36 +        if (args.length != 1)
  101.37 +            throw new Exception("Usage: java PrefsSpi REGEXP");
  101.38 +
  101.39 +        String className = Preferences.userRoot().getClass().getName();
  101.40 +        System.out.printf("className=%s%n", className);
  101.41 +
  101.42 +        if (! className.matches(args[0]))
  101.43 +            throw new Exception("Preferences class name \"" + className
  101.44 +                                + "\" does not match regular expression \""
  101.45 +                                + args[0] + "\".");
  101.46 +    }
  101.47 +}
   102.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.2 +++ b/test/java/util/prefs/PrefsSpi.sh	Tue Sep 01 13:03:09 2009 -0700
   102.3 @@ -0,0 +1,100 @@
   102.4 +#!/bin/sh
   102.5 +
   102.6 +#
   102.7 +# Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   102.8 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   102.9 +#
  102.10 +# This code is free software; you can redistribute it and/or modify it
  102.11 +# under the terms of the GNU General Public License version 2 only, as
  102.12 +# published by the Free Software Foundation.
  102.13 +#
  102.14 +# This code is distributed in the hope that it will be useful, but WITHOUT
  102.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  102.16 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  102.17 +# version 2 for more details (a copy is included in the LICENSE file that
  102.18 +# accompanied this code).
  102.19 +#
  102.20 +# You should have received a copy of the GNU General Public License version
  102.21 +# 2 along with this work; if not, write to the Free Software Foundation,
  102.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  102.23 +#
  102.24 +# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  102.25 +# CA 95054 USA or visit www.sun.com if you need additional information or
  102.26 +# have any questions.
  102.27 +#
  102.28 +
  102.29 +# @test
  102.30 +# @bug 4991526 6514993
  102.31 +# @summary Unit test for Preferences jar providers
  102.32 +#
  102.33 +# @build PrefsSpi
  102.34 +# @run shell PrefsSpi.sh
  102.35 +# @author Martin Buchholz
  102.36 +
  102.37 +# Command-line usage: sh PrefsSpi.sh /path/to/build
  102.38 +
  102.39 +if [ -z "$TESTJAVA" ]; then
  102.40 +    if [ $# -lt 1 ]; then exit 1; fi
  102.41 +    TESTJAVA="$1"; shift
  102.42 +    TESTSRC="`pwd`"
  102.43 +    TESTCLASSES="`pwd`"
  102.44 +fi
  102.45 +
  102.46 + java="$TESTJAVA/bin/java"
  102.47 +javac="$TESTJAVA/bin/javac"
  102.48 +  jar="$TESTJAVA/bin/jar"
  102.49 +
  102.50 +Die() { printf "%s\n" "$*"; exit 1; }
  102.51 +
  102.52 +Sys() {
  102.53 +    printf "%s\n" "$*"; "$@"; rc="$?";
  102.54 +    test "$rc" -eq 0 || Die "Command \"$*\" failed with exitValue $rc";
  102.55 +}
  102.56 +
  102.57 +cat > StubPreferences.java <<'EOF'
  102.58 +import java.util.prefs.*;
  102.59 +
  102.60 +public class StubPreferences extends AbstractPreferences {
  102.61 +    public StubPreferences() { super(null, ""); }
  102.62 +    public String              getSpi(String x)           { return null; }
  102.63 +    public void                putSpi(String x, String y) { }
  102.64 +    public void                removeSpi(String x)        { }
  102.65 +    public AbstractPreferences childSpi(String x)         { return null; }
  102.66 +    public void                removeNodeSpi()            { }
  102.67 +    public String[]            keysSpi()                  { return null; }
  102.68 +    public String[]            childrenNamesSpi()         { return null; }
  102.69 +    public void                syncSpi()                  { }
  102.70 +    public void                flushSpi()                 { }
  102.71 +}
  102.72 +EOF
  102.73 +
  102.74 +cat > StubPreferencesFactory.java <<'EOF'
  102.75 +import java.util.prefs.*;
  102.76 +
  102.77 +public class StubPreferencesFactory implements PreferencesFactory {
  102.78 +    public Preferences userRoot()   { return new StubPreferences(); }
  102.79 +    public Preferences systemRoot() { return new StubPreferences(); }
  102.80 +}
  102.81 +EOF
  102.82 +
  102.83 +Sys rm -rf jarDir extDir
  102.84 +Sys mkdir -p jarDir/META-INF/services extDir
  102.85 +echo "StubPreferencesFactory" \
  102.86 +  > "jarDir/META-INF/services/java.util.prefs.PreferencesFactory"
  102.87 +Sys "$javac" -d jarDir StubPreferencesFactory.java StubPreferences.java
  102.88 +
  102.89 +(cd jarDir && "$jar" "cf" "../extDir/PrefsSpi.jar" ".")
  102.90 +
  102.91 +case "`uname`" in Windows*|CYGWIN* ) CPS=';';; *) CPS=':';; esac
  102.92 +
  102.93 +Sys "$java" "-cp" "$TESTCLASSES${CPS}extDir/PrefsSpi.jar" \
  102.94 +    -Djava.util.prefs.PreferencesFactory=StubPreferencesFactory \
  102.95 +    PrefsSpi "StubPreferences"
  102.96 +Sys "$java" "-cp" "$TESTCLASSES" \
  102.97 +    PrefsSpi "java.util.prefs.*"
  102.98 +Sys "$java" "-cp" "$TESTCLASSES${CPS}extDir/PrefsSpi.jar" \
  102.99 +    PrefsSpi "StubPreferences"
 102.100 +Sys "$java" "-cp" "$TESTCLASSES" "-Djava.ext.dirs=extDir" \
 102.101 +    PrefsSpi "StubPreferences"
 102.102 +
 102.103 +rm -rf jarDir extDir
   103.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.2 +++ b/test/java/util/prefs/RemoveReadOnlyNode.java	Tue Sep 01 13:03:09 2009 -0700
   103.3 @@ -0,0 +1,63 @@
   103.4 +/*
   103.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   103.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   103.7 + *
   103.8 + * This code is free software; you can redistribute it and/or modify it
   103.9 + * under the terms of the GNU General Public License version 2 only, as
  103.10 + * published by the Free Software Foundation.
  103.11 + *
  103.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  103.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  103.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  103.15 + * version 2 for more details (a copy is included in the LICENSE file that
  103.16 + * accompanied this code).
  103.17 + *
  103.18 + * You should have received a copy of the GNU General Public License version
  103.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  103.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  103.21 + *
  103.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  103.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
  103.24 + * have any questions.
  103.25 + */
  103.26 +
  103.27 +
  103.28 +/* @test
  103.29 +   @bug 6178148
  103.30 +   @summary check if wrong exception gets thrown if one of the child
  103.31 +            nodes is readonly on underlying filesystem when node is
  103.32 +            being removed.
  103.33 + */
  103.34 +
  103.35 +import java.io.*;
  103.36 +import java.util.prefs.*;
  103.37 +
  103.38 +public class RemoveReadOnlyNode {
  103.39 +    public static void main(String[] args) throws Exception {
  103.40 +        String osName = System.getProperty("os.name");
  103.41 +        if (osName.startsWith("Windows"))
  103.42 +            return;
  103.43 +        Preferences root = Preferences.userRoot();
  103.44 +        Preferences node1 = root.node("node1");
  103.45 +        Preferences node1A = node1.node("node1A");
  103.46 +        Preferences node1B = node1.node("node1B");
  103.47 +        node1B.put("mykey", "myvalue");
  103.48 +        node1.flush();
  103.49 +        String node1BDirName = System.getProperty("user.home")
  103.50 +            + "/.java/.userPrefs"
  103.51 +            + "/node1/node1B";
  103.52 +        File node1BDir = new File(node1BDirName);
  103.53 +        node1BDir.setReadOnly();
  103.54 +        try {
  103.55 +            node1.removeNode();
  103.56 +        }
  103.57 +        catch (BackingStoreException ex) {
  103.58 +            //expected exception
  103.59 +        } finally {
  103.60 +            Runtime.getRuntime().exec("chmod 755 " + node1BDirName).waitFor();
  103.61 +            try {
  103.62 +                node1.removeNode();
  103.63 +            } catch (Exception e) {}
  103.64 +        }
  103.65 +    }
  103.66 +}
   104.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   104.2 +++ b/test/java/util/prefs/RemoveUnregedListener.java	Tue Sep 01 13:03:09 2009 -0700
   104.3 @@ -0,0 +1,63 @@
   104.4 +/*
   104.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   104.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   104.7 + *
   104.8 + * This code is free software; you can redistribute it and/or modify it
   104.9 + * under the terms of the GNU General Public License version 2 only, as
  104.10 + * published by the Free Software Foundation.
  104.11 + *
  104.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  104.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  104.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  104.15 + * version 2 for more details (a copy is included in the LICENSE file that
  104.16 + * accompanied this code).
  104.17 + *
  104.18 + * You should have received a copy of the GNU General Public License version
  104.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  104.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  104.21 + *
  104.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  104.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
  104.24 + * have any questions.
  104.25 + */
  104.26 +
  104.27 +
  104.28 +/* @test
  104.29 + * @bug 4705094
  104.30 + * @summary Checks if correct exception gets thrown when removing an
  104.31 + *          unregistered NodeChangeListener .
  104.32 + */
  104.33 +
  104.34 +import java.util.prefs.*;
  104.35 +import java.util.*;
  104.36 +
  104.37 +public class RemoveUnregedListener {
  104.38 +    public static void main(String[] args) throws Exception {
  104.39 +        Preferences userRoot = null;
  104.40 +        Preferences N1 = null;
  104.41 +        NodeChangeListenerTestAdd ncl = new NodeChangeListenerTestAdd();
  104.42 +        NodeChangeListenerTestAdd ncl2 = new NodeChangeListenerTestAdd();
  104.43 +        NodeChangeListenerTestAdd ncl3 = new NodeChangeListenerTestAdd();
  104.44 +        try {
  104.45 +            userRoot = Preferences.userRoot();
  104.46 +            N1 = userRoot.node("N1");
  104.47 +            userRoot.flush();
  104.48 +
  104.49 +            //add ncl nc2
  104.50 +            N1.addNodeChangeListener(ncl);
  104.51 +            N1.addNodeChangeListener(ncl2);
  104.52 +            N1.removeNodeChangeListener(ncl3);
  104.53 +            throw new RuntimeException();
  104.54 +        } catch (IllegalArgumentException iae) {
  104.55 +            System.out.println("Test Passed!");
  104.56 +        } catch (Exception e) {
  104.57 +            System.out.println("Test Failed");
  104.58 +            throw e;
  104.59 +        }
  104.60 +    }
  104.61 +
  104.62 +}
  104.63 +class NodeChangeListenerTestAdd implements NodeChangeListener {
  104.64 +    public void childAdded(NodeChangeEvent evt) {}
  104.65 +    public void childRemoved(NodeChangeEvent evt) {}
  104.66 +}
   105.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   105.2 +++ b/test/java/util/prefs/SerializeExceptions.java	Tue Sep 01 13:03:09 2009 -0700
   105.3 @@ -0,0 +1,48 @@
   105.4 +/*
   105.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   105.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   105.7 + *
   105.8 + * This code is free software; you can redistribute it and/or modify it
   105.9 + * under the terms of the GNU General Public License version 2 only, as
  105.10 + * published by the Free Software Foundation.
  105.11 + *
  105.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  105.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  105.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  105.15 + * version 2 for more details (a copy is included in the LICENSE file that
  105.16 + * accompanied this code).
  105.17 + *
  105.18 + * You should have received a copy of the GNU General Public License version
  105.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  105.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  105.21 + *
  105.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  105.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
  105.24 + * have any questions.
  105.25 + */
  105.26 +
  105.27 +
  105.28 +/*
  105.29 + * @test
  105.30 + * @bug     4811356
  105.31 + * @summary Prefs exceptions were unintentionally not serializable
  105.32 + * @author  Josh Bloch
  105.33 + */
  105.34 +
  105.35 +import java.util.prefs.*;
  105.36 +import java.io.*;
  105.37 +
  105.38 +public class SerializeExceptions {
  105.39 +    public static void main(String args[]) throws Exception {
  105.40 +        test(new BackingStoreException("Hi"));
  105.41 +        test(new InvalidPreferencesFormatException("Mom!"));
  105.42 +    }
  105.43 +
  105.44 +    static void test(Object o) throws IOException {
  105.45 +        ByteArrayOutputStream bos = new ByteArrayOutputStream();
  105.46 +        ObjectOutputStream out = new ObjectOutputStream(bos);
  105.47 +        out.writeObject(o);
  105.48 +        out.flush();
  105.49 +        out.close();
  105.50 +    }
  105.51 +}
   106.1 --- a/test/sun/nio/cs/FindCanEncodeBugs.java	Mon Aug 24 17:26:09 2009 -0700
   106.2 +++ b/test/sun/nio/cs/FindCanEncodeBugs.java	Tue Sep 01 13:03:09 2009 -0700
   106.3 @@ -22,7 +22,7 @@
   106.4   */
   106.5  
   106.6  /* @test
   106.7 -   @bug 5066863 5066867 5066874 5066879 5066884 5066887 5065777
   106.8 +   @bug 5066863 5066867 5066874 5066879 5066884 5066887 5065777 6730652
   106.9     @summary canEncode() false iff encode() throws CharacterCodingException
  106.10     @run main/timeout=1200 FindCanEncodeBugs
  106.11     @author Martin Buchholz
  106.12 @@ -52,9 +52,7 @@
  106.13              String csn = e.getKey();
  106.14              Charset cs = e.getValue();
  106.15  
  106.16 -            if (! cs.canEncode() ||
  106.17 -                csn.matches("x-COMPOUND_TEXT")   ||
  106.18 -                csn.matches("x-ISO-2022-CN-CNS"))  // ISO2022_CN_CNS supports less
  106.19 +            if (! cs.canEncode() || csn.matches("x-COMPOUND_TEXT"))
  106.20                  continue;
  106.21  
  106.22              //System.out.println(csn);
   107.1 --- a/test/sun/security/ec/TestEC.java	Mon Aug 24 17:26:09 2009 -0700
   107.2 +++ b/test/sun/security/ec/TestEC.java	Tue Sep 01 13:03:09 2009 -0700
   107.3 @@ -53,7 +53,7 @@
   107.4          long start = System.currentTimeMillis();
   107.5          new TestECDH().main(p);
   107.6          new TestECDSA().main(p);
   107.7 -        //new TestCurves().main(p);
   107.8 +        new TestCurves().main(p);
   107.9          new TestKeyFactory().main(p);
  107.10          new TestECGenSpec().main(p);
  107.11          new ReadPKCS12().main(p);
   108.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   108.2 +++ b/test/sun/security/krb5/ktab/HighestKvno.java	Tue Sep 01 13:03:09 2009 -0700
   108.3 @@ -0,0 +1,235 @@
   108.4 +/*
   108.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   108.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   108.7 + *
   108.8 + * This code is free software; you can redistribute it and/or modify it
   108.9 + * under the terms of the GNU General Public License version 2 only, as
  108.10 + * published by the Free Software Foundation.
  108.11 + *
  108.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  108.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  108.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  108.15 + * version 2 for more details (a copy is included in the LICENSE file that
  108.16 + * accompanied this code).
  108.17 + *
  108.18 + * You should have received a copy of the GNU General Public License version
  108.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  108.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  108.21 + *
  108.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  108.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
  108.24 + * have any questions.
  108.25 + */
  108.26 +/*
  108.27 + * @test
  108.28 + * @bug 6867665
  108.29 + * @bug 6875033
  108.30 + * @summary Problem with keytabs with multiple kvno's (key versions)
  108.31 + */
  108.32 +
  108.33 +import sun.security.krb5.internal.ktab.*;
  108.34 +import sun.security.krb5.*;
  108.35 +import java.io.File;
  108.36 +import java.io.FileOutputStream;
  108.37 +
  108.38 +public class HighestKvno {
  108.39 +
  108.40 +    public static void main(String[] args) throws Exception {
  108.41 +        // kt is a keytab including these entries:
  108.42 +        //
  108.43 +        // me@MAD.LOCAL: Type: 3, KVNO: 4
  108.44 +        // me@MAD.LOCAL: Type: 23, KVNO: 4
  108.45 +        // me@MAD.LOCAL: Type: 16, KVNO: 4
  108.46 +        // me@MAD.LOCAL: Type: 1, KVNO: 5
  108.47 +        // me@MAD.LOCAL: Type: 17, KVNO: 5
  108.48 +        // me@MAD.LOCAL: Type: 18, KVNO: 5
  108.49 +        // me@MAD.LOCAL: Type: 1, KVNO: 3
  108.50 +        // me@MAD.LOCAL: Type: 17, KVNO: 3
  108.51 +        // me@MAD.LOCAL: Type: 18, KVNO: 3
  108.52 +        // he@MAD.LOCAL: Type: 1, KVNO: 1
  108.53 +        // he@MAD.LOCAL: Type: 17, KVNO: 1
  108.54 +        // he@MAD.LOCAL: Type: 18, KVNO: 1
  108.55 +        //
  108.56 +        // This file is created with these steps:
  108.57 +        // 1. Modify JRE's Ktab.java so that adding new entries
  108.58 +        //    does not remove the old one.
  108.59 +        // 2. Run the modified Ktab to create 4 sets of keys
  108.60 +        // 3. Manually hex edit the KVNO as above
  108.61 +
  108.62 +        byte[] kt = {
  108.63 +            (byte)0x05, (byte)0x02, (byte)0x00, (byte)0x00,
  108.64 +            (byte)0x00, (byte)0x26, (byte)0x00, (byte)0x01,
  108.65 +            (byte)0x00, (byte)0x09, (byte)0x4D, (byte)0x41,
  108.66 +            (byte)0x44, (byte)0x2E, (byte)0x4C, (byte)0x4F,
  108.67 +            (byte)0x43, (byte)0x41, (byte)0x4C, (byte)0x00,
  108.68 +            (byte)0x02, (byte)0x6D, (byte)0x65, (byte)0x00,
  108.69 +            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x4A,
  108.70 +            (byte)0x79, (byte)0x45, (byte)0xCD, (byte)0x04,
  108.71 +            (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x08,
  108.72 +            (byte)0xE6, (byte)0xB0, (byte)0x07, (byte)0xA8,
  108.73 +            (byte)0x5B, (byte)0xF8, (byte)0x73, (byte)0xAD,
  108.74 +            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x2E,
  108.75 +            (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09,
  108.76 +            (byte)0x4D, (byte)0x41, (byte)0x44, (byte)0x2E,
  108.77 +            (byte)0x4C, (byte)0x4F, (byte)0x43, (byte)0x41,
  108.78 +            (byte)0x4C, (byte)0x00, (byte)0x02, (byte)0x6D,
  108.79 +            (byte)0x65, (byte)0x00, (byte)0x00, (byte)0x00,
  108.80 +            (byte)0x00, (byte)0x4A, (byte)0x79, (byte)0x45,
  108.81 +            (byte)0xCD, (byte)0x04, (byte)0x00, (byte)0x17,
  108.82 +            (byte)0x00, (byte)0x10, (byte)0x50, (byte)0x92,
  108.83 +            (byte)0x01, (byte)0x6B, (byte)0xCF, (byte)0x5A,
  108.84 +            (byte)0x2A, (byte)0x7A, (byte)0x4F, (byte)0xE8,
  108.85 +            (byte)0x39, (byte)0xD9, (byte)0x90, (byte)0xB5,
  108.86 +            (byte)0x9C, (byte)0xEB, (byte)0x00, (byte)0x00,
  108.87 +            (byte)0x00, (byte)0x36, (byte)0x00, (byte)0x01,
  108.88 +            (byte)0x00, (byte)0x09, (byte)0x4D, (byte)0x41,
  108.89 +            (byte)0x44, (byte)0x2E, (byte)0x4C, (byte)0x4F,
  108.90 +            (byte)0x43, (byte)0x41, (byte)0x4C, (byte)0x00,
  108.91 +            (byte)0x02, (byte)0x6D, (byte)0x65, (byte)0x00,
  108.92 +            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x4A,
  108.93 +            (byte)0x79, (byte)0x45, (byte)0xCD, (byte)0x04,
  108.94 +            (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x18,
  108.95 +            (byte)0xDF, (byte)0xDF, (byte)0x62, (byte)0x86,
  108.96 +            (byte)0x37, (byte)0xCE, (byte)0x29, (byte)0xBA,
  108.97 +            (byte)0xBC, (byte)0x23, (byte)0x15, (byte)0xDC,
  108.98 +            (byte)0x86, (byte)0x7C, (byte)0xB6, (byte)0x89,
  108.99 +            (byte)0x25, (byte)0x25, (byte)0xCD, (byte)0x4A,
 108.100 +            (byte)0x9B, (byte)0xCE, (byte)0xF4, (byte)0xAE,
 108.101 +            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x26,
 108.102 +            (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09,
 108.103 +            (byte)0x4D, (byte)0x41, (byte)0x44, (byte)0x2E,
 108.104 +            (byte)0x4C, (byte)0x4F, (byte)0x43, (byte)0x41,
 108.105 +            (byte)0x4C, (byte)0x00, (byte)0x02, (byte)0x6D,
 108.106 +            (byte)0x65, (byte)0x00, (byte)0x00, (byte)0x00,
 108.107 +            (byte)0x00, (byte)0x4A, (byte)0x79, (byte)0x4B,
 108.108 +            (byte)0x5E, (byte)0x05, (byte)0x00, (byte)0x01,
 108.109 +            (byte)0x00, (byte)0x08, (byte)0xE6, (byte)0xB0,
 108.110 +            (byte)0x07, (byte)0xA8, (byte)0x5B, (byte)0xF8,
 108.111 +            (byte)0x73, (byte)0xAD, (byte)0x00, (byte)0x00,
 108.112 +            (byte)0x00, (byte)0x2E, (byte)0x00, (byte)0x01,
 108.113 +            (byte)0x00, (byte)0x09, (byte)0x4D, (byte)0x41,
 108.114 +            (byte)0x44, (byte)0x2E, (byte)0x4C, (byte)0x4F,
 108.115 +            (byte)0x43, (byte)0x41, (byte)0x4C, (byte)0x00,
 108.116 +            (byte)0x02, (byte)0x6D, (byte)0x65, (byte)0x00,
 108.117 +            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x4A,
 108.118 +            (byte)0x79, (byte)0x4B, (byte)0x5E, (byte)0x05,
 108.119 +            (byte)0x00, (byte)0x11, (byte)0x00, (byte)0x10,
 108.120 +            (byte)0xEA, (byte)0xF5, (byte)0xA8, (byte)0x36,
 108.121 +            (byte)0xA5, (byte)0x3E, (byte)0x5F, (byte)0x5C,
 108.122 +            (byte)0x26, (byte)0xE9, (byte)0xDD, (byte)0x8B,
 108.123 +            (byte)0x8C, (byte)0xE8, (byte)0x92, (byte)0x9C,
 108.124 +            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x3E,
 108.125 +            (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09,
 108.126 +            (byte)0x4D, (byte)0x41, (byte)0x44, (byte)0x2E,
 108.127 +            (byte)0x4C, (byte)0x4F, (byte)0x43, (byte)0x41,
 108.128 +            (byte)0x4C, (byte)0x00, (byte)0x02, (byte)0x6D,
 108.129 +            (byte)0x65, (byte)0x00, (byte)0x00, (byte)0x00,
 108.130 +            (byte)0x00, (byte)0x4A, (byte)0x79, (byte)0x4B,
 108.131 +            (byte)0x5E, (byte)0x05, (byte)0x00, (byte)0x12,
 108.132 +            (byte)0x00, (byte)0x20, (byte)0x68, (byte)0xBE,
 108.133 +            (byte)0xD4, (byte)0x17, (byte)0x3A, (byte)0x06,
 108.134 +            (byte)0xE0, (byte)0x0C, (byte)0x62, (byte)0x11,
 108.135 +            (byte)0xB7, (byte)0x53, (byte)0x1B, (byte)0x3E,
 108.136 +            (byte)0xB2, (byte)0x6B, (byte)0x0D, (byte)0x48,
 108.137 +            (byte)0xD8, (byte)0x52, (byte)0x5A, (byte)0x4C,
 108.138 +            (byte)0xBE, (byte)0x24, (byte)0xBB, (byte)0x3D,
 108.139 +            (byte)0xC1, (byte)0x74, (byte)0x69, (byte)0xDA,
 108.140 +            (byte)0x34, (byte)0x98, (byte)0x00, (byte)0x00,
 108.141 +            (byte)0x00, (byte)0x26, (byte)0x00, (byte)0x01,
 108.142 +            (byte)0x00, (byte)0x09, (byte)0x4D, (byte)0x41,
 108.143 +            (byte)0x44, (byte)0x2E, (byte)0x4C, (byte)0x4F,
 108.144 +            (byte)0x43, (byte)0x41, (byte)0x4C, (byte)0x00,
 108.145 +            (byte)0x02, (byte)0x6D, (byte)0x65, (byte)0x00,
 108.146 +            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x4A,
 108.147 +            (byte)0x79, (byte)0x51, (byte)0x27, (byte)0x03,
 108.148 +            (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x08,
 108.149 +            (byte)0xE6, (byte)0xB0, (byte)0x07, (byte)0xA8,
 108.150 +            (byte)0x5B, (byte)0xF8, (byte)0x73, (byte)0xAD,
 108.151 +            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x2E,
 108.152 +            (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09,
 108.153 +            (byte)0x4D, (byte)0x41, (byte)0x44, (byte)0x2E,
 108.154 +            (byte)0x4C, (byte)0x4F, (byte)0x43, (byte)0x41,
 108.155 +            (byte)0x4C, (byte)0x00, (byte)0x02, (byte)0x6D,
 108.156 +            (byte)0x65, (byte)0x00, (byte)0x00, (byte)0x00,
 108.157 +            (byte)0x00, (byte)0x4A, (byte)0x79, (byte)0x51,
 108.158 +            (byte)0x27, (byte)0x03, (byte)0x00, (byte)0x11,
 108.159 +            (byte)0x00, (byte)0x10, (byte)0xEA, (byte)0xF5,
 108.160 +            (byte)0xA8, (byte)0x36, (byte)0xA5, (byte)0x3E,
 108.161 +            (byte)0x5F, (byte)0x5C, (byte)0x26, (byte)0xE9,
 108.162 +            (byte)0xDD, (byte)0x8B, (byte)0x8C, (byte)0xE8,
 108.163 +            (byte)0x92, (byte)0x9C, (byte)0x00, (byte)0x00,
 108.164 +            (byte)0x00, (byte)0x3E, (byte)0x00, (byte)0x01,
 108.165 +            (byte)0x00, (byte)0x09, (byte)0x4D, (byte)0x41,
 108.166 +            (byte)0x44, (byte)0x2E, (byte)0x4C, (byte)0x4F,
 108.167 +            (byte)0x43, (byte)0x41, (byte)0x4C, (byte)0x00,
 108.168 +            (byte)0x02, (byte)0x6D, (byte)0x65, (byte)0x00,
 108.169 +            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x4A,
 108.170 +            (byte)0x79, (byte)0x51, (byte)0x27, (byte)0x03,
 108.171 +            (byte)0x00, (byte)0x12, (byte)0x00, (byte)0x20,
 108.172 +            (byte)0x68, (byte)0xBE, (byte)0xD4, (byte)0x17,
 108.173 +            (byte)0x3A, (byte)0x06, (byte)0xE0, (byte)0x0C,
 108.174 +            (byte)0x62, (byte)0x11, (byte)0xB7, (byte)0x53,
 108.175 +            (byte)0x1B, (byte)0x3E, (byte)0xB2, (byte)0x6B,
 108.176 +            (byte)0x0D, (byte)0x48, (byte)0xD8, (byte)0x52,
 108.177 +            (byte)0x5A, (byte)0x4C, (byte)0xBE, (byte)0x24,
 108.178 +            (byte)0xBB, (byte)0x3D, (byte)0xC1, (byte)0x74,
 108.179 +            (byte)0x69, (byte)0xDA, (byte)0x34, (byte)0x98,
 108.180 +            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x26,
 108.181 +            (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09,
 108.182 +            (byte)0x4D, (byte)0x41, (byte)0x44, (byte)0x2E,
 108.183 +            (byte)0x4C, (byte)0x4F, (byte)0x43, (byte)0x41,
 108.184 +            (byte)0x4C, (byte)0x00, (byte)0x02, (byte)0x68,
 108.185 +            (byte)0x65, (byte)0x00, (byte)0x00, (byte)0x00,
 108.186 +            (byte)0x00, (byte)0x4A, (byte)0x79, (byte)0x54,
 108.187 +            (byte)0xC7, (byte)0x01, (byte)0x00, (byte)0x01,
 108.188 +            (byte)0x00, (byte)0x08, (byte)0x85, (byte)0x5B,
 108.189 +            (byte)0xE3, (byte)0x13, (byte)0x3E, (byte)0xF8,
 108.190 +            (byte)0x76, (byte)0xEC, (byte)0x00, (byte)0x00,
 108.191 +            (byte)0x00, (byte)0x2E, (byte)0x00, (byte)0x01,
 108.192 +            (byte)0x00, (byte)0x09, (byte)0x4D, (byte)0x41,
 108.193 +            (byte)0x44, (byte)0x2E, (byte)0x4C, (byte)0x4F,
 108.194 +            (byte)0x43, (byte)0x41, (byte)0x4C, (byte)0x00,
 108.195 +            (byte)0x02, (byte)0x68, (byte)0x65, (byte)0x00,
 108.196 +            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x4A,
 108.197 +            (byte)0x79, (byte)0x54, (byte)0xC7, (byte)0x01,
 108.198 +            (byte)0x00, (byte)0x11, (byte)0x00, (byte)0x10,
 108.199 +            (byte)0xEC, (byte)0xCC, (byte)0x16, (byte)0xCD,
 108.200 +            (byte)0xE8, (byte)0x51, (byte)0x46, (byte)0x4C,
 108.201 +            (byte)0x1B, (byte)0x57, (byte)0xAE, (byte)0x19,
 108.202 +            (byte)0xC3, (byte)0xD2, (byte)0x55, (byte)0x1B,
 108.203 +            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x3E,
 108.204 +            (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09,
 108.205 +            (byte)0x4D, (byte)0x41, (byte)0x44, (byte)0x2E,
 108.206 +            (byte)0x4C, (byte)0x4F, (byte)0x43, (byte)0x41,
 108.207 +            (byte)0x4C, (byte)0x00, (byte)0x02, (byte)0x68,
 108.208 +            (byte)0x65, (byte)0x00, (byte)0x00, (byte)0x00,
 108.209 +            (byte)0x00, (byte)0x4A, (byte)0x79, (byte)0x54,
 108.210 +            (byte)0xC7, (byte)0x01, (byte)0x00, (byte)0x12,
 108.211 +            (byte)0x00, (byte)0x20, (byte)0xAE, (byte)0xBA,
 108.212 +            (byte)0xCB, (byte)0xF5, (byte)0xA8, (byte)0x09,
 108.213 +            (byte)0xC1, (byte)0xB0, (byte)0x2C, (byte)0x2A,
 108.214 +            (byte)0x3D, (byte)0x96, (byte)0x2C, (byte)0x2D,
 108.215 +            (byte)0xF5, (byte)0xFE, (byte)0x65, (byte)0xEC,
 108.216 +            (byte)0x75, (byte)0x72, (byte)0x5B, (byte)0x46,
 108.217 +            (byte)0x84, (byte)0xD7, (byte)0x49, (byte)0x3E,
 108.218 +            (byte)0xF2, (byte)0x27, (byte)0x32, (byte)0x69,
 108.219 +            (byte)0x75, (byte)0x9B,
 108.220 +        };
 108.221 +        System.setProperty("java.security.krb5.conf",
 108.222 +                new File(System.getProperty("test.src"),
 108.223 +                    "../krb5.conf").getAbsolutePath());
 108.224 +        FileOutputStream fout = new FileOutputStream("kt");
 108.225 +        fout.write(kt);
 108.226 +        fout.close();
 108.227 +        KeyTab ktab = KeyTab.getInstance("kt");
 108.228 +        PrincipalName pn = new PrincipalName("me@MAD.LOCAL");
 108.229 +        EncryptionKey[] keys = ktab.readServiceKeys(pn);
 108.230 +        if (keys[0].getKeyVersionNumber() != 5) {
 108.231 +            throw new Exception("Highest not first");
 108.232 +        }
 108.233 +        if (ktab.readServiceKey(pn).getKeyVersionNumber() != 5) {
 108.234 +            throw new Exception("Highest not chosen");
 108.235 +        }
 108.236 +        new File("kt").delete();
 108.237 +    }
 108.238 +}