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 "${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 "1.0"/>
4.253 + <contains string="${version-output}" substring="java version "1.1"/>
4.254 + <contains string="${version-output}" substring="java version "1.2"/>
4.255 + <contains string="${version-output}" substring="java version "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> <tt><</tt> <i>n</i> <tt><=</tt> <i>r</i>.
27.33 @@ -79,44 +79,46 @@
27.34 * <i>p</i> <tt>+</tt> <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> <tt><</tt> <i>n</i> <tt><=</tt> <i>r</i>.
27.124 @@ -156,41 +158,43 @@
27.125 * <i>p</i> <tt>+</tt> <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}<V> <em>operation</em>(<em>...</em>)</pre></li>
28.7 - * <li><pre>Future<V> <em>operation</em>(<em>...</em> A attachment, {@link CompletionHandler}<V,? super A> handler)</pre></li>
28.8 + * <li><pre>void <em>operation</em>(<em>...</em> A attachment, {@link
28.9 + * CompletionHandler}<V,? super A> 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<SocketAddress,ByteBuffer>() {
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<?>[0]);
30.78 + * ch.{@link #open(Path,Set,ExecutorService,FileAttribute[])
30.79 + * open}(file, opts, null, new FileAttribute<?>[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} + {@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 +}