This commit is contained in:
Phil Race 2018-02-05 02:07:12 -08:00
commit a0b36d2293
64 changed files with 4784 additions and 70772 deletions

View File

@ -1,4 +1,5 @@
^build/
^.build/
^dist/
^.idea/
nbproject/private/

View File

@ -56,10 +56,10 @@
<li><a href="#alsa">ALSA</a></li>
<li><a href="#libffi">libffi</a></li>
</ul></li>
<li><a href="#other-tooling-requirements">Other Tooling Requirements</a><ul>
<li><a href="#build-tools-requirements">Build Tools Requirements</a><ul>
<li><a href="#autoconf">Autoconf</a></li>
<li><a href="#gnu-make">GNU Make</a></li>
<li><a href="#gnu-bash">GNU Bash</a></li>
<li><a href="#autoconf">Autoconf</a></li>
</ul></li>
<li><a href="#running-configure">Running Configure</a><ul>
<li><a href="#common-configure-arguments">Common Configure Arguments</a></li>
@ -116,10 +116,10 @@
<p>If you are eager to try out building OpenJDK, these simple steps works most of the time. They assume that you have installed Mercurial (and Cygwin if running on Windows) and cloned the top-level OpenJDK repository that you want to build.</p>
<ol type="1">
<li><p><a href="#getting-the-source-code">Get the complete source code</a>:<br />
<code>hg clone http://hg.openjdk.java.net/jdk10/master</code></p></li>
<code>hg clone http://hg.openjdk.java.net/jdk/jdk</code></p></li>
<li><p><a href="#running-configure">Run configure</a>:<br />
<code>bash configure</code></p>
<p>If <code>configure</code> fails due to missing dependencies (to either the <a href="#native-compiler-toolchain-requirements">toolchain</a>, <a href="#external-library-requirements">external libraries</a> or the <a href="#boot-jdk-requirements">boot JDK</a>), most of the time it prints a suggestion on how to resolve the situation on your platform. Follow the instructions, and try running <code>bash configure</code> again.</p></li>
<p>If <code>configure</code> fails due to missing dependencies (to either the <a href="#native-compiler-toolchain-requirements">toolchain</a>, <a href="#build-tools-requirements">build tools</a>, <a href="#external-library-requirements">external libraries</a> or the <a href="#boot-jdk-requirements">boot JDK</a>), most of the time it prints a suggestion on how to resolve the situation on your platform. Follow the instructions, and try running <code>bash configure</code> again.</p></li>
<li><p><a href="#running-make">Run make</a>:<br />
<code>make images</code></p></li>
<li><p>Verify your newly built JDK:<br />
@ -201,12 +201,13 @@
<p>OpenJDK requires GNU Make 4.0 or greater on Windows. This is usually not a problem, since Cygwin currently only distributes GNU Make at a version above 4.0.</p>
<p>Apart from the basic Cygwin installation, the following packages must also be installed:</p>
<ul>
<li><code>autoconf</code></li>
<li><code>make</code></li>
<li><code>zip</code></li>
<li><code>unzip</code></li>
</ul>
<p>Often, you can install these packages using the following command line:</p>
<pre><code>&lt;path to Cygwin setup&gt;/setup-x86_64 -q -P make -P unzip -P zip</code></pre>
<pre><code>&lt;path to Cygwin setup&gt;/setup-x86_64 -q -P autoconf -P make -P unzip -P zip</code></pre>
<p>Unfortunately, Cygwin can be unreliable in certain circumstances. If you experience build tool crashes or strange issues when building on Windows, please check the Cygwin FAQ on the <a href="https://cygwin.com/faq/faq.html#faq.using.bloda">&quot;BLODA&quot; list</a> and the section on <a href="https://cygwin.com/faq/faq.html#faq.using.fixing-fork-failures">fork() failures</a>.</p>
<h3 id="solaris">Solaris</h3>
<p>See <code>make/devkit/solaris11.1-package-list.txt</code> for a list of recommended packages to install when building on Solaris. The versions specified in this list is the versions used by the daily builds at Oracle, and is likely to work properly.</p>
@ -424,7 +425,17 @@ tar -xzf freetype-2.5.3.tar.gz</code></pre>
<li>To install on an rpm-based Linux, try running <code>sudo yum install libffi-devel</code>.</li>
</ul>
<p>Use <code>--with-libffi=&lt;path&gt;</code> if <code>configure</code> does not properly locate your libffi files.</p>
<h2 id="other-tooling-requirements">Other Tooling Requirements</h2>
<h2 id="build-tools-requirements">Build Tools Requirements</h2>
<h3 id="autoconf">Autoconf</h3>
<p>OpenJDK requires <a href="http://www.gnu.org/software/autoconf">Autoconf</a> on all platforms. At least version 2.69 is required.</p>
<ul>
<li>To install on an apt-based Linux, try running <code>sudo apt-get install autoconf</code>.</li>
<li>To install on an rpm-based Linux, try running <code>sudo yum install autoconf</code>.</li>
<li>To install on macOS, try running <code>brew install autoconf</code>.</li>
<li>To install on Windows, try running <code>&lt;path to Cygwin setup&gt;/setup-x86_64 -q -P autoconf</code>.</li>
</ul>
<p>If <code>configure</code> has problems locating your installation of autoconf, you can specify it using the <code>AUTOCONF</code> environment variable, like this:</p>
<pre><code>AUTOCONF=&lt;path to autoconf&gt; configure ...</code></pre>
<h3 id="gnu-make">GNU Make</h3>
<p>OpenJDK requires <a href="http://www.gnu.org/software/make">GNU Make</a>. No other flavors of make are supported.</p>
<p>At least version 3.81 of GNU Make must be used. For distributions supporting GNU Make 4.0 or above, we strongly recommend it. GNU Make 4.0 contains useful functionality to handle parallel building (supported by <code>--with-output-sync</code>) and speed and stability improvements.</p>
@ -434,10 +445,6 @@ tar -xzf freetype-2.5.3.tar.gz</code></pre>
<h3 id="gnu-bash">GNU Bash</h3>
<p>OpenJDK requires <a href="http://www.gnu.org/software/bash">GNU Bash</a>. No other shells are supported.</p>
<p>At least version 3.2 of GNU Bash must be used.</p>
<h3 id="autoconf">Autoconf</h3>
<p>If you want to modify the build system itself, you need to install <a href="http://www.gnu.org/software/autoconf">Autoconf</a>.</p>
<p>However, if you only need to build OpenJDK or if you only edit the actual OpenJDK source files, there is no dependency on autoconf, since the source distribution includes a pre-generated <code>configure</code> shell script.</p>
<p>See the section on <a href="#autoconf-details">Autoconf Details</a> for details on how OpenJDK uses autoconf. This is especially important if you plan to contribute changes to OpenJDK that modifies the build system.</p>
<h2 id="running-configure">Running Configure</h2>
<p>To build OpenJDK, you need a &quot;configuration&quot;, which consists of a directory where to store the build output, coupled with information about the platform, the specific build machine, and choices that affect how OpenJDK is built.</p>
<p>The configuration is created by the <code>configure</code> script. The basic invocation of the <code>configure</code> script looks like this:</p>
@ -751,7 +758,12 @@ cannot create ... Permission denied
spawn failed</code></pre>
<p>This can be a sign of a Cygwin problem. See the information about solving problems in the <a href="#cygwin">Cygwin</a> section. Rebooting the computer might help temporarily.</p>
<h3 id="getting-help">Getting Help</h3>
<p>If none of the suggestions in this document helps you, or if you find what you believe is a bug in the build system, please contact the Build Group by sending a mail to <a href="mailto:build-dev@openjdk.java.net">build-dev@openjdk.java.net</a>. Please include the relevant parts of the configure and/or build log.</p>
<p>If none of the suggestions in this document helps you, or if you find what you believe is a bug in the build system, please contact the Build Group by sending a mail to <script type="text/javascript">
<!--
h='&#x6f;&#112;&#x65;&#110;&#106;&#100;&#x6b;&#46;&#106;&#x61;&#118;&#x61;&#46;&#110;&#x65;&#116;';a='&#64;';n='&#98;&#x75;&#x69;&#108;&#100;&#x2d;&#100;&#x65;&#118;';e=n+a+h;
document.write('<a h'+'ref'+'="ma'+'ilto'+':'+e+'" clas'+'s="em' + 'ail">'+e+'<\/'+'a'+'>');
// -->
</script><noscript>&#98;&#x75;&#x69;&#108;&#100;&#x2d;&#100;&#x65;&#118;&#32;&#x61;&#116;&#32;&#x6f;&#112;&#x65;&#110;&#106;&#100;&#x6b;&#32;&#100;&#x6f;&#116;&#32;&#106;&#x61;&#118;&#x61;&#32;&#100;&#x6f;&#116;&#32;&#110;&#x65;&#116;</noscript>. Please include the relevant parts of the configure and/or build log.</p>
<p>If you need general help or advice about developing for OpenJDK, you can also contact the Adoption Group. See the section on <a href="#contributing-to-openjdk">Contributing to OpenJDK</a> for more information.</p>
<h2 id="hints-and-suggestions-for-advanced-users">Hints and Suggestions for Advanced Users</h2>
<h3 id="setting-up-a-forest-for-pushing-changes-defpath">Setting Up a Forest for Pushing Changes (defpath)</h3>
@ -871,15 +883,9 @@ test-support/</code></pre>
<p>When building for distribution, <code>zipped</code> is a good solution. Binaries built with <code>internal</code> is suitable for use by developers, since they facilitate debugging, but should be stripped before distributed to end users.</p>
<h3 id="autoconf-details">Autoconf Details</h3>
<p>The <code>configure</code> script is based on the autoconf framework, but in some details deviate from a normal autoconf <code>configure</code> script.</p>
<p>The <code>configure</code> script in the top level directory of OpenJDK is just a thin wrapper that calls <code>make/autoconf/configure</code>. This in turn provides functionality that is not easily expressed in the normal Autoconf framework, and then calls into the core of the <code>configure</code> script, which is the <code>make/autoconf/generated-configure.sh</code> file.</p>
<p>As the name implies, this file is generated by Autoconf. It is checked in after regeneration, to alleviate the common user to have to install Autoconf.</p>
<p>The build system will detect if the Autoconf source files have changed, and will trigger a regeneration of <code>make/autoconf/generated-configure.sh</code> if needed. You can also manually request such an update by <code>bash make/autoconf/autogen.sh</code>.</p>
<p>If you make changes to the build system that requires a re-generation, note the following:</p>
<ul>
<li><p>You must use <em>exactly</em> version 2.69 of autoconf for your patch to be accepted. This is to avoid spurious changes in the generated file. Note that Ubuntu 16.04 ships a patched version of autoconf which claims to be 2.69, but is not.</p></li>
<li><p>You do not need to include the generated file in reviews.</p></li>
<li><p>If the generated file needs updating, the Oracle JDK closed counter-part will also need to be updated. It is very much appreciated if you ask for an Oracle engineer to sponsor your push so this can be made in tandem.</p></li>
</ul>
<p>The <code>configure</code> script in the top level directory of OpenJDK is just a thin wrapper that calls <code>make/autoconf/configure</code>. This in turn will run <code>autoconf</code> to create the runnable (generated) configure script, as <code>.build/generated-configure.sh</code>. Apart from being responsible for the generation of the runnable script, the <code>configure</code> script also provides functionality that is not easily expressed in the normal Autoconf framework. As part of this functionality, the generated script is called.</p>
<p>The build system will detect if the Autoconf source files have changed, and will trigger a regeneration of the generated script if needed. You can also manually request such an update by <code>bash configure autogen</code>.</p>
<p>In previous versions of the OpenJDK, the generated script was checked in at <code>make/autoconf/generated-configure.sh</code>. This is no longer the case.</p>
<h3 id="developing-the-build-system-itself">Developing the Build System Itself</h3>
<p>This section contains a few remarks about how to develop for the build system itself. It is not relevant if you are only making changes in the product source code.</p>
<p>While technically using <code>make</code>, the make source files of the OpenJDK does not resemble most other Makefiles. Instead of listing specific targets and actions (perhaps using patterns), the basic modus operandi is to call a high-level function (or properly, macro) from the API in <code>make/common</code>. For instance, to compile all classes in the <code>jdk.internal.foo</code> package in the <code>jdk.foo</code> module, a call like this would be made:</p>
@ -897,7 +903,7 @@ test-support/</code></pre>
<pre><code>make COMPARE_BUILD=CONF=--enable-new-hotspot-feature:MAKE=hotspot</code></pre>
<p>See <code>make/InitSupport.gmk</code> for details on how to use <code>COMPARE_BUILD</code>.</p>
<p>To analyze build performance, run with <code>LOG=trace</code> and check <code>$BUILD/build-trace-time.log</code>. Use <code>JOBS=1</code> to avoid parallelism.</p>
<p>Please check that you adhere to the <a href="http://openjdk.java.net/groups/build/doc/code-conventions.html">Code Conventions for the Build System</a> before submitting patches. Also see the section in <a href="#autoconf-details">Autoconf Details</a> about the generated configure script.</p>
<p>Please check that you adhere to the <a href="http://openjdk.java.net/groups/build/doc/code-conventions.html">Code Conventions for the Build System</a> before submitting patches.</p>
<h2 id="contributing-to-openjdk">Contributing to OpenJDK</h2>
<p>So, now you've build your OpenJDK, and made your first patch, and want to contribute it back to the OpenJDK community.</p>
<p>First of all: Thank you! We gladly welcome your contribution to the OpenJDK. However, please bear in mind that OpenJDK is a massive project, and we must ask you to follow our rules and guidelines to be able to accept your contribution.</p>

View File

@ -7,13 +7,14 @@ the time. They assume that you have installed Mercurial (and Cygwin if running
on Windows) and cloned the top-level OpenJDK repository that you want to build.
1. [Get the complete source code](#getting-the-source-code): \
`hg clone http://hg.openjdk.java.net/jdk10/master`
`hg clone http://hg.openjdk.java.net/jdk/jdk`
2. [Run configure](#running-configure): \
`bash configure`
If `configure` fails due to missing dependencies (to either the
[toolchain](#native-compiler-toolchain-requirements), [external libraries](
[toolchain](#native-compiler-toolchain-requirements), [build tools](
#build-tools-requirements), [external libraries](
#external-library-requirements) or the [boot JDK](#boot-jdk-requirements)),
most of the time it prints a suggestion on how to resolve the situation on
your platform. Follow the instructions, and try running `bash configure`
@ -195,13 +196,14 @@ problem, since Cygwin currently only distributes GNU Make at a version above
Apart from the basic Cygwin installation, the following packages must also be
installed:
* `autoconf`
* `make`
* `zip`
* `unzip`
Often, you can install these packages using the following command line:
```
<path to Cygwin setup>/setup-x86_64 -q -P make -P unzip -P zip
<path to Cygwin setup>/setup-x86_64 -q -P autoconf -P make -P unzip -P zip
```
Unfortunately, Cygwin can be unreliable in certain circumstances. If you
@ -552,7 +554,27 @@ Hotspot.
Use `--with-libffi=<path>` if `configure` does not properly locate your libffi
files.
## Other Tooling Requirements
## Build Tools Requirements
### Autoconf
OpenJDK requires [Autoconf](http://www.gnu.org/software/autoconf) on all
platforms. At least version 2.69 is required.
* To install on an apt-based Linux, try running `sudo apt-get install
autoconf`.
* To install on an rpm-based Linux, try running `sudo yum install
autoconf`.
* To install on macOS, try running `brew install autoconf`.
* To install on Windows, try running `<path to Cygwin setup>/setup-x86_64 -q
-P autoconf`.
If `configure` has problems locating your installation of autoconf, you can
specify it using the `AUTOCONF` environment variable, like this:
```
AUTOCONF=<path to autoconf> configure ...
```
### GNU Make
@ -585,19 +607,6 @@ are supported.
At least version 3.2 of GNU Bash must be used.
### Autoconf
If you want to modify the build system itself, you need to install [Autoconf](
http://www.gnu.org/software/autoconf).
However, if you only need to build OpenJDK or if you only edit the actual
OpenJDK source files, there is no dependency on autoconf, since the source
distribution includes a pre-generated `configure` shell script.
See the section on [Autoconf Details](#autoconf-details) for details on how
OpenJDK uses autoconf. This is especially important if you plan to contribute
changes to OpenJDK that modifies the build system.
## Running Configure
To build OpenJDK, you need a "configuration", which consists of a directory
@ -1660,32 +1669,19 @@ The `configure` script is based on the autoconf framework, but in some details
deviate from a normal autoconf `configure` script.
The `configure` script in the top level directory of OpenJDK is just a thin
wrapper that calls `make/autoconf/configure`. This in turn provides
functionality that is not easily expressed in the normal Autoconf framework,
and then calls into the core of the `configure` script, which is the
`make/autoconf/generated-configure.sh` file.
As the name implies, this file is generated by Autoconf. It is checked in after
regeneration, to alleviate the common user to have to install Autoconf.
wrapper that calls `make/autoconf/configure`. This in turn will run `autoconf`
to create the runnable (generated) configure script, as
`.build/generated-configure.sh`. Apart from being responsible for the
generation of the runnable script, the `configure` script also provides
functionality that is not easily expressed in the normal Autoconf framework. As
part of this functionality, the generated script is called.
The build system will detect if the Autoconf source files have changed, and
will trigger a regeneration of `make/autoconf/generated-configure.sh` if
needed. You can also manually request such an update by `bash
make/autoconf/autogen.sh`.
will trigger a regeneration of the generated script if needed. You can also
manually request such an update by `bash configure autogen`.
If you make changes to the build system that requires a re-generation, note the
following:
* You must use *exactly* version 2.69 of autoconf for your patch to be
accepted. This is to avoid spurious changes in the generated file. Note
that Ubuntu 16.04 ships a patched version of autoconf which claims to be
2.69, but is not.
* You do not need to include the generated file in reviews.
* If the generated file needs updating, the Oracle JDK closed counter-part
will also need to be updated. It is very much appreciated if you ask for an
Oracle engineer to sponsor your push so this can be made in tandem.
In previous versions of the OpenJDK, the generated script was checked in at
`make/autoconf/generated-configure.sh`. This is no longer the case.
### Developing the Build System Itself
@ -1736,8 +1732,7 @@ Use `JOBS=1` to avoid parallelism.
Please check that you adhere to the [Code Conventions for the Build System](
http://openjdk.java.net/groups/build/doc/code-conventions.html) before
submitting patches. Also see the section in [Autoconf Details](
#autoconf-details) about the generated configure script.
submitting patches.
## Contributing to OpenJDK

View File

@ -1,81 +0,0 @@
#!/bin/bash
#
# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
generate_configure_script() {
# First create a header
cat > $1 << EOT
#!/bin/bash
#
# ##########################################################
# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ###
# ##########################################################
#
EOT
# Then replace "magic" variables in configure.ac and append the output
# from autoconf. $2 is either cat (just a no-op) or a filter.
cat $script_dir/configure.ac | sed -e "s|@DATE_WHEN_GENERATED@|$TIMESTAMP|" | \
eval $2 | ${AUTOCONF} -W all -I$script_dir - >> $1
rm -rf autom4te.cache
}
script_dir=`dirname $0`
# Create a timestamp as seconds since epoch
if test "x`uname -s`" = "xSunOS"; then
TIMESTAMP=`date +%s`
if test "x$TIMESTAMP" = "x%s"; then
# date +%s not available on this Solaris, use workaround from nawk(1):
TIMESTAMP=`nawk 'BEGIN{print srand()}'`
fi
else
TIMESTAMP=`date +%s`
fi
AUTOCONF="`which autoconf 2> /dev/null | grep -v '^no autoconf in'`"
if test "x${AUTOCONF}" = x; then
echo "You need autoconf installed to be able to regenerate the configure script"
echo "Error: Cannot find autoconf" 1>&2
exit 1
fi
autoconf_version=`$AUTOCONF --version | head -1`
echo "Using autoconf at ${AUTOCONF} [$autoconf_version]"
echo "Generating generated-configure.sh"
generate_configure_script "$script_dir/generated-configure.sh" 'cat'
if test "x$CUSTOM_CONFIG_DIR" != "x"; then
custom_hook=$CUSTOM_CONFIG_DIR/custom-hook.m4
if test ! -e $custom_hook; then
echo "CUSTOM_CONFIG_DIR set but $CUSTOM_CONFIG_DIR/custom-hook.m4 not present"
echo "Error: Cannot continue" 1>&2
exit 1
fi
# We have custom sources available; also generate configure script
# with custom hooks compiled in.
echo "Generating custom generated-configure.sh"
generate_configure_script "$CUSTOM_CONFIG_DIR/generated-configure.sh" 'sed -e "s|#CUSTOM_AUTOCONF_INCLUDE|m4_include([$custom_hook])|"'
fi

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -336,7 +336,6 @@ AC_DEFUN_ONCE([BASIC_INIT],
DATE_WHEN_CONFIGURED=`LANG=C date`
AC_SUBST(DATE_WHEN_CONFIGURED)
AC_MSG_NOTICE([Configuration created at $DATE_WHEN_CONFIGURED.])
AC_MSG_NOTICE([configure script generated at timestamp $DATE_WHEN_GENERATED.])
])
# Test that variable $1 denoting a program is not empty. If empty, exit with an error.

View File

@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -43,82 +43,138 @@ fi
export CONFIG_SHELL=$BASH
export _as_can_reexec=no
conf_script_dir="$TOPDIR/make/autoconf"
if test "x$CUSTOM_CONFIG_DIR" != x; then
if test ! -e $CUSTOM_CONFIG_DIR/generated-configure.sh; then
custom_hook=$CUSTOM_CONFIG_DIR/custom-hook.m4
if test ! -e $custom_hook; then
echo "CUSTOM_CONFIG_DIR not pointing to a proper custom config dir."
echo "Error: Cannot continue" 1>&2
exit 1
fi
build_support_dir="$CUSTOM_ROOT/.build"
else
build_support_dir="$TOPDIR/.build"
fi
conf_script_dir="$TOPDIR/make/autoconf"
generated_script="$build_support_dir/generated-configure.sh"
###
### Test that the generated configure is up-to-date
### Use autoconf to create a runnable configure script, if needed
###
run_autogen_or_fail() {
if test "x`which autoconf 2> /dev/null | grep -v '^no autoconf in'`" = x; then
echo "Cannot locate autoconf, unable to correct situation."
echo "Please install autoconf and run 'bash autogen.sh' to update the generated files."
echo "Error: Cannot continue" 1>&2
exit 1
else
echo "Running autogen.sh to correct the situation"
bash $conf_script_dir/autogen.sh
autoconf_missing_help() {
APT_GET="`which apt-get 2> /dev/null | grep -v '^no apt-get in'`"
YUM="`which yum 2> /dev/null | grep -v '^no yum in'`"
BREW="`which brew 2> /dev/null | grep -v '^no brew in'`"
CYGWIN="`which cygpath 2> /dev/null | grep -v '^no cygpath in'`"
if test "x$APT_GET" != x; then
PKGHANDLER_COMMAND="sudo apt-get install autoconf"
elif test "x$YUM" != x; then
PKGHANDLER_COMMAND="sudo yum install autoconf"
elif test "x$BREW" != x; then
PKGHANDLER_COMMAND="brew install autoconf"
elif test "x$CYGWIN" != x; then
PKGHANDLER_COMMAND="( cd <location of cygwin setup.exe> && cmd /c setup -q -P autoconf )"
fi
if test "x$PKGHANDLER_COMMAND" != x; then
echo "You might be able to fix this by running '$PKGHANDLER_COMMAND'."
fi
}
check_autoconf_timestamps() {
for file in $conf_script_dir/configure.ac $conf_script_dir/*.m4 ; do
if test $file -nt $conf_script_dir/generated-configure.sh; then
echo "Warning: The configure source files is newer than the generated files."
run_autogen_or_fail
generate_configure_script() {
if test "x$AUTOCONF" != x; then
if test ! -x "$AUTOCONF"; then
echo
echo "The specified AUTOCONF variable does not point to a valid autoconf executable:"
echo "AUTOCONF=$AUTOCONF"
echo "Error: Cannot continue" 1>&2
exit 1
fi
done
else
AUTOCONF="`which autoconf 2> /dev/null | grep -v '^no autoconf in'`"
if test "x$AUTOCONF" = x; then
echo
echo "Autoconf is not found on the PATH, and AUTOCONF is not set."
echo "You need autoconf to be able to generate a runnable configure script."
autoconf_missing_help
echo "Error: Cannot find autoconf" 1>&2
exit 1
fi
fi
autoconf_version=`$AUTOCONF --version | head -1`
echo "Using autoconf at ${AUTOCONF} [$autoconf_version]"
if test "x$CUSTOM_CONFIG_DIR" != x; then
# If custom source configure is available, make sure it is up-to-date as well.
for file in $conf_script_dir/configure.ac $conf_script_dir/*.m4 $CUSTOM_CONFIG_DIR/*.m4; do
if test $file -nt $CUSTOM_CONFIG_DIR/generated-configure.sh; then
echo "Warning: The configure source files is newer than the custom generated files."
run_autogen_or_fail
fi
done
# Generate configure script with custom hooks compiled in.
custom_patcher='sed -e "s|#CUSTOM_AUTOCONF_INCLUDE|m4_include([$custom_hook])|"'
else
custom_patcher='cat'
fi
mkdir -p `dirname $generated_script`
# Call autoconf but replace the "magic" variable in configure.ac if requested.
cat $conf_script_dir/configure.ac | eval $custom_patcher | \
${AUTOCONF} -W all -I$conf_script_dir - > $generated_script
rm -rf autom4te.cache
# Sanity check
if test ! -s $generated_script; then
echo "Error: Failed to generate runnable configure script" 1>&2
rm -f $generated_script
exit 1
fi
}
check_hg_updates() {
test_generated_up_to_date() {
if test "x`which hg 2> /dev/null | grep -v '^no hg in'`" != x; then
conf_updated_autoconf_files=`cd $conf_script_dir && hg status -mard . 2> /dev/null`
if test "x$conf_updated_autoconf_files" != x; then
echo "Configure source code has been updated, checking time stamps"
check_autoconf_timestamps
elif test "x$CUSTOM_CONFIG_DIR" != x; then
# If custom source configure is available, make sure it is up-to-date as well.
conf_source_files="$conf_script_dir/configure.ac $conf_script_dir/*.m4"
if test "x$CUSTOM_CONFIG_DIR" != x; then
conf_custom_updated_autoconf_files=`cd $CUSTOM_CONFIG_DIR && hg status -mard . 2> /dev/null`
if test "x$conf_custom_updated_autoconf_files" != x; then
echo "Configure custom source code has been updated, checking time stamps"
check_autoconf_timestamps
fi
conf_custom_source_files="$CUSTOM_CONFIG_DIR/*.m4"
else
conf_custom_updated_autoconf_files=""
conf_custom_source_files=""
fi
if test "x${conf_updated_autoconf_files}${conf_custom_updated_autoconf_files}" != x; then
for file in $conf_source_files $conf_custom_source_files ; do
if test $file -nt $generated_script; then
return 0
fi
done
fi
fi
return 1
}
# Check for local changes
check_hg_updates
run_autoconf=false
if test "x$1" = xautogen; then
# User called us as "configure autogen", so force regeneration
run_autoconf=true
shift
fi
if test "x$CUSTOM_CONFIG_DIR" != x; then
# Test if open configure is newer than custom configure, if so, custom needs to
# be regenerated. This test is required to ensure consistency with custom source.
conf_open_configure_timestamp=`grep DATE_WHEN_GENERATED= $conf_script_dir/generated-configure.sh | cut -d"=" -f 2`
conf_custom_configure_timestamp=`grep DATE_WHEN_GENERATED= $CUSTOM_CONFIG_DIR/generated-configure.sh | cut -d"=" -f 2`
if test $conf_open_configure_timestamp -gt $conf_custom_configure_timestamp; then
echo "Warning: The generated configure file contains changes not present in the custom generated file."
run_autogen_or_fail
if test ! -s $generated_script; then
# Generated script is missing, so we need to create it
echo "Runnable configure script is not present"
run_autoconf=true
else
# File is present, but is it up to date?
if test_generated_up_to_date; then
echo "Runnable configure script is not up to date"
run_autoconf=true
fi
fi
if test "x$run_autoconf" = xtrue; then
echo "Generating runnable configure script"
generate_configure_script
fi
# Autoconf calls the configure script recursively sometimes.
# Don't start logging twice in that case
if test "x$conf_debug_configure" = xtrue; then
@ -240,15 +296,6 @@ conf_processed_arguments=("--enable-option-checking=fatal" "${conf_processed_arg
###
### Call the configure script
###
if test "x$CUSTOM_CONFIG_DIR" != x; then
# Custom source configure available; run that instead
echo "Running custom generated-configure.sh"
conf_script_to_run=$CUSTOM_CONFIG_DIR/generated-configure.sh
else
echo "Running generated-configure.sh"
conf_script_to_run=$conf_script_dir/generated-configure.sh
fi
if test "x$conf_debug_configure" != x; then
# Turn on shell debug output if requested (initial or recursive)
set -x
@ -259,7 +306,7 @@ fi
RCDIR=`mktemp -dt jdk-build-configure.tmp.XXXXXX` || exit $?
trap "rm -rf \"$RCDIR\"" EXIT
conf_logfile=./configure.log
(exec 3>&1 ; ((. $conf_script_to_run "${conf_processed_arguments[@]}" 2>&1 1>&3 ) \
(exec 3>&1 ; ((. $generated_script "${conf_processed_arguments[@]}" 2>&1 1>&3 ) \
; echo $? > "$RCDIR/rc" ) \
| tee -a $conf_logfile 1>&2 ; exec 3>&-) | tee -a $conf_logfile
@ -284,7 +331,7 @@ EOT
# Print additional help, e.g. a list of toolchains and JVM features.
# This must be done by the autoconf script.
( CONFIGURE_PRINT_ADDITIONAL_HELP=true . $conf_script_to_run PRINTF=printf )
( CONFIGURE_PRINT_ADDITIONAL_HELP=true . $generated_script PRINTF=printf )
cat <<EOT

View File

@ -1,5 +1,5 @@
SRC#
# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -63,9 +63,6 @@ AC_DEFUN_ONCE([CUSTOM_SUMMARY_AND_WARNINGS_HOOK])
# custom sources.
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
DATE_WHEN_GENERATED=@DATE_WHEN_GENERATED@
###############################################################################
#
# Initialization / Boot-strapping

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -200,7 +200,7 @@ var getJibProfiles = function (input) {
data.configuration_make_arg = "CONF_NAME=";
// Exclude list to use when Jib creates a source bundle
data.src_bundle_excludes = "./build webrev* */webrev* */*/webrev* */*/*/webrev* .hg */.hg */*/.hg */*/*/.hg";
data.src_bundle_excludes = "./build .build webrev* */webrev* */*/webrev* */*/*/webrev* .hg */.hg */*/.hg */*/*/.hg";
// Include list to use when creating a minimal jib source bundle which
// contains just the jib configuration files.
data.conf_bundle_includes = "*/conf/jib-profiles.* make/autoconf/version-numbers"
@ -411,7 +411,7 @@ var getJibProfilesProfiles = function (input, common, data) {
"linux-x64": {
target_os: "linux",
target_cpu: "x64",
dependencies: ["devkit", "graphviz", "pandoc"],
dependencies: ["devkit", "autoconf", "graphviz", "pandoc"],
configure_args: concat(common.configure_args_64bit,
"--enable-full-docs", "--with-zlib=system"),
default_make_targets: ["docs-bundles"],
@ -421,7 +421,7 @@ var getJibProfilesProfiles = function (input, common, data) {
target_os: "linux",
target_cpu: "x86",
build_cpu: "x64",
dependencies: ["devkit"],
dependencies: ["devkit", "autoconf"],
configure_args: concat(common.configure_args_32bit,
"--with-jvm-variants=minimal,server", "--with-zlib=system"),
},
@ -429,7 +429,7 @@ var getJibProfilesProfiles = function (input, common, data) {
"macosx-x64": {
target_os: "macosx",
target_cpu: "x64",
dependencies: ["devkit", "freetype"],
dependencies: ["devkit", "autoconf", "freetype"],
configure_args: concat(common.configure_args_64bit, "--with-zlib=system",
"--with-macosx-version-max=10.7.0"),
},
@ -437,7 +437,7 @@ var getJibProfilesProfiles = function (input, common, data) {
"solaris-x64": {
target_os: "solaris",
target_cpu: "x64",
dependencies: ["devkit", "cups"],
dependencies: ["devkit", "autoconf", "cups"],
configure_args: concat(common.configure_args_64bit,
"--with-zlib=system", "--enable-dtrace"),
},
@ -445,7 +445,7 @@ var getJibProfilesProfiles = function (input, common, data) {
"solaris-sparcv9": {
target_os: "solaris",
target_cpu: "sparcv9",
dependencies: ["devkit", "cups"],
dependencies: ["devkit", "autoconf", "cups"],
configure_args: concat(common.configure_args_64bit,
"--with-zlib=system", "--enable-dtrace"),
},
@ -453,7 +453,7 @@ var getJibProfilesProfiles = function (input, common, data) {
"windows-x64": {
target_os: "windows",
target_cpu: "x64",
dependencies: ["devkit", "freetype"],
dependencies: ["devkit", "autoconf", "freetype"],
configure_args: concat(common.configure_args_64bit),
},
@ -461,7 +461,7 @@ var getJibProfilesProfiles = function (input, common, data) {
target_os: "windows",
target_cpu: "x86",
build_cpu: "x64",
dependencies: ["devkit", "freetype"],
dependencies: ["devkit", "autoconf", "freetype"],
configure_args: concat(common.configure_args_32bit),
},
@ -469,7 +469,7 @@ var getJibProfilesProfiles = function (input, common, data) {
target_os: "linux",
target_cpu: "aarch64",
build_cpu: "x64",
dependencies: ["devkit", "build_devkit", "cups", "headless_stubs"],
dependencies: ["devkit", "autoconf", "build_devkit", "cups", "headless_stubs"],
configure_args: [
"--with-cpu-port=arm64",
"--with-jvm-variants=server",
@ -482,7 +482,7 @@ var getJibProfilesProfiles = function (input, common, data) {
target_os: "linux",
target_cpu: "arm",
build_cpu: "x64",
dependencies: ["devkit", "build_devkit", "cups"],
dependencies: ["devkit", "autoconf", "build_devkit", "cups"],
configure_args: [
"--with-jvm-variants=minimal1,client",
"--with-x=" + input.get("devkit", "install_path") + "/arm-linux-gnueabihf/libc/usr/X11R6-PI",
@ -854,6 +854,17 @@ var getJibProfilesDependencies = function (input, common) {
environment_path: makeBinDir
},
autoconf: {
organization: common.organization,
ext: "tar.gz",
revision: "2.69+1.0.1",
module: (input.build_os == "windows"
? "autoconf-" + input.build_osenv_platform
: "autoconf-" + input.build_platform),
configure_args: "",
environment_path: input.get("autoconf", "install_path")
},
freetype: {
organization: common.organization,
ext: "tar.gz",
@ -878,6 +889,7 @@ var getJibProfilesDependencies = function (input, common) {
configure_args: "PANDOC=" + input.get("pandoc", "install_path") + "/pandoc/pandoc",
environment_path: input.get("pandoc", "install_path") + "/pandoc"
},
// This adds java jib as a dependency for the test artifacts resolver
jib: {
organization: "com.oracle.java.jib",

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,8 +25,6 @@
package java.lang;
import java.util.Arrays;
/** The CharacterData class encapsulates the large tables found in
Java.lang.Character. */
@ -190,10 +188,8 @@ class CharacterDataLatin1 extends CharacterData {
int digit(int ch, int radix) {
int value = DIGITS[ch];
if (value >= 0 && radix >= Character.MIN_RADIX && radix <= Character.MAX_RADIX) {
value = (value < radix) ? value : -1;
}
return value;
return (value >= 0 && value < radix && radix >= Character.MIN_RADIX
&& radix <= Character.MAX_RADIX) ? value : -1;
}
int getNumericValue(int ch) {

View File

@ -0,0 +1,116 @@
#!/bin/bash -e
#
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# Create a bundle in the current directory, containing what's needed to run
# the 'autoconf' program by the OpenJDK build.
# Autoconf depends on m4, so download and build that first.
AUTOCONF_VERSION=2.69
M4_VERSION=1.4.18
PACKAGE_VERSION=1.0.1
TARGET_PLATFORM=linux_x86
MODULE_NAME=autoconf-$TARGET_PLATFORM-$AUTOCONF_VERSION+$PACKAGE_VERSION
BUNDLE_NAME=$MODULE_NAME.tar.gz
TMPDIR=`mktemp -d -t autoconfbundle-XXXX`
trap "rm -rf \"$TMPDIR\"" EXIT
ORIG_DIR=`pwd`
cd $TMPDIR
OUTPUT_DIR=$TMPDIR/$MODULE_NAME
mkdir -p $OUTPUT_DIR/usr
# Download and build m4
if test "x$TARGET_PLATFORM" = xcygwin_x64; then
# On cygwin 64-bit, just copy the cygwin .exe file
mkdir -p $OUTPUT_DIR/usr/bin
cp /usr/bin/m4 $OUTPUT_DIR/usr/bin
elif test "x$TARGET_PLATFORM" = xcygwin_x86; then
# On cygwin 32-bit, just copy the cygwin .exe file
mkdir -p $OUTPUT_DIR/usr/bin
cp /usr/bin/m4 $OUTPUT_DIR/usr/bin
elif test "x$TARGET_PLATFORM" = xlinux_x64; then
M4_VERSION=1.4.13-5
wget http://yum.oracle.com/repo/OracleLinux/OL6/latest/x86_64/getPackage/m4-$M4_VERSION.el6.x86_64.rpm
cd $OUTPUT_DIR
rpm2cpio ../m4-$M4_VERSION.el6.x86_64.rpm | cpio -d -i
elif test "x$TARGET_PLATFORM" = xlinux_x86; then
M4_VERSION=1.4.13-5
wget http://yum.oracle.com/repo/OracleLinux/OL6/latest/i386/getPackage/m4-$M4_VERSION.el6.i686.rpm
cd $OUTPUT_DIR
rpm2cpio ../m4-$M4_VERSION.el6.i686.rpm | cpio -d -i
else
wget https://ftp.gnu.org/gnu/m4/m4-$M4_VERSION.tar.gz
tar xzf m4-$M4_VERSION.tar.gz
cd m4-$M4_VERSION
./configure --prefix=$OUTPUT_DIR/usr
make
make install
cd ..
fi
# Download and build autoconf
wget https://ftp.gnu.org/gnu/autoconf/autoconf-$AUTOCONF_VERSION.tar.gz
tar xzf autoconf-$AUTOCONF_VERSION.tar.gz
cd autoconf-$AUTOCONF_VERSION
./configure --prefix=$OUTPUT_DIR/usr M4=$OUTPUT_DIR/usr/bin/m4
make
make install
cd ..
perl -pi -e "s!$OUTPUT_DIR/!./!" $OUTPUT_DIR/usr/bin/auto* $OUTPUT_DIR/usr/share/autoconf/autom4te.cfg
cp $OUTPUT_DIR/usr/share/autoconf/autom4te.cfg $OUTPUT_DIR/autom4te.cfg
cat > $OUTPUT_DIR/autoconf << EOF
#!/bin/bash
# Get an absolute path to this script
this_script_dir=\`dirname \$0\`
this_script_dir=\`cd \$this_script_dir > /dev/null && pwd\`
export M4="\$this_script_dir/usr/bin/m4"
export AUTOM4TE="\$this_script_dir/usr/bin/autom4te"
export AUTOCONF="\$this_script_dir/usr/bin/autoconf"
export AUTOHEADER="\$this_script_dir/usr/bin/autoheader"
export AC_MACRODIR="\$this_script_dir/usr/share/autoconf"
export autom4te_perllibdir="\$this_script_dir/usr/share/autoconf"
autom4te_cfg=\$this_script_dir/usr/share/autoconf/autom4te.cfg
cp \$this_script_dir/autom4te.cfg \$autom4te_cfg
echo 'begin-language: "M4sugar"' >> \$autom4te_cfg
echo "args: --prepend-include '"\$this_script_dir/usr/share/autoconf"'" >> \$autom4te_cfg
echo 'end-language: "M4sugar"' >> \$autom4te_cfg
exec \$this_script_dir/usr/bin/autoconf "\$@"
EOF
chmod +x $OUTPUT_DIR/autoconf
cd $OUTPUT_DIR
tar -cvzf ../$BUNDLE_NAME *
cd ..
cp $BUNDLE_NAME "$ORIG_DIR"

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -89,6 +89,7 @@ SUNWprivate_1.1 {
Java_java_net_PlainDatagramSocketImpl_setTimeToLive;
Java_java_net_AbstractPlainSocketImpl_isReusePortAvailable0;
Java_java_net_AbstractPlainDatagramSocketImpl_isReusePortAvailable0;
Java_java_net_SocketCleanable_cleanupClose0;
Java_jdk_net_Sockets_isReusePortAvailable0;
Java_sun_net_PortConfig_getUpper0;
Java_sun_net_PortConfig_getLower0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,11 +26,11 @@ package java.net;
import java.io.FileDescriptor;
import java.io.IOException;
import java.security.AccessController;
import sun.net.ResourceManager;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import sun.net.ResourceManager;
import sun.security.action.GetPropertyAction;
/**
@ -115,6 +115,7 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
fd = new FileDescriptor();
try {
datagramSocketCreate();
SocketCleanable.register(fd);
} catch (SocketException ioe) {
ResourceManager.afterUdpClose();
fd = null;
@ -265,6 +266,7 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
*/
protected void close() {
if (fd != null) {
SocketCleanable.unregister(fd);
datagramSocketClose();
ResourceManager.afterUdpClose();
fd = null;
@ -275,11 +277,6 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
return (fd == null) ? true : false;
}
@SuppressWarnings("deprecation")
protected void finalize() {
close();
}
/**
* set a value - since we only support (setting) binary options
* here, o must be a Boolean

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,17 +25,18 @@
package java.net;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileDescriptor;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import sun.net.ConnectionResetException;
import sun.net.NetHooks;
import sun.net.ResourceManager;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
/**
* Default Socket Implementation. This implementation does
@ -136,6 +137,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
fd = new FileDescriptor();
try {
socketCreate(false);
SocketCleanable.register(fd);
} catch (IOException ioe) {
ResourceManager.afterUdpClose();
fd = null;
@ -144,6 +146,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
} else {
fd = new FileDescriptor();
socketCreate(true);
SocketCleanable.register(fd);
}
if (socket != null)
socket.setCreated();
@ -643,14 +646,6 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
socketSendUrgentData (data);
}
/**
* Cleans up if the user forgets to close it.
*/
@SuppressWarnings("deprecation")
protected void finalize() throws IOException {
close();
}
/*
* "Acquires" and returns the FileDescriptor for this impl
*
@ -748,6 +743,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
* Close the socket (and release the file descriptor).
*/
protected void socketClose() throws IOException {
SocketCleanable.unregister(fd);
socketClose0(false);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -549,6 +549,7 @@ class ServerSocket implements java.io.Closeable {
si.address = new InetAddress();
si.fd = new FileDescriptor();
getImpl().accept(si);
SocketCleanable.register(si.fd); // raw fd has been set
SecurityManager security = System.getSecurityManager();
if (security != null) {

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.net;
import jdk.internal.misc.JavaIOFileDescriptorAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.ref.CleanerFactory;
import jdk.internal.ref.PhantomCleanable;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.ref.Cleaner;
/**
* Cleanup for a socket/datagramsocket FileDescriptor when it becomes phantom reachable.
* Create a cleanup if the raw fd != -1. Windows closes sockets using the fd.
* Subclassed from {@code PhantomCleanable} so that {@code clear} can be
* called to disable the cleanup when the socket fd is closed by any means
* other than calling {@link FileDescriptor#close}.
* Otherwise, it would incorrectly close the handle or fd after it has been reused.
*/
final class SocketCleanable extends PhantomCleanable<Object> {
// Access to FileDescriptor internals
private static final JavaIOFileDescriptorAccess fdAccess =
SharedSecrets.getJavaIOFileDescriptorAccess();
// Native function to call NET_SocketClose(fd)
private static native void cleanupClose0(int fd) throws IOException;
// The raw fd to close
private final int fd;
/**
* Register a socket specific Cleanable with the FileDescriptor
* if the FileDescriptor is non-null and the raw fd is != -1.
*
* @param fdo the FileDescriptor; may be null
*/
static void register(FileDescriptor fdo) {
if (fdo != null) {
int fd = fdAccess.get(fdo);
if (fd != -1) {
fdAccess.registerCleanup(fdo,
new SocketCleanable(fdo, CleanerFactory.cleaner(), fd));
}
}
}
/**
* Unregister a Cleanable from the FileDescriptor.
* @param fdo the FileDescriptor; may be null
*/
static void unregister(FileDescriptor fdo) {
if (fdo != null) {
fdAccess.unregisterCleanup(fdo);
}
}
/**
* Constructor for a phantom cleanable reference.
*
* @param obj the object to monitor
* @param cleaner the cleaner
* @param fd file descriptor to close
*/
private SocketCleanable(Object obj, Cleaner cleaner, int fd) {
super(obj, cleaner);
this.fd = fd;
}
/**
* Close the native handle or fd.
*/
@Override
protected void performCleanup() {
try {
cleanupClose0(fd);
} catch (IOException ioe) {
throw new UncheckedIOException("close", ioe);
}
}
}

View File

@ -610,7 +610,7 @@ public final class Instant
* <p>
* The epoch second count is a simple incrementing count of seconds where
* second 0 is 1970-01-01T00:00:00Z.
* The nanosecond part of the day is returned by {@link #getNano}.
* The nanosecond part is returned by {@link #getNano}.
*
* @return the seconds from the epoch of 1970-01-01T00:00:00Z
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,6 +27,8 @@ package jdk.internal.misc;
import java.io.FileDescriptor;
import java.io.IOException;
import jdk.internal.ref.PhantomCleanable;
/*
* @author Chris Hegarty
*/
@ -38,6 +40,8 @@ public interface JavaIOFileDescriptorAccess {
public boolean getAppend(FileDescriptor fdo);
public void close(FileDescriptor fdo) throws IOException;
public void registerCleanup(FileDescriptor fdo);
public void registerCleanup(FileDescriptor fdo, PhantomCleanable<Object> cleanable);
public void unregisterCleanup(FileDescriptor fdo);
// Only valid on Windows
public void setHandle(FileDescriptor fdo, long handle);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -115,9 +115,13 @@ class SharedFileLockTable extends FileLockTable {
// File key for the file that this channel is connected to
private final FileKey fileKey;
// Locks obtained for this channel
private final Set<FileLock> locks;
SharedFileLockTable(Channel channel, FileDescriptor fd) throws IOException {
this.channel = channel;
this.fileKey = FileKey.create(fd);
this.locks = new HashSet<FileLock>();
}
@Override
@ -135,6 +139,7 @@ class SharedFileLockTable extends FileLockTable {
if (prev == null) {
// we successfully created the key so we add the file lock
list.add(new FileLockReference(fl, queue, fileKey));
locks.add(fl);
break;
}
}
@ -151,6 +156,7 @@ class SharedFileLockTable extends FileLockTable {
if (list == current) {
checkList(list, fl.position(), fl.size());
list.add(new FileLockReference(fl, queue, fileKey));
locks.add(fl);
break;
}
list = current;
@ -187,6 +193,7 @@ class SharedFileLockTable extends FileLockTable {
assert (lock != null) && (lock.acquiredBy() == channel);
ref.clear();
list.remove(index);
locks.remove(fl);
break;
}
index++;
@ -220,6 +227,8 @@ class SharedFileLockTable extends FileLockTable {
// once the lock list is empty we remove it from the map
removeKeyIfEmpty(fileKey, list);
locks.clear();
}
}
return result;
@ -238,6 +247,8 @@ class SharedFileLockTable extends FileLockTable {
if (lock == fromLock) {
ref.clear();
list.set(index, new FileLockReference(toLock, queue, fileKey));
locks.remove(fromLock);
locks.add(toLock);
break;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -91,6 +91,14 @@ public final class FileDescriptor {
fdo.registerCleanup();
}
public void registerCleanup(FileDescriptor fdo, PhantomCleanable<Object> cleanup) {
fdo.registerCleanup(cleanup);
}
public void unregisterCleanup(FileDescriptor fdo) {
fdo.unregisterCleanup();
}
public void setHandle(FileDescriptor fdo, long handle) {
throw new UnsupportedOperationException();
}
@ -105,7 +113,7 @@ public final class FileDescriptor {
/**
* Cleanup in case FileDescriptor is not explicitly closed.
*/
private FDCleanup cleanup;
private PhantomCleanable<Object> cleanup;
/**
* Constructs an (invalid) FileDescriptor
@ -206,16 +214,44 @@ public final class FileDescriptor {
}
/**
* Register a cleanup for the current raw fd.
* Register a cleanup for the current handle.
* Used directly in java.io and indirectly via fdAccess.
* The cleanup should be registered after the fd is set in the FileDescriptor.
* The cleanup should be registered after the handle is set in the FileDescriptor.
*/
@SuppressWarnings("unchecked")
synchronized void registerCleanup() {
void registerCleanup() {
registerCleanup(null);
}
/**
* Register a cleanup for the current handle.
* Used directly in java.io and indirectly via fdAccess.
* The cleanup should be registered after the handle is set in the FileDescriptor.
* @param newCleanable a PhantomCleanable to register
*/
@SuppressWarnings("unchecked")
synchronized void registerCleanup(PhantomCleanable<Object> newCleanable) {
if (cleanup != null) {
cleanup.clear();
}
cleanup = FDCleanup.create(this);
cleanup = (newCleanable == null) ? FDCleanup.create(this) : newCleanable;
}
/**
* Unregister a cleanup for the current raw fd.
* Used directly in java.io and indirectly via fdAccess.
* Normally {@link #close()} should be used except in cases where
* it is certain the caller will close the raw fd and the cleanup
* must not close the raw fd. {@link #unregisterCleanup()} must be
* called before the raw fd is closed to prevent a race that makes
* it possible for the fd to be reallocated to another use and later
* the cleanup might be invoked.
*/
synchronized void unregisterCleanup() {
if (cleanup != null) {
cleanup.clear();
}
cleanup = null;
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,6 +27,7 @@
#include <string.h>
#include "net_util.h"
#include "java_net_SocketCleanable.h"
JNIEXPORT jboolean JNICALL
Java_java_net_AbstractPlainSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
@ -45,3 +46,15 @@ Java_jdk_net_Sockets_isReusePortAvailable0(JNIEnv* env, jclass c1)
{
return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
}
/*
* Class: java_net_SocketCleanable
* Method: cleanupClose0
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_java_net_SocketCleanable_cleanupClose0(JNIEnv *env, jclass c1, jint fd)
{
NET_SocketClose(fd);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -90,7 +90,15 @@ public final class FileDescriptor {
}
public void registerCleanup(FileDescriptor fdo) {
fdo.registerCleanup();
fdo.registerCleanup(null);
}
public void registerCleanup(FileDescriptor fdo, PhantomCleanable<Object> cleanup) {
fdo.registerCleanup(cleanup);
}
public void unregisterCleanup(FileDescriptor fdo) {
fdo.unregisterCleanup();
}
public void setHandle(FileDescriptor fdo, long handle) {
@ -107,7 +115,7 @@ public final class FileDescriptor {
/**
* Cleanup in case FileDescriptor is not explicitly closed.
*/
private FDCleanup cleanup;
private PhantomCleanable<Object> cleanup;
/**
* Constructs an (invalid) FileDescriptor
@ -217,11 +225,39 @@ public final class FileDescriptor {
* The cleanup should be registered after the handle is set in the FileDescriptor.
*/
@SuppressWarnings("unchecked")
synchronized void registerCleanup() {
void registerCleanup() {
registerCleanup(null);
}
/**
* Register a cleanup for the current handle.
* Used directly in java.io and indirectly via fdAccess.
* The cleanup should be registered after the handle is set in the FileDescriptor.
* @param newCleanable a PhantomCleanable to register
*/
@SuppressWarnings("unchecked")
synchronized void registerCleanup(PhantomCleanable<Object> newCleanable) {
if (cleanup != null) {
cleanup.clear();
}
cleanup = FDCleanup.create(this);
cleanup = (newCleanable == null) ? FDCleanup.create(this) : newCleanable;
}
/**
* Unregister a cleanup for the current raw fd.
* Used directly in java.io and indirectly via fdAccess.
* Normally {@link #close()} should be used except in cases where
* it is certain the caller will close the raw fd and the cleanup
* must not close the raw fd. {@link #unregisterCleanup()} must be
* called before the raw fd is closed to prevent a race that makes
* it possible for the fd to be reallocated to another use and later
* the cleanup might be invoked.
*/
synchronized void unregisterCleanup() {
if (cleanup != null) {
cleanup.clear();
}
cleanup = null;
}
/**
@ -319,16 +355,21 @@ public final class FileDescriptor {
/**
* Cleanup for a FileDescriptor when it becomes phantom reachable.
* Create a cleanup if handle != -1.
* Windows closes files using handles and sockets via the fd.
* Network FileDescriptors using socket fd must provide their
* own PhantomCleanable to {@link #registerCleanup}.
* This implementation only clears thehandles.
* <p>
* Subclassed from {@code PhantomCleanable} so that {@code clear} can be
* called to disable the cleanup when the fd is closed by any means other
* called to disable the cleanup when the handle is closed by any means other
* than calling {@link FileDescriptor#close}.
* Otherwise, it may close the handle after it has been reused.
* Otherwise, it may incorrectly close the handle after it has been reused.
*/
static final class FDCleanup extends PhantomCleanable<Object> {
private final long handle;
static FDCleanup create(FileDescriptor fdo) {
return fdo.handle == -1
return fdo.handle == -1L
? null
: new FDCleanup(fdo, CleanerFactory.cleaner(), fdo.handle);
}

View File

@ -86,6 +86,7 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
fd1 = new FileDescriptor();
try {
super.create();
SocketCleanable.register(fd1);
} catch (SocketException e) {
fd1 = null;
throw e;
@ -160,6 +161,8 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
protected void close() {
if (fd != null || fd1 != null) {
SocketCleanable.unregister(fd);
SocketCleanable.unregister(fd1);
datagramSocketClose();
ResourceManager.afterUdpClose();
fd = null;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,6 +24,8 @@
*/
#include <jni.h>
#include "net_util.h"
#include "java_net_SocketCleanable.h"
JNIEXPORT jboolean JNICALL
Java_java_net_AbstractPlainSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
@ -45,3 +47,15 @@ Java_jdk_net_Sockets_isReusePortAvailable0(JNIEnv* env, jclass c1)
// SO_REUSEPORT is not supported on Windows
return JNI_FALSE;
}
/*
* Class: java_net_SocketCleanable
* Method: cleanupClose0
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_java_net_SocketCleanable_cleanupClose0(JNIEnv *env, jclass c1, jint fd)
{
NET_SocketClose(fd);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -41,8 +41,8 @@ import jdk.test.lib.process.OutputAnalyzer;
public class MultiReleaseJars {
static final int MAJOR_VERSION = Runtime.version().major();
static final String MAJOR_VERSION_STRING = String.valueOf(Runtime.version().major());
static final int MAJOR_VERSION = 10; // Runtime.version().major();
static final String MAJOR_VERSION_STRING = String.valueOf(MAJOR_VERSION);
static String[] getMain() {
String[] sts = {

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary The characters FFFE and FFFF should not be in a UnicodeBlock. They
* should be in a null block.
* @bug 4404588
* @author John O'Conner
*/
public class Bug4404588 {
public Bug4404588() {
// do nothing
}
public static void main(String[] args) {
Bug4404588 test = new Bug4404588();
test.run();
}
/**
* Test the correct data against what Character reports.
*/
void run() {
Character ch;
Character.UnicodeBlock block;
for(int x=0; x < charData.length; x++) {
ch = (Character)charData[x][0];
block = (Character.UnicodeBlock)charData[x][1];
if (Character.UnicodeBlock.of(ch.charValue()) != block) {
System.err.println("Error: block = " + block);
System.err.println("Character.UnicodeBlock.of(" +
Integer.toHexString(ch.charValue()) +") = " +
Character.UnicodeBlock.of(ch.charValue()));
throw new RuntimeException("Blocks aren't equal.");
}
}
System.out.println("Passed.");
}
/**
* Contains the character data to test. The first object is the character.
* The next object is the UnicodeBlock to which it should belong.
*/
Object[][] charData = {
{ new Character('\uFFFE'), Character.UnicodeBlock.SPECIALS },
{ new Character('\uFFFF'), Character.UnicodeBlock.SPECIALS },
};
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8196740
* @summary Check j.l.Character.digit(int,int) for Latin1 characters
*/
public class Latin1Digit {
public static void main(String[] args) throws Exception {
for (int ch = 0; ch < 256; ++ch) {
for (int radix = -256; radix <= 256; ++radix) {
test(ch, radix);
}
test(ch, Integer.MIN_VALUE);
test(ch, Integer.MAX_VALUE);
}
}
static void test(int ch, int radix) throws Exception {
int d1 = Character.digit(ch, radix);
int d2 = canonicalDigit(ch, radix);
if (d1 != d2) {
throw new Exception("Wrong result for char="
+ ch + " (" + (char)ch + "), radix="
+ radix + "; " + d1 + " != " + d2);
}
}
// canonical version of Character.digit(int,int) for Latin1
static int canonicalDigit(int ch, int radix) {
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
return -1;
}
if (ch >= '0' && ch <= '9' && ch < (radix + '0')) {
return ch - '0';
}
if (ch >= 'A' && ch <= 'Z' && ch < (radix + 'A' - 10)) {
return ch - 'A' + 10;
}
if (ch >= 'a' && ch <= 'z' && ch < (radix + 'a' - 10)) {
return ch - 'a' + 10;
}
return -1;
}
}

View File

@ -0,0 +1,856 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4533872 4985214 4985217 5017268 5017280
* @summary Unit tests for supplementary character support (JSR-204)
* @compile Supplementary.java
* @run main/timeout=600 Supplementary
*/
public class Supplementary {
private static final char MIN_HIGH = '\uD800';
private static final char MAX_HIGH = '\uDBFF';
private static final char MIN_LOW = MAX_HIGH + 1;
private static final char MAX_LOW = '\uDFFF';
private static final int MIN_CODE_POINT = 0x000000;
private static final int MIN_SUPPLEMENTARY = 0x010000;
private static final int MAX_SUPPLEMENTARY = 0x10ffff;
public static void main(String[] args) {
// Do not change the order of test method calls since there
// are some interdependencies.
testConstants();
test00();
// Store all Unicode code points, except for surrogate code
// points, in cu[] through the loops below. Then, use the data
// for code point/code unit conversion and other tests later.
char[] cu = new char[(MAX_SUPPLEMENTARY+1) * 2];
int length = test01(cu);
String str = new String(cu, 0, length);
cu = null;
test02(str);
test03(str.toCharArray());
test04(str);
test05(str);
// Test unpaired surrogates
testUnpaired();
// Test exceptions
testExceptions00();
testExceptions01(str);
testExceptions02(str.toCharArray());
}
static void testConstants() {
if (Character.MIN_HIGH_SURROGATE != MIN_HIGH) {
constantError("MIN_HIGH_SURROGATE", Character.MIN_HIGH_SURROGATE, MIN_HIGH);
}
if (Character.MAX_HIGH_SURROGATE != MAX_HIGH) {
constantError("MAX_HIGH_SURROGATE", Character.MAX_HIGH_SURROGATE, MAX_HIGH);
}
if (Character.MIN_LOW_SURROGATE != MIN_LOW) {
constantError("MIN_LOW_SURROGATE", Character.MIN_LOW_SURROGATE, MIN_LOW);
}
if (Character.MAX_LOW_SURROGATE != MAX_LOW) {
constantError("MAX_LOW_SURROGATE", Character.MAX_LOW_SURROGATE, MAX_LOW);
}
if (Character.MIN_SURROGATE != MIN_HIGH) {
constantError("MIN_SURROGATE", Character.MIN_SURROGATE, MIN_HIGH);
}
if (Character.MAX_SURROGATE != MAX_LOW) {
constantError("MAX_SURROGATE", Character.MAX_SURROGATE, MAX_LOW);
}
if (Character.MIN_SUPPLEMENTARY_CODE_POINT != MIN_SUPPLEMENTARY) {
constantError("MIN_SUPPLEMENTARY_CODE_POINT",
Character.MIN_SUPPLEMENTARY_CODE_POINT, MIN_SUPPLEMENTARY);
}
if (Character.MIN_CODE_POINT != MIN_CODE_POINT) {
constantError("MIN_CODE_POINT", Character.MIN_CODE_POINT, MIN_CODE_POINT);
}
if (Character.MAX_CODE_POINT != MAX_SUPPLEMENTARY) {
constantError("MAX_CODE_POINT", Character.MAX_CODE_POINT, MAX_SUPPLEMENTARY);
}
}
static void constantError(String name, int value, int expectedValue) {
throw new RuntimeException("Character." + name + " has a wrong value: got "
+ toHexString(value)
+ ", expected " + toHexString(expectedValue));
}
/*
* Test isValidCodePoint(int)
* isSupplementaryCodePoint(int)
* charCount(int)
*/
static void test00() {
for (int cp = -MAX_SUPPLEMENTARY; cp <= MAX_SUPPLEMENTARY*2; cp++) {
boolean isValid = cp >= 0 && cp <= MAX_SUPPLEMENTARY;
if (Character.isValidCodePoint(cp) != isValid) {
throw new RuntimeException("isValidCodePoint failed with "
+ toHexString(cp));
}
boolean isSupplementary = cp >= MIN_SUPPLEMENTARY && cp <= MAX_SUPPLEMENTARY;
if (Character.isSupplementaryCodePoint(cp) != isSupplementary) {
throw new RuntimeException("isSupplementaryCodePoint failed with "
+ toHexString(cp));
}
int len = Character.charCount(cp);
if (isValid) {
if ((isSupplementary && len != 2)
|| (!isSupplementary && len != 1)) {
throw new RuntimeException("wrong character length "+len+" for "
+ toHexString(cp));
}
} else if (len != 1 && len != 2) {
throw new RuntimeException("wrong character length "+len+" for "
+ toHexString(cp));
}
}
}
/**
* Test toChar(int)
* toChar(int, char[], int)
* isHighSurrogate(char)
* isLowSurrogate(char)
* isSurrogatePair(int, int)
*
* While testing those methods, this method generates all Unicode
* code points (except for surrogate code points) and store them
* in cu.
*
* @return the number of code units generated in cu
*/
static int test01(char[] cu) {
int index = 0;
// Test toChar(int)
// toChar(int, char[], int)
// isHighSurrogate(char)
// isLowSurrogate(char)
// with BMP code points
for (int i = 0; i <= Character.MAX_VALUE; i++) {
char[] u = Character.toChars(i);
if (u.length != 1 || u[0] != i) {
throw new RuntimeException("wrong toChars(int) result for BMP: "
+ toHexString("u", u));
}
int n = Character.toChars(i, cu, index);
if (n != 1 || cu[index] != i) {
throw new RuntimeException("wrong toChars(int, char[], int) result for BMP:"
+ " len=" + n
+ ", cu["+index+"]="+toHexString(cu[index]));
}
boolean isHigh = i >= MIN_HIGH && i <= MAX_HIGH;
if (Character.isHighSurrogate((char) i) != isHigh) {
throw new RuntimeException("wrong high-surrogate test for "
+ toHexString(i));
}
boolean isLow = i >= MIN_LOW && i <= MAX_LOW;
if (Character.isLowSurrogate((char)i) != isLow) {
throw new RuntimeException("wrong low-surrogate test for "
+ toHexString(i));
}
if (!isHigh && !isLow) {
index++;
}
}
// Test isSurrogatePair with all surrogate pairs
// Test toChars(int)
// toChars(int, char[], int)
// with all supplementary characters
int supplementary = MIN_SUPPLEMENTARY;
for (int i = Character.MAX_VALUE/2; i <= Character.MAX_VALUE; i++) {
char hi = (char) i;
boolean isHigh = Character.isHighSurrogate(hi);
for (int j = Character.MAX_VALUE/2; j <= Character.MAX_VALUE; j++) {
char lo = (char) j;
boolean isLow = Character.isLowSurrogate(lo);
boolean isSurrogatePair = isHigh && isLow;
if (Character.isSurrogatePair(hi, lo) != isSurrogatePair) {
throw new RuntimeException("wrong surrogate pair test for hi="
+ toHexString(hi)
+ ", lo="+toHexString(lo));
}
if (isSurrogatePair) {
int cp = Character.toCodePoint(hi, lo);
if (cp != supplementary) {
throw new RuntimeException("wrong code point: got "
+ toHexString(cp)
+ ", expected="
+ toHexString(supplementary));
}
char[] u = Character.toChars(cp);
if (u.length != 2 || u[0] != hi || u[1] != lo) {
throw new RuntimeException("wrong toChars(int) result for supplementary: "+
toHexString("u", u));
}
int n = Character.toChars(cp, cu, index);
if (n != 2 || cu[index] != hi || cu[index+1] != lo) {
throw new RuntimeException("wrong toChars(int, char[], int) result "
+ "for supplementary: len=" + n
+ ", cu["+index+"]=" + toHexString(cu[index])
+ ", cu["+(index+1)+"]=" + toHexString(cu[index+1]));
}
index += n;
supplementary++;
}
}
}
if (supplementary != MAX_SUPPLEMENTARY + 1) {
throw new RuntimeException("wrong supplementary count (supplementary="
+ toHexString(supplementary)+")");
}
int nCodeUnits = Character.MAX_VALUE + 1 - (MAX_LOW - MIN_HIGH + 1)
+ ((MAX_SUPPLEMENTARY - MIN_SUPPLEMENTARY + 1) * 2);
if (index != nCodeUnits) {
throw new RuntimeException("wrong number of code units: " + index
+ ", expected " + nCodeUnits);
}
return index;
}
/**
* Test codePointAt(CharSequence, int)
* codePointBefore(CharSequence, int)
*/
static void test02(CharSequence cs) {
int cp = 0;
int ch;
for (int i = 0; i < cs.length(); i += Character.charCount(ch)) {
ch = Character.codePointAt(cs, i);
if (ch != cp) {
throw new RuntimeException("wrong codePointAt(CharSequence, "+i+") value: got "
+ toHexString(ch)
+ ", expected "+toHexString(cp));
}
cp++;
// Skip surrogates
if (cp == MIN_HIGH) {
cp = MAX_LOW + 1;
}
}
cp--;
for (int i = cs.length(); i > 0; i -= Character.charCount(ch)) {
ch = Character.codePointBefore(cs, i);
if (ch != cp) {
throw new RuntimeException("codePointBefore(CharSequence, "+i+") returned "
+ toHexString(ch)
+ ", expected " + toHexString(cp));
}
cp--;
// Skip surrogates
if (cp == MAX_LOW) {
cp = MIN_HIGH - 1;
}
}
}
/**
* Test codePointAt(char[], int)
* codePointAt(char[], int, int)
* codePointBefore(char[], int)
* codePointBefore(char[], int, int)
*/
static void test03(char[] a) {
int cp = 0;
int ch;
for (int i = 0; i < a.length; i += Character.charCount(ch)) {
ch = Character.codePointAt(a, i);
if (ch != cp) {
throw new RuntimeException("codePointAt(char[], "+i+") returned "
+ toHexString(ch)
+ ", expected "+toHexString(cp));
}
int x = Character.codePointAt(a, i, i+1);
if (x != a[i]) {
throw new RuntimeException(String.format(
"codePointAt(char[], %d, %d) returned 0x%04x, expected 0x%04x\n",
i, i+1, x, (int)a[i]));
}
cp++;
// Skip surrogates
if (cp == MIN_HIGH) {
cp = MAX_LOW + 1;
}
}
cp--;
for (int i = a.length; i > 0; i -= Character.charCount(ch)) {
ch = Character.codePointBefore(a, i);
if (ch != cp) {
throw new RuntimeException("codePointBefore(char[], "+i+") returned "
+ toHexString(ch)
+ ", expected " + toHexString(cp));
}
int x = Character.codePointBefore(a, i, i-1);
if (x != a[i-1]) {
throw new RuntimeException(String.format(
"codePointAt(char[], %d, %d) returned 0x%04x, expected 0x%04x\n",
i, i-1, x, (int)a[i-1]));
}
cp--;
// Skip surrogates
if (cp == MAX_LOW) {
cp = MIN_HIGH - 1;
}
}
}
/**
* Test codePointCount(CharSequence, int, int)
* codePointCount(char[], int, int, int, int)
*/
static void test04(String str) {
int length = str.length();
char[] a = str.toCharArray();
for (int i = 0; i <= length; i += 99, length -= 29999) {
int n = Character.codePointCount(str, i, length);
int m = codePointCount(str.substring(i, length));
checkCodePointCount(str, n, m);
n = Character.codePointCount(a, i, length - i);
checkCodePointCount(a, n, m);
}
// test special cases
length = str.length();
int n = Character.codePointCount(str, 0, 0);
checkCodePointCount(str, n, 0);
n = Character.codePointCount(str, length, length);
checkCodePointCount(str, n, 0);
n = Character.codePointCount(a, 0, 0);
checkCodePointCount(a, n, 0);
n = Character.codePointCount(a, length, 0);
checkCodePointCount(a, n, 0);
}
// This method assumes that Character.codePointAt() and
// Character.charCount() work correctly.
private static int codePointCount(CharSequence seq) {
int n = 0, len;
for (int i = 0; i < seq.length(); i += len) {
int codepoint = Character.codePointAt(seq, i);
n++;
len = Character.charCount(codepoint);
}
return n;
}
private static void checkCodePointCount(Object data, int n, int expected) {
String type = getType(data);
if (n != expected) {
throw new RuntimeException("codePointCount(" + type + "...) returned " + n
+ ", expected " + expected);
}
}
/**
* Test offsetByCodePoints(CharSequence, int, int)
* offsetByCodePoints(char[], int, int, int, int)
*
* This test case assumes that Character.codePointCount()s work
* correctly.
*/
static void test05(String str) {
int length = str.length();
char[] a = str.toCharArray();
for (int i = 0; i <= length; i += 99, length -= 29999) {
int nCodePoints = Character.codePointCount(a, i, length - i);
int index;
// offsetByCodePoints(CharSequence, int, int)
int expectedHighIndex = length;
// For forward CharSequence scan, we need to adjust the
// expected index in case the last char in the text range
// is a high surrogate and forms a valid supplementary
// code point with the next char.
if (length < a.length) {
int cp = Character.codePointAt(a, length - 1);
if (Character.isSupplementaryCodePoint(cp)) {
expectedHighIndex++;
}
}
index = Character.offsetByCodePoints(str, i, nCodePoints);
checkNewIndex(str, nCodePoints, index, expectedHighIndex);
int expectedLowIndex = i;
if (i > 0) {
int cp = Character.codePointBefore(a, i + 1);
if (Character.isSupplementaryCodePoint(cp)) {
expectedLowIndex--;
}
}
index = Character.offsetByCodePoints(str, length, -nCodePoints);
checkNewIndex(str, -nCodePoints, index, expectedLowIndex);
// offsetByCodePoints(char[], int, int, int, int)
int start = Math.max(0, i-1);
int limit = Math.min(a.length, length+1);
index = Character.offsetByCodePoints(a, start, limit - start,
i, nCodePoints);
checkNewIndex(a, nCodePoints, index, expectedHighIndex);
if (length != expectedHighIndex) {
index = Character.offsetByCodePoints(a, start, length - start,
i, nCodePoints);
checkNewIndex(a, nCodePoints, index, length);
}
index = Character.offsetByCodePoints(a, start, limit - start,
length, -nCodePoints);
checkNewIndex(a, -nCodePoints, index, expectedLowIndex);
if (i != expectedLowIndex) {
index = Character.offsetByCodePoints(a, i, limit - i,
length, -nCodePoints);
checkNewIndex(a, -nCodePoints, index, i);
}
}
// test special cases for 0-length text ranges.
length = str.length();
int index = Character.offsetByCodePoints(str, 0, 0);
checkNewIndex(str, 0, index, 0);
index = Character.offsetByCodePoints(str, length, 0);
checkNewIndex(str, 0, index, length);
index = Character.offsetByCodePoints(a, 0, 0, 0, 0);
checkNewIndex(a, 0, index, 0);
index = Character.offsetByCodePoints(a, 0, length, 0, 0);
checkNewIndex(a, 0, index, 0);
index = Character.offsetByCodePoints(a, 0, length, length, 0);
checkNewIndex(a, 0, index, length);
index = Character.offsetByCodePoints(a, length, 0, length, 0);
checkNewIndex(a, 0, index, length);
}
private static void checkNewIndex(Object data, int offset, int result, int expected) {
String type = getType(data);
String offsetType = (offset > 0) ? "positive" : (offset < 0) ? "negative" : "0";
if (result != expected) {
throw new RuntimeException("offsetByCodePoints(" + type + ", ...) ["
+ offsetType + " offset]"
+ " returned " + result
+ ", expected " + expected);
}
}
// Test codePointAt(CharSequence, int)
// codePointBefore(CharSequence, int)
// codePointAt(char[], int)
// codePointBefore(char[], int)
// toChar(int)
// toChar(int, char[], int)
// with unpaired surrogates
static void testUnpaired() {
testCodePoint("\uD800", new int[] { 0xD800 });
testCodePoint("\uDC00", new int[] { 0xDC00 });
testCodePoint("a\uD800", new int[] { 'a', 0xD800 });
testCodePoint("a\uDC00", new int[] { 'a', 0xDC00 });
testCodePoint("\uD800a", new int[] { 0xD800, 'a' });
testCodePoint("\uDBFFa", new int[] { 0xDBFF, 'a' });
testCodePoint("a\uD800\uD801", new int[] { 'a', 0xD800, 0xD801 });
testCodePoint("a\uD800x\uDC00", new int[] { 'a', 0xD800, 'x', 0xDC00 });
testCodePoint("\uDC00\uD800", new int[] { 0xDC00, 0xD800 });
testCodePoint("\uD800\uDC00\uDC00", new int[] { 0x10000, 0xDC00 });
testCodePoint("\uD800\uD800\uDC00", new int[] { 0xD800, 0x10000 });
testCodePoint("\uD800\uD800\uD800\uD800\uDC00\uDC00\uDC00\uDC00",
new int[] { 0xD800, 0xD800, 0xD800, 0x10000, 0xDC00, 0xDC00, 0xDC00});
}
static void testCodePoint(String str, int[] codepoints) {
int c;
// Test Character.codePointAt/Before(CharSequence, int)
int j = 0;
for (int i = 0; i < str.length(); i += Character.charCount(c)) {
c = Character.codePointAt(str, i);
if (c != codepoints[j++]) {
throw new RuntimeException("codePointAt(CharSequence, " + i + ") returned "
+ toHexString(c)
+ ", expected " + toHexString(codepoints[j-1]));
}
}
if (j != codepoints.length) {
throw new RuntimeException("j != codepoints.length after codePointAt(CharSequence, int)"
+ " (j=" + j + ")"
+ ", expected: " + codepoints.length);
}
j = codepoints.length;
for (int i = str.length(); i > 0 ; i -= Character.charCount(c)) {
c = Character.codePointBefore(str, i);
if (c != codepoints[--j]) {
throw new RuntimeException("codePointBefore(CharSequence, " + i + ") returned "
+ toHexString(c)
+ ", expected " + toHexString(codepoints[j]));
}
}
if (j != 0) {
throw new RuntimeException("j != 0 after codePointBefore(CharSequence, int)"
+ " (j=" + j + ")");
}
// Test Character.codePointAt/Before(char[], int)
char[] a = str.toCharArray();
j = 0;
for (int i = 0; i < a.length; i += Character.charCount(c)) {
c = Character.codePointAt(a, i);
if (c != codepoints[j++]) {
throw new RuntimeException("codePointAt(char[], " + i + ") returned "
+ toHexString(c)
+ ", expected " + toHexString(codepoints[j-1]));
}
}
if (j != codepoints.length) {
throw new RuntimeException("j != codepoints.length after codePointAt(char[], int)"
+ " (j=" + j + ")"
+ ", expected: " + codepoints.length);
}
j = codepoints.length;
for (int i = a.length; i > 0 ; i -= Character.charCount(c)) {
c = Character.codePointBefore(a, i);
if (c != codepoints[--j]) {
throw new RuntimeException("codePointBefore(char[], " + i + ") returned "
+ toHexString(c)
+ ", expected " + toHexString(codepoints[j]));
}
}
if (j != 0) {
throw new RuntimeException("j != 0 after codePointBefore(char[], int)"
+ " (j=" + j + ")");
}
// Test toChar(int)
j = 0;
for (int i = 0; i < codepoints.length; i++) {
a = Character.toChars(codepoints[i]);
for (int k = 0; k < a.length; k++) {
if (str.charAt(j++) != a[k]) {
throw new RuntimeException("toChars(int) returned " + toHexString("result", a)
+ " from codepoint=" + toHexString(codepoints[i]));
}
}
}
// Test toChars(int, char[], int)
a = new char[codepoints.length * 2];
j = 0;
for (int i = 0; i < codepoints.length; i++) {
int n = Character.toChars(codepoints[i], a, j);
j += n;
}
String s = new String(a, 0, j);
if (!str.equals(s)) {
throw new RuntimeException("toChars(int, char[], int) returned "
+ toHexString("dst", s.toCharArray())
+ ", expected " + toHexString("data", str.toCharArray()));
}
}
// Test toChar(int)
// toChar(int, char[], int)
// for exceptions
static void testExceptions00() {
callToChars1(-1, IllegalArgumentException.class);
callToChars1(MAX_SUPPLEMENTARY + 1, IllegalArgumentException.class);
callToChars3(MAX_SUPPLEMENTARY, null, 0, NullPointerException.class);
callToChars3(-MIN_SUPPLEMENTARY, new char[2], 0, IllegalArgumentException.class);
callToChars3(MAX_SUPPLEMENTARY + 1, new char[2], 0, IllegalArgumentException.class);
callToChars3('A', new char[0], 0, IndexOutOfBoundsException.class);
callToChars3('A', new char[1], -1, IndexOutOfBoundsException.class);
callToChars3('A', new char[1], 1, IndexOutOfBoundsException.class);
callToChars3(MIN_SUPPLEMENTARY, new char[0], 0, IndexOutOfBoundsException.class);
callToChars3(MIN_SUPPLEMENTARY, new char[1], 0, IndexOutOfBoundsException.class);
callToChars3(MIN_SUPPLEMENTARY, new char[2], -1, IndexOutOfBoundsException.class);
callToChars3(MIN_SUPPLEMENTARY, new char[2], 1, IndexOutOfBoundsException.class);
}
static final boolean At = true, Before = false;
/**
* Test codePointAt(CharSequence, int)
* codePointBefore(CharSequence, int)
* codePointCount(CharSequence, int, int)
* offsetByCodePoints(CharSequence, int, int)
* for exceptions
*/
static void testExceptions01(CharSequence cs) {
CharSequence nullSeq = null;
// codePointAt
callCodePoint(At, nullSeq, 0, NullPointerException.class);
callCodePoint(At, cs, -1, IndexOutOfBoundsException.class);
callCodePoint(At, cs, cs.length(), IndexOutOfBoundsException.class);
callCodePoint(At, cs, cs.length()*3, IndexOutOfBoundsException.class);
// codePointBefore
callCodePoint(Before, nullSeq, 0, NullPointerException.class);
callCodePoint(Before, cs, -1, IndexOutOfBoundsException.class);
callCodePoint(Before, cs, 0, IndexOutOfBoundsException.class);
callCodePoint(Before, cs, cs.length()+1, IndexOutOfBoundsException.class);
// codePointCount
callCodePointCount(nullSeq, 0, 0, NullPointerException.class);
callCodePointCount(cs, -1, 1, IndexOutOfBoundsException.class);
callCodePointCount(cs, 0, cs.length()+1, IndexOutOfBoundsException.class);
callCodePointCount(cs, 3, 1, IndexOutOfBoundsException.class);
// offsetByCodePoints
callOffsetByCodePoints(nullSeq, 0, 0, NullPointerException.class);
callOffsetByCodePoints(cs, -1, 1, IndexOutOfBoundsException.class);
callOffsetByCodePoints(cs, cs.length()+1, 1, IndexOutOfBoundsException.class);
callOffsetByCodePoints(cs, 0, cs.length()*2, IndexOutOfBoundsException.class);
callOffsetByCodePoints(cs, cs.length(), 1, IndexOutOfBoundsException.class);
callOffsetByCodePoints(cs, 0, -1, IndexOutOfBoundsException.class);
callOffsetByCodePoints(cs, cs.length(), -cs.length()*2,
IndexOutOfBoundsException.class);
callOffsetByCodePoints(cs, cs.length(), Integer.MIN_VALUE,
IndexOutOfBoundsException.class);
callOffsetByCodePoints(cs, 0, Integer.MAX_VALUE, IndexOutOfBoundsException.class);
}
/**
* Test codePointAt(char[], int)
* codePointAt(char[], int, int)
* codePointBefore(char[], int)
* codePointBefore(char[], int, int)
* codePointCount(char[], int, int)
* offsetByCodePoints(char[], int, int, int, int)
* for exceptions
*/
static void testExceptions02(char[] a) {
char[] nullArray = null;
callCodePoint(At, nullArray, 0, NullPointerException.class);
callCodePoint(At, a, -1, IndexOutOfBoundsException.class);
callCodePoint(At, a, a.length, IndexOutOfBoundsException.class);
callCodePoint(At, a, a.length*3, IndexOutOfBoundsException.class);
callCodePoint(Before, nullArray, 0, NullPointerException.class);
callCodePoint(Before, a, -1, IndexOutOfBoundsException.class);
callCodePoint(Before, a, 0, IndexOutOfBoundsException.class);
callCodePoint(Before, a, a.length+1, IndexOutOfBoundsException.class);
// tests for the methods with limit
callCodePoint(At, nullArray, 0, 1, NullPointerException.class);
callCodePoint(At, a, 0, -1, IndexOutOfBoundsException.class);
callCodePoint(At, a, 0, 0, IndexOutOfBoundsException.class);
callCodePoint(At, a, 0, a.length+1, IndexOutOfBoundsException.class);
callCodePoint(At, a, 2, 1, IndexOutOfBoundsException.class);
callCodePoint(At, a, -1, 1, IndexOutOfBoundsException.class);
callCodePoint(At, a, a.length, 1, IndexOutOfBoundsException.class);
callCodePoint(At, a, a.length*3, 1, IndexOutOfBoundsException.class);
callCodePoint(Before, nullArray, 1, 0, NullPointerException.class);
callCodePoint(Before, a, 2, -1, IndexOutOfBoundsException.class);
callCodePoint(Before, a, 2, 2, IndexOutOfBoundsException.class);
callCodePoint(Before, a, 2, 3, IndexOutOfBoundsException.class);
callCodePoint(Before, a, 2, a.length, IndexOutOfBoundsException.class);
callCodePoint(Before, a, -1, -1, IndexOutOfBoundsException.class);
callCodePoint(Before, a, 0, 0, IndexOutOfBoundsException.class);
callCodePoint(Before, a, a.length+1, a.length-1, IndexOutOfBoundsException.class);
// codePointCount
callCodePointCount(nullArray, 0, 0, NullPointerException.class);
callCodePointCount(a, -1, 1, IndexOutOfBoundsException.class);
callCodePointCount(a, 0, -1, IndexOutOfBoundsException.class);
callCodePointCount(a, 0, a.length+1, IndexOutOfBoundsException.class);
callCodePointCount(a, 1, a.length, IndexOutOfBoundsException.class);
callCodePointCount(a, a.length, 1, IndexOutOfBoundsException.class);
callCodePointCount(a, a.length+1, -1, IndexOutOfBoundsException.class);
// offsetByCodePoints
callOffsetByCodePoints(nullArray, 0, 0, 0, 0, NullPointerException.class);
callOffsetByCodePoints(a, -1, a.length, 1, 1, IndexOutOfBoundsException.class);
callOffsetByCodePoints(a, 0, a.length+1, 1, 1, IndexOutOfBoundsException.class);
callOffsetByCodePoints(a, 10, a.length, 1, 1, IndexOutOfBoundsException.class);
callOffsetByCodePoints(a, 10, a.length-10, 1, 1, IndexOutOfBoundsException.class);
callOffsetByCodePoints(a, 10, 10, 21, 1, IndexOutOfBoundsException.class);
callOffsetByCodePoints(a, 20, -10, 15, 1, IndexOutOfBoundsException.class);
callOffsetByCodePoints(a, 10, 10, 15, 20, IndexOutOfBoundsException.class);
callOffsetByCodePoints(a, 10, 10, 15, -20, IndexOutOfBoundsException.class);
callOffsetByCodePoints(a, 0, a.length, -1, 1, IndexOutOfBoundsException.class);
callOffsetByCodePoints(a, 0, a.length, a.length+1, 1, IndexOutOfBoundsException.class);
callOffsetByCodePoints(a, 0, a.length, 0, a.length*2, IndexOutOfBoundsException.class);
callOffsetByCodePoints(a, 0, a.length, a.length, 1, IndexOutOfBoundsException.class);
callOffsetByCodePoints(a, 0, a.length, 0, -1, IndexOutOfBoundsException.class);
callOffsetByCodePoints(a, 0, a.length, a.length, -a.length*2,
IndexOutOfBoundsException.class);
callOffsetByCodePoints(a, 0, a.length, a.length, Integer.MIN_VALUE,
IndexOutOfBoundsException.class);
callOffsetByCodePoints(a, 0, a.length, 0, Integer.MAX_VALUE,
IndexOutOfBoundsException.class);
}
/**
* Test the 1-arg toChars(int) for exceptions
*/
private static void callToChars1(int codePoint, Class expectedException) {
try {
char[] a = Character.toChars(codePoint);
} catch (Exception e) {
if (expectedException.isInstance(e)) {
return;
}
throw new RuntimeException("Unspecified exception", e);
}
throw new RuntimeException("toChars(int) didn't throw " + expectedException.getName());
}
/**
* Test the 3-arg toChars(int, char[], int) for exceptions
*/
private static void callToChars3(int codePoint, char[] dst, int index,
Class expectedException) {
try {
int n = Character.toChars(codePoint, dst, index);
} catch (Exception e) {
if (expectedException.isInstance(e)) {
return;
}
throw new RuntimeException("Unspecified exception", e);
}
throw new RuntimeException("toChars(int,char[],int) didn't throw "
+ expectedException.getName());
}
private static void callCodePoint(boolean isAt, CharSequence cs, int index,
Class expectedException) {
try {
int c = isAt ? Character.codePointAt(cs, index)
: Character.codePointBefore(cs, index);
} catch (Exception e) {
if (expectedException.isInstance(e)) {
return;
}
throw new RuntimeException("Unspecified exception", e);
}
throw new RuntimeException("codePoint" + (isAt ? "At" : "Before")
+ " didn't throw " + expectedException.getName());
}
private static void callCodePoint(boolean isAt, char[] a, int index,
Class expectedException) {
try {
int c = isAt ? Character.codePointAt(a, index)
: Character.codePointBefore(a, index);
} catch (Exception e) {
if (expectedException.isInstance(e)) {
return;
}
throw new RuntimeException("Unspecified exception", e);
}
throw new RuntimeException("codePoint" + (isAt ? "At" : "Before")
+ " didn't throw " + expectedException.getName());
}
private static void callCodePoint(boolean isAt, char[] a, int index, int limit,
Class expectedException) {
try {
int c = isAt ? Character.codePointAt(a, index, limit)
: Character.codePointBefore(a, index, limit);
} catch (Exception e) {
if (expectedException.isInstance(e)) {
return;
}
throw new RuntimeException("Unspecified exception", e);
}
throw new RuntimeException("codePoint" + (isAt ? "At" : "Before")
+ " didn't throw " + expectedException.getName());
}
private static void callCodePointCount(Object data, int beginIndex, int endIndex,
Class expectedException) {
String type = getType(data);
try {
int n = (data instanceof CharSequence) ?
Character.codePointCount((CharSequence) data, beginIndex, endIndex)
: Character.codePointCount((char[]) data, beginIndex, endIndex);
} catch (Exception e) {
if (expectedException.isInstance(e)) {
return;
}
throw new RuntimeException("Unspecified exception", e);
}
throw new RuntimeException("codePointCount(" + type + "...) didn't throw "
+ expectedException.getName());
}
private static void callOffsetByCodePoints(CharSequence seq, int index, int offset,
Class expectedException) {
try {
int n = Character.offsetByCodePoints(seq, index, offset);
} catch (Exception e) {
if (expectedException.isInstance(e)) {
return;
}
throw new RuntimeException("Unspecified exception", e);
}
throw new RuntimeException("offsetCodePointCounts(CharSequnce...) didn't throw "
+ expectedException.getName());
}
private static void callOffsetByCodePoints(char[] a, int start, int count,
int index, int offset,
Class expectedException) {
try {
int n = Character.offsetByCodePoints(a, start, count, index, offset);
} catch (Exception e) {
if (expectedException.isInstance(e)) {
return;
}
throw new RuntimeException("Unspecified exception", e);
}
throw new RuntimeException("offsetCodePointCounts(char[]...) didn't throw "
+ expectedException.getName());
}
private static String getType(Object data) {
return (data instanceof CharSequence) ? "CharSequence" : "char[]";
}
private static String toHexString(int c) {
return "0x" + Integer.toHexString(c);
}
private static String toHexString(String name, char[] a) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < a.length; i++) {
if (i > 0) {
sb.append(", ");
}
sb.append(name).append('[').append(i).append("]=");
sb.append(toHexString(a[i]));
}
return sb.toString();
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Check that ISO control ranges are valid.
* @run main TestISOControls
* @author John O'Conner
*/
public class TestISOControls {
public static void main(String[] args) {
int[] test = { -1, 0, 0x0010, 0x001F, 0x0020, 0x007E, 0x007F, 0x0090,
0x009F, 0x00A0 };
boolean[] expectedResult = { false, true, true, true, false, false, true,
true, true, false };
for (int x=0; x < test.length; ++x) {
if (Character.isISOControl(test[x]) != expectedResult[x]) {
System.out.println("Fail: " + test[x]);
throw new RuntimeException();
}
}
System.out.println("Passed");
}
}

View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4899380
* @summary Character.is<Property>(int codePoint) methods should return false
* for negative codepoint values. The to<CaseMap> methods should return
* the original codePoint for invalid codePoint ranges.
* @author John O'Conner
*/
public class TestNegativeCodepoint {
public static void main(String[] args) {
int[] invalidCodePoints = { -1, -'a', 0x110000};
for (int x = 0; x < invalidCodePoints.length; ++x) {
int cp = invalidCodePoints[x];
System.out.println("Testing codepoint: " + cp);
// test all of the is<Property> methods
if (Character.isLowerCase(cp) ||
Character.isUpperCase(cp) ||
Character.isTitleCase(cp) ||
Character.isISOControl(cp) ||
Character.isLetterOrDigit(cp) ||
Character.isLetter(cp) ||
Character.isDigit(cp) ||
Character.isDefined(cp) ||
Character.isJavaIdentifierStart(cp) ||
Character.isJavaIdentifierPart(cp) ||
Character.isUnicodeIdentifierStart(cp) ||
Character.isUnicodeIdentifierPart(cp) ||
Character.isIdentifierIgnorable(cp) ||
Character.isSpaceChar(cp) ||
Character.isWhitespace(cp) ||
Character.isMirrored(cp) ||
// test the case mappings
Character.toLowerCase(cp) != cp ||
Character.toUpperCase(cp) != cp ||
Character.toTitleCase(cp) != cp ||
// test directionality of invalid codepoints
Character.getDirectionality(cp) != Character.DIRECTIONALITY_UNDEFINED ||
// test type
Character.getType(cp) != Character.UNASSIGNED ||
// test numeric and digit values
Character.getNumericValue(cp) != -1 ||
Character.digit(cp, 10) != -1 ) {
System.out.println("Failed.");
throw new RuntimeException();
}
// test block value
Character.UnicodeBlock block = null;
try {
block = Character.UnicodeBlock.of(cp);
// if we haven't already thrown an exception because of the illegal
// arguments, then we need to throw one because of an error in the of() method
System.out.println("Failed.");
throw new RuntimeException();
}
catch(IllegalArgumentException e) {
// Since we're testing illegal values, we
// expect to land here every time. If not,
// our test has failed
}
}
System.out.println("Passed.");
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4427146
* @summary Undefined char values should have DIRECTIONALITY_UNDEFINED.
* @author John O'Conner
*/
public class TestUndefinedDirectionality {
public static void main(String[] args) {
int failures = 0;
for (int ch=0x0000;ch <= 0xFFFF; ch++) {
if (!Character.isDefined((char)ch)) {
byte direction = Character.getDirectionality((char)ch);
if (direction != Character.DIRECTIONALITY_UNDEFINED) {
System.err.println("Fail: \\u" + Integer.toString(ch, 16));
failures++;
}
}
}
if (failures != 0) {
throw new RuntimeException("TestUndefinedDirectionality: failed.");
} else {
System.out.println("Passed.");
}
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4453719
* @author John O'Conner
* @summary Undefined char values cannot be Java identifier starts or parts.
*/
public class TestUndefinedIdentifierStartPart {
static int endValue = 0xFFFF;
public static void main(String[] args) {
for (int ch=0x0000; ch <= endValue; ch++) {
if (!Character.isDefined((char)ch) &&
(Character.isJavaIdentifierStart((char)ch) ||
Character.isJavaIdentifierPart((char)ch) ||
Character.isUnicodeIdentifierStart((char)ch) ||
Character.isUnicodeIdentifierPart((char)ch))) {
throw new RuntimeException("Char value " + Integer.toHexString((char)ch));
}
}
System.out.println("Passed");
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4453719
* @author John O'Conner
* @summary Undefined character values should not be ignorable identifiers.
*/
public class TestUndefinedIgnorable {
static int endValue = 0xFFFF;
public static void main(String[] args) {
for (int ch=0x0000; ch <= endValue; ch++) {
if (!Character.isDefined((char)ch) &&
Character.isIdentifierIgnorable((char)ch)) {
throw new RuntimeException("Char value " + Integer.toHexString((char)ch));
}
}
System.out.println("Passed.");
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4453720
* @author John O'Conner
* @summary Undefined char values should not have mirrored property.
*/
public class TestUndefinedMirrored {
static int endValue = 0xFFFF;
public static void main(String[] args) {
for (int ch = 0x0000; ch <= endValue; ch++) {
if (!Character.isDefined((char)ch) && Character.isMirrored((char)ch)) {
throw new RuntimeException("Char value " + Integer.toHexString((char)ch));
}
}
System.out.println("Passed.");
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4453721
* @author John O'Conner
* @summary Unassigned char values should have no numeric properties.
*/
public class TestUndefinedNumeric {
static int endValue = 0xFFFF;
public static void main(String[] args) {
for (int ch = 0x0000; ch <= 0xFFFF; ch++) {
if (!Character.isDefined((char)ch) &&
Character.getNumericValue((char)ch) != -1) {
throw new RuntimeException("Char value " + Integer.toHexString((char)ch));
}
}
System.out.println("Passed.");
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @author John O'Conner
* @bug 4453730
* @summary Undefined character code points do not have titlecase mappings. The
* toTitleCase method should return the argument code value.
*/
public class TestUndefinedTitleCase {
static int endCharValue = 0xFFFF;
public static void main(String[] args) {
for(int ch=0x0000; ch <= endCharValue; ch++) {
if (!Character.isDefined((char)ch) && Character.toTitleCase((char)ch) != (char)ch) {
throw new RuntimeException("Char value " + Integer.toHexString((char)ch));
}
}
System.out.println("Passed");
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4427146
* @summary Some char values that are Unicode spaces are non-breaking. These
* should not be Java whitespaces.
* @author John O'Conner
*/
public class TestWhiteSpace {
public static void main(String[] args) {
// These values should NOT be whitespace
char[] whiteSpace = {'\u00A0', '\u2007', '\u202F'};
for (int x=0;x<whiteSpace.length;x++) {
if (Character.isWhitespace(whiteSpace[x])) {
throw new RuntimeException("Invalid whitespace: \\u" +
Integer.toString((int)whiteSpace[x], 16));
}
}
System.out.println("Passed.");
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package p;
public class A {
}

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public class IsCompatibleWith {
private static boolean fail = false;
private static Package p = p.A.class.getPackage();
public static void main(String [] args) {
IsCompatibleWith s = new IsCompatibleWith();
s.ex("");
s.ex("x.31");
s.ex("5....");
s.ex("10.3a");
s.ex("2.-2");
s.ex("-1.0");
s.ex(".01");
s.t("0");
s.t("1.4");
s.t("1.4.0");
s.f("1.415");
s.t("1.3.1.0.0.0.0.7");
s.t("1.2.02");
s.f("1.4.35");
s.f("33.0");
s.f(new Integer(Integer.MAX_VALUE).toString());
s.ex("2147483648"); // Integer.MAX_VALUE + 1
if (fail == true)
throw new RuntimeException("Test FAILED");
else
System.out.println("Test PASSED");
}
// NumberFormatException expected
private void ex(String s) {
try {
p.isCompatibleWith(s);
} catch (NumberFormatException e) {
System.out.println("PASS: \"" + s + "\"");
e.printStackTrace(System.out);
return;
}
fail = true;
System.err.println("FAIL: Exception missing: \"" + s + "\"");
}
// "true" or "false" expected
private void t(String s) { test(s, true); }
private void f(String s) { test(s, false); }
private void test(String s, boolean expect) {
try {
if (p.isCompatibleWith(s) != expect) {
System.err.println("FAIL: \"" + s + "\", expected: " + expect);
fail = true;
return;
}
} catch (Exception e) {
System.err.println("FAIL: \"" + s + "\"");
e.printStackTrace();
fail = true;
return;
}
System.out.println("PASS: \"" + s + "\"");
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4227825 4785473
* @summary Test behaviour of Package.isCompatibleWith().
* @library /lib/testlibrary
* @library /test/lib
* @build A IsCompatibleWith
* JarUtils
* jdk.test.lib.process.*
* @run main IsCompatibleWithDriver
*/
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.jar.Manifest;
import static java.io.File.pathSeparator;
import java.io.InputStream;
import java.nio.file.Files;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
public class IsCompatibleWithDriver {
public static void main(String args[]) throws Throwable {
Path classes = Paths.get(System.getProperty("test.classes", ""));
Path manifest = Paths.get(System.getProperty("test.src"), "test.mf");
try (InputStream is = Files.newInputStream(manifest)) {
JarUtils.createJarFile(Paths.get("test.jar"), new Manifest(is),
classes, classes.resolve("p"));
}
Files.delete(classes.resolve("p").resolve("A.class"));
OutputAnalyzer analyzer = ProcessTools.executeTestJava("-cp",
"test.jar" + pathSeparator + classes.toString(), "IsCompatibleWith");
System.out.println(analyzer.getOutput());
analyzer.shouldHaveExitValue(0);
}
}

View File

@ -0,0 +1,2 @@
Manifest-version: 1.0
Specification-Version: 1.4

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4349850
* @summary java.lang.Runtime.maxMemory()/availableProcessors()
*/
import java.io.PrintStream;
public class Resources {
static PrintStream out = System.err;
public static void main(String args[]) throws Exception {
Runtime rt = Runtime.getRuntime();
out.println(rt.freeMemory() + " bytes free");
out.println(rt.totalMemory() + " bytes in use");
out.println(rt.maxMemory() + " bytes max");
out.println(rt.availableProcessors() + " processors");
}
}

View File

@ -0,0 +1,263 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4227137
* @summary Basic functional test for virtual-machine shutdown hooks
* @modules java.desktop
* @library /test/lib
* @build jdk.test.lib.process.*
* @run testng Basic
*/
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.io.PrintStream;
import java.io.FileOutputStream;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import jdk.test.lib.process.ProcessTools;
public class Basic {
static Runtime rt = Runtime.getRuntime();
static PrintStream out = System.out;
@DataProvider(name = "testcase")
public Object[][] getTestCase() {
return new Object[][] {
{ "fallThrough", 0, "h1", "f1" },
{ "exit0", 0, "h1", "f1" },
{ "exit0NoHook", 0, "", "f1" },
{ "exit1", 1, "h1", "" },
{ "exit1NoHook", 1, "", "" },
{ "halt", 0, "", "" },
{ "haltNoHook", 0, "", "" },
{ "haltInHook", 0, "h1", "" },
{ "addLate", 0, "h1",
"Caught as expected: java.lang.IllegalStateException: Shutdown in progress" },
{ "removeLate", 0, "h2",
"Caught as expected: java.lang.IllegalStateException: Shutdown in progress" }
};
}
@Test(dataProvider = "testcase")
public void test(String testcase, int exitValue, String hook, String finalizer)
throws Exception {
System.out.println("Test " + testcase);
ProcessTools.executeTestJava("Basic", testcase)
.shouldHaveExitValue(exitValue)
.stdoutShouldMatch(
hook + (hook.isEmpty() ? "" : System.lineSeparator()) + finalizer);
System.out.println("Passed");
}
public static class Fin {
String name;
public Fin(String name) {
this.name = name;
}
public void go() { }
protected void finalize() {
out.println(name);
go();
}
}
public static class Hook extends Thread {
String name;
public Hook(String name) {
this.name = name;
}
public void go() { }
public void run() {
out.println(name);
go();
}
}
public static void fallThrough() throws Exception {
rt.addShutdownHook(new Hook("h1"));
Fin f = new Fin("f1");
rt.runFinalizersOnExit(true);
}
public static void exit0() throws Exception {
rt.addShutdownHook(new Hook("h1"));
Fin f = new Fin("f1");
rt.runFinalizersOnExit(true);
rt.exit(0);
}
public static void exit0NoHook() throws Exception {
Fin f = new Fin("f1");
rt.runFinalizersOnExit(true);
rt.exit(0);
}
/* Finalizer should not run */
public static void exit1() throws Exception {
rt.addShutdownHook(new Hook("h1"));
Fin f = new Fin("f1");
rt.runFinalizersOnExit(true);
rt.exit(1);
}
public static void exit1NoHook() throws Exception {
Fin f = new Fin("f1");
rt.runFinalizersOnExit(true);
rt.exit(1);
}
public static void halt() throws Exception {
rt.addShutdownHook(new Hook("h1") {
public void go() { rt.halt(1); }});
Fin f = new Fin("f1") { public void go() { rt.halt(1); }};
rt.runFinalizersOnExit(true);
rt.halt(0);
}
public static void haltNoHook() throws Exception {
Fin f = new Fin("f1") { public void go() { rt.halt(1); }};
rt.runFinalizersOnExit(true);
rt.halt(0);
}
public static void haltInHook() throws Exception {
rt.addShutdownHook(new Hook("h1") {
public void go() { rt.halt(0); }});
Fin f = new Fin("f1");
rt.runFinalizersOnExit(true);
rt.exit(1);
}
public static void addLate() throws Exception {
rt.addShutdownHook(new Hook("h1") {
public void go() {
try {
rt.addShutdownHook(new Hook("h2"));
} catch (IllegalStateException x) {
out.println("Caught as expected: " + x);
rt.halt(0);
}
}});
rt.exit(1);
}
public static void removeLate() throws Exception {
final Hook h1 = new Hook("h1");
rt.addShutdownHook(new Hook("h2") {
public void go() {
try {
rt.removeShutdownHook(h1);
} catch (IllegalStateException x) {
out.println("Caught as expected: " + x);
rt.halt(0);
}
}});
rt.exit(1);
}
/* The following two methods are provided for manual testing only.
* Neither test is suitable for being run from within the harness.
*/
public static void awt() throws Exception {
final Frame f = new Frame();
final TextArea ta = new TextArea();
Fin fx = new Fin("f1");
rt.runFinalizersOnExit(true);
rt.addShutdownHook(new Hook("h1") {
public void go() {
ta.setText("Hooked!");
out.println("Hooked!");
try {
Thread.sleep(1000);
} catch (InterruptedException x) { }
ta.append("\nSleep 1");
out.println("Sleep 1");
try {
Thread.sleep(1000);
} catch (InterruptedException x) { }
ta.append("\nSleep 2");
out.println("Sleep 2");
}});
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
out.println("Closing...");
ta.setText("Closing...");
try {
Thread.sleep(1000);
} catch (InterruptedException x) { }
f.dispose();
rt.exit(42);
}});
ta.setText("Terminate me!");
f.add(ta);
f.pack();
f.show();
Thread.sleep(10000);
}
/* For INT, HUP, TERM */
public static void stall() throws Exception {
Fin f = new Fin("f1");
rt.runFinalizersOnExit(true);
rt.addShutdownHook(new Hook("h1"));
out.print("Type ^C now: ");
out.flush();
Thread.sleep(100000);
}
public static void main(String[] args) throws Throwable {
Method m = Basic.class.getMethod(args[0], new Class[] { });
String log = null;
try {
log = System.getProperty("log");
} catch (SecurityException x) { }
if (log != null) {
out = new PrintStream(new FileOutputStream(log), true);
}
try {
m.invoke(null, new Object[] { });
} catch (InvocationTargetException x) {
throw x.getTargetException();
}
}
}

View File

@ -0,0 +1,138 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8055206
* @summary Check that each module loaded by the platform loader has the
* proper "accessClassInPackage" RuntimePermissions to access its
* qualified exports.
* @run main CheckAccessClassInPackagePermissions
*/
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleDescriptor.Exports;
import java.net.URL;
import java.security.CodeSigner;
import java.security.CodeSource;
import java.security.Policy;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CheckAccessClassInPackagePermissions {
private static final String[] deployModules = {
"jdk.javaws", "jdk.plugin", "jdk.plugin.server", "jdk.deploy" };
public static void main(String[] args) throws Exception {
// Get the modules in the boot layer loaded by the boot or platform
// loader
ModuleLayer bootLayer = ModuleLayer.boot();
Set<Module> modules = bootLayer.modules()
.stream()
.filter(CheckAccessClassInPackagePermissions::isBootOrPlatformMod)
.collect(Collectors.toSet());
// Create map of target module's qualified export packages
Map<String, List<String>> map = new HashMap<>();
Set<Exports> qualExports =
modules.stream()
.map(Module::getDescriptor)
.map(ModuleDescriptor::exports)
.flatMap(Set::stream)
.filter(Exports::isQualified)
.collect(Collectors.toSet());
for (Exports e : qualExports) {
Set<String> targets = e.targets();
for (String t : targets) {
map.compute(t, (k, ov) -> {
if (ov == null) {
List<String> v = new ArrayList<>();
v.add(e.source());
return v;
} else {
ov.add(e.source());
return ov;
}
});
}
}
// Check if each target module has the right permissions to access
// its qualified exports
Policy policy = Policy.getPolicy();
List<String> deployMods = Arrays.asList(deployModules);
for (Map.Entry<String, List<String>> me : map.entrySet()) {
String moduleName = me.getKey();
// skip deploy modules since they are granted permissions in
// deployment policy file
if (deployMods.contains(moduleName)) {
continue;
}
// is this a module loaded by the platform loader?
Optional<Module> module = bootLayer.findModule(moduleName);
if (!module.isPresent()) {
continue;
}
Module mod = module.get();
if (mod.getClassLoader() != ClassLoader.getPlatformClassLoader()) {
continue;
}
// create ProtectionDomain simulating module
URL url = new URL("jrt:/" + moduleName);
CodeSource cs = new CodeSource(url, (CodeSigner[])null);
ProtectionDomain pd = new ProtectionDomain(cs, null, null, null);
List<String> pkgs = me.getValue();
for (String p : pkgs) {
RuntimePermission rp =
new RuntimePermission("accessClassInPackage." + p);
if (!policy.implies(pd, rp)) {
throw new Exception("Module " + mod + " has not been " +
"granted " + rp);
}
}
}
}
/**
* Returns true if the module's loader is the boot or platform loader.
*/
private static boolean isBootOrPlatformMod(Module m) {
return m.getClassLoader() == null ||
m.getClassLoader() == ClassLoader.getPlatformClassLoader();
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4463345
* @summary Simple test of System.clearProperty
* @run main/othervm ClearProperty
*/
public class ClearProperty {
public static void main(String [] argv) throws Exception {
clearTest();
paramTest();
}
static void clearTest() throws Exception {
System.setProperty("blah", "blech");
if (!System.getProperty("blah").equals("blech"))
throw new RuntimeException("Clear test failed 1");
System.clearProperty("blah");
if (System.getProperty("blah") != null)
throw new RuntimeException("Clear test failed 2");
}
static void paramTest() throws Exception {
try {
System.clearProperty(null);
throw new RuntimeException("Param test failed");
} catch (NullPointerException npe) {
// Correct result
}
try {
System.clearProperty("");
throw new RuntimeException("Param test failed");
} catch (IllegalArgumentException iae) {
// Correct result
}
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4459099
* @key i18n
* @summary Tests non ANSI code page locales set default file encoding
* to "utf-8". This test must be run on Windows 2K/XP in one of Armenian,
* Georgian, Hindi, Punjabi, Gujarati, Tamil, Telugu, Kannada, Marathi,
* or Sanskrit languages.
*/
public class NonAnsiFileEncodingTest {
public static void main(String[] s) {
String OS = System.getProperty("os.name");
String lang = System.getProperty("user.language");
String fileenc = System.getProperty("file.encoding");
if (!(OS.equals("Windows 2000") || OS.equals("Windows XP"))) {
System.out.println("This test is not meaningful on the platform \"" + OS + "\".");
return;
}
if (!(lang.equals("hy") || // Armenian
lang.equals("ka") || // Georgian
lang.equals("hi") || // Hindi
lang.equals("pa") || // Punjabi
lang.equals("gu") || // Gujarati
lang.equals("ta") || // Tamil
lang.equals("te") || // Telugu
lang.equals("kn") || // Kannada
lang.equals("mr") || // Marathi
lang.equals("sa"))) { // Sanskrit
System.out.println("Windows' locale settings for this test is incorrect. Select one of \"Armenian\", \"Georgian\", \"Hindi\", \"Punjabi\", \"Gujarati\", \"Tamil\", \"Telugu\", \"Kannada\", \"Marathi\", or \"Sanskrit\" for the user locale, and \"English(United States)\" for the system default locale using the Control Panel.");
return;
}
if (!fileenc.equals("utf-8")) {
throw new RuntimeException("file.encoding is incorrectly set to \"" + fileenc + "\". Should be \"utf-8\".");
}
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4244670
* @summary test System.setProperties(null)
*/
import java.util.Properties;
public class SetProperties {
public static void main(String [] argv) {
System.setProperties((Properties)null);
System.getProperties().containsKey("java.version");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,7 +24,7 @@
/* @test
*
* @bug 4095393
*
* @test main SendSize
* @summary this tests a regression in 1.2, beta 2 and earlier where
* the DatagramPackets sent the entire buffer, not the buffer length
* of the packet.
@ -43,8 +43,12 @@ public class SendSize {
public static void main(String[] args) throws Exception {
DatagramSocket serverSocket = new DatagramSocket();
new ServerThread(serverSocket).start();
new ClientThread(serverSocket.getLocalPort()).start();
Thread server = new ServerThread(serverSocket);
server.start();
Thread client = new ClientThread(serverSocket.getLocalPort());
client.start();
server.join();
client.join();
}
static class ServerThread extends Thread {
@ -58,24 +62,26 @@ public class SendSize {
try {
System.err.println("started server thread: " + server);
byte[] buf = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(buf,
buf.length);
server.receive(receivePacket);
int len = receivePacket.getLength();
switch(len) {
case packetLength:
System.out.println("receive length is: " + len);
break;
default:
throw new RuntimeException(
"receive length is: " + len +
", send length: " + packetLength +
", buffer length: " + buf.length);
for (int i = 0; i < 10; i++) {
DatagramPacket receivePacket = new DatagramPacket(buf,
buf.length);
server.receive(receivePacket);
int len = receivePacket.getLength();
switch (len) {
case packetLength:
System.out.println("receive length is: " + len);
break;
default:
throw new RuntimeException(
"receive length is: " + len +
", send length: " + packetLength +
", buffer length: " + buf.length);
}
}
return;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("caugth: " + e);
throw new RuntimeException("caught: " + e);
} finally {
if (server != null) { server.close(); }
}

View File

@ -0,0 +1,269 @@
/*
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @modules java.management java.base/java.io:+open java.base/java.net:+open
* @run main/othervm UnreferencedDatagramSockets
* @run main/othervm -Djava.net.preferIPv4Stack=true UnreferencedDatagramSockets
* @summary Check that unreferenced datagram sockets are closed
*/
import java.io.FileDescriptor;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.DatagramSocketImpl;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayDeque;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import com.sun.management.UnixOperatingSystemMXBean;
public class UnreferencedDatagramSockets {
/**
* The set of sockets we have to check up on.
*/
final static ArrayDeque<NamedWeak> pendingSockets = new ArrayDeque<>(5);
/**
* Queued objects when they are unreferenced.
*/
final static ReferenceQueue<Object> pendingQueue = new ReferenceQueue<>();
// Server to echo a datagram packet
static class Server implements Runnable {
DatagramSocket ss;
Server() throws IOException {
ss = new DatagramSocket(0);
System.out.printf(" DatagramServer addr: %s: %d%n",
this.getHost(), this.getPort());
pendingSockets.add(new NamedWeak(ss, pendingQueue, "serverDatagramSocket"));
extractRefs(ss, "serverDatagramSocket");
}
InetAddress getHost() throws UnknownHostException {
InetAddress localhost = InetAddress.getByName("localhost"); //.getLocalHost();
return localhost;
}
int getPort() {
return ss.getLocalPort();
}
// Receive a byte and send back a byte
public void run() {
try {
byte[] buffer = new byte[50];
DatagramPacket p = new DatagramPacket(buffer, buffer.length);
ss.receive(p);
buffer[0] += 1;
ss.send(p); // send back +1
// do NOT close but 'forget' the datagram socket reference
ss = null;
} catch (Exception ioe) {
ioe.printStackTrace();
}
}
}
public static void main(String args[]) throws Exception {
// Create and close a DatagramSocket to warm up the FD count for side effects.
try (DatagramSocket s = new DatagramSocket(0)) {
// no-op; close immediately
s.getLocalPort(); // no-op
}
long fdCount0 = getFdCount();
listProcFD();
// start a server
Server svr = new Server();
Thread thr = new Thread(svr);
thr.start();
DatagramSocket client = new DatagramSocket(0);
client.connect(svr.getHost(), svr.getPort());
pendingSockets.add(new NamedWeak(client, pendingQueue, "clientDatagramSocket"));
extractRefs(client, "clientDatagramSocket");
byte[] msg = new byte[1];
msg[0] = 1;
DatagramPacket p = new DatagramPacket(msg, msg.length, svr.getHost(), svr.getPort());
client.send(p);
p = new DatagramPacket(msg, msg.length);
client.receive(p);
System.out.printf("echo received from: %s%n", p.getSocketAddress());
if (msg[0] != 2) {
throw new AssertionError("incorrect data received: expected: 2, actual: " + msg[0]);
}
// Do NOT close the DatagramSocket; forget it
Object ref;
int loops = 20;
while (!pendingSockets.isEmpty() && loops-- > 0) {
ref = pendingQueue.remove(1000L);
if (ref != null) {
pendingSockets.remove(ref);
System.out.printf(" ref freed: %s, remaining: %d%n", ref, pendingSockets.size());
} else {
client = null;
p = null;
msg = null;
System.gc();
}
}
thr.join();
// List the open file descriptors
long fdCount = getFdCount();
System.out.printf("Initial fdCount: %d, final fdCount: %d%n", fdCount0, fdCount);
listProcFD();
if (loops == 0) {
throw new AssertionError("Not all references reclaimed");
}
}
// Get the count of open file descriptors, or -1 if not available
private static long getFdCount() {
OperatingSystemMXBean mxBean = ManagementFactory.getOperatingSystemMXBean();
return (mxBean instanceof UnixOperatingSystemMXBean)
? ((UnixOperatingSystemMXBean) mxBean).getOpenFileDescriptorCount()
: -1L;
}
// Reflect to find references in the datagram implementation that will be gc'd
private static void extractRefs(DatagramSocket s, String name) {
try {
Field socketImplField = DatagramSocket.class.getDeclaredField("impl");
socketImplField.setAccessible(true);
Object socketImpl = socketImplField.get(s);
Field fileDescriptorField = DatagramSocketImpl.class.getDeclaredField("fd");
fileDescriptorField.setAccessible(true);
FileDescriptor fileDescriptor = (FileDescriptor) fileDescriptorField.get(socketImpl);
extractRefs(fileDescriptor, name);
Class<?> socketImplClass = socketImpl.getClass();
System.out.printf("socketImplClass: %s%n", socketImplClass);
if (socketImplClass.getName().equals("java.net.TwoStacksPlainDatagramSocketImpl")) {
Field fileDescriptor1Field = socketImplClass.getDeclaredField("fd1");
fileDescriptor1Field.setAccessible(true);
FileDescriptor fileDescriptor1 = (FileDescriptor) fileDescriptor1Field.get(socketImpl);
extractRefs(fileDescriptor1, name + "::twoStacksFd1");
} else {
System.out.printf("socketImpl class name not matched: %s != %s%n",
socketImplClass.getName(), "java.net.TwoStacksPlainDatagramSocketImpl");
}
} catch (NoSuchFieldException | IllegalAccessException ex) {
ex.printStackTrace();
throw new AssertionError("missing field", ex);
}
}
private static void extractRefs(FileDescriptor fileDescriptor, String name) {
Object cleanup = null;
int rawfd = -1;
try {
if (fileDescriptor != null) {
Field fd1Field = FileDescriptor.class.getDeclaredField("fd");
fd1Field.setAccessible(true);
rawfd = fd1Field.getInt(fileDescriptor);
Field cleanupfdField = FileDescriptor.class.getDeclaredField("cleanup");
cleanupfdField.setAccessible(true);
cleanup = cleanupfdField.get(fileDescriptor);
pendingSockets.add(new NamedWeak(fileDescriptor, pendingQueue,
name + "::fileDescriptor: " + rawfd));
pendingSockets.add(new NamedWeak(cleanup, pendingQueue, name + "::fdCleanup: " + rawfd));
}
} catch (NoSuchFieldException | IllegalAccessException ex) {
ex.printStackTrace();
throw new AssertionError("missing field", ex);
} finally {
System.out.print(String.format(" %s:: fd: %s, fd: %d, cleanup: %s%n",
name, fileDescriptor, rawfd, cleanup));
}
}
/**
* Method to list the open file descriptors (if supported by the 'lsof' command).
*/
static void listProcFD() {
List<String> lsofDirs = List.of("/usr/bin", "/usr/sbin");
Optional<Path> lsof = lsofDirs.stream()
.map(s -> Paths.get(s, "lsof"))
.filter(f -> Files.isExecutable(f))
.findFirst();
lsof.ifPresent(exe -> {
try {
System.out.printf("Open File Descriptors:%n");
long pid = ProcessHandle.current().pid();
ProcessBuilder pb = new ProcessBuilder(exe.toString(), "-p", Integer.toString((int) pid));
pb.inheritIO();
Process p = pb.start();
p.waitFor(10, TimeUnit.SECONDS);
} catch (IOException | InterruptedException ie) {
ie.printStackTrace();
}
});
}
// Simple class to identify which refs have been queued
static class NamedWeak extends WeakReference<Object> {
private final String name;
NamedWeak(Object o, ReferenceQueue<Object> queue, String name) {
super(o, queue);
this.name = name;
}
public String toString() {
return name + "; " + super.toString();
}
}
}

View File

@ -0,0 +1,271 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @modules java.management java.base/java.io:+open java.base/java.net:+open
* @run main/othervm -Djava.net.preferIPv4Stack=true UnreferencedMulticastSockets
* @run main/othervm UnreferencedMulticastSockets
* @summary Check that unreferenced multicast sockets are closed
*/
import java.io.FileDescriptor;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.DatagramSocketImpl;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayDeque;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import com.sun.management.UnixOperatingSystemMXBean;
public class UnreferencedMulticastSockets {
/**
* The set of sockets we have to check up on.
*/
final static ArrayDeque<NamedWeak> pendingSockets = new ArrayDeque<>(5);
/**
* Queued objects when they are unreferenced.
*/
final static ReferenceQueue<Object> pendingQueue = new ReferenceQueue<>();
// Server to echo a datagram packet
static class Server implements Runnable {
MulticastSocket ss;
Server() throws IOException {
ss = new MulticastSocket(0);
System.out.printf(" DatagramServer addr: %s: %d%n",
this.getHost(), this.getPort());
pendingSockets.add(new NamedWeak(ss, pendingQueue, "serverMulticastSocket"));
extractRefs(ss, "serverMulticastSocket");
}
InetAddress getHost() throws UnknownHostException {
InetAddress localhost = InetAddress.getByName("localhost"); //.getLocalHost();
return localhost;
}
int getPort() {
return ss.getLocalPort();
}
// Receive a byte and send back a byte
public void run() {
try {
byte[] buffer = new byte[50];
DatagramPacket p = new DatagramPacket(buffer, buffer.length);
ss.receive(p);
buffer[0] += 1;
ss.send(p); // send back +1
// do NOT close but 'forget' the socket reference
ss = null;
} catch (Exception ioe) {
ioe.printStackTrace();
}
}
}
public static void main(String args[]) throws Exception {
// Create and close a MulticastSocket to warm up the FD count for side effects.
try (MulticastSocket s = new MulticastSocket(0)) {
// no-op; close immediately
s.getLocalPort(); // no-op
}
long fdCount0 = getFdCount();
listProcFD();
// start a server
Server svr = new Server();
Thread thr = new Thread(svr);
thr.start();
MulticastSocket client = new MulticastSocket(0);
client.connect(svr.getHost(), svr.getPort());
pendingSockets.add(new NamedWeak(client, pendingQueue, "clientMulticastSocket"));
extractRefs(client, "clientMulticastSocket");
byte[] msg = new byte[1];
msg[0] = 1;
DatagramPacket p = new DatagramPacket(msg, msg.length, svr.getHost(), svr.getPort());
client.send(p);
p = new DatagramPacket(msg, msg.length);
client.receive(p);
System.out.printf("echo received from: %s%n", p.getSocketAddress());
if (msg[0] != 2) {
throw new AssertionError("incorrect data received: expected: 2, actual: " + msg[0]);
}
// Do NOT close the MulticastSocket; forget it
Object ref;
int loops = 20;
while (!pendingSockets.isEmpty() && loops-- > 0) {
ref = pendingQueue.remove(1000L);
if (ref != null) {
pendingSockets.remove(ref);
System.out.printf(" ref freed: %s, remaining: %d%n", ref, pendingSockets.size());
} else {
client = null;
p = null;
msg = null;
System.gc();
}
}
thr.join();
// List the open file descriptors
long fdCount = getFdCount();
System.out.printf("Initial fdCount: %d, final fdCount: %d%n", fdCount0, fdCount);
listProcFD();
if (loops == 0) {
throw new AssertionError("Not all references reclaimed");
}
}
// Get the count of open file descriptors, or -1 if not available
private static long getFdCount() {
OperatingSystemMXBean mxBean = ManagementFactory.getOperatingSystemMXBean();
return (mxBean instanceof UnixOperatingSystemMXBean)
? ((UnixOperatingSystemMXBean) mxBean).getOpenFileDescriptorCount()
: -1L;
}
// Reflect to find references in the socket implementation that will be gc'd
private static void extractRefs(MulticastSocket s, String name) {
try {
Field socketImplField = DatagramSocket.class.getDeclaredField("impl");
socketImplField.setAccessible(true);
Object socketImpl = socketImplField.get(s);
Field fileDescriptorField = DatagramSocketImpl.class.getDeclaredField("fd");
fileDescriptorField.setAccessible(true);
FileDescriptor fileDescriptor = (FileDescriptor) fileDescriptorField.get(socketImpl);
extractRefs(fileDescriptor, name);
Class<?> socketImplClass = socketImpl.getClass();
System.out.printf("socketImplClass: %s%n", socketImplClass);
if (socketImplClass.getName().equals("java.net.TwoStacksPlainDatagramSocketImpl")) {
Field fileDescriptor1Field = socketImplClass.getDeclaredField("fd1");
fileDescriptor1Field.setAccessible(true);
FileDescriptor fileDescriptor1 = (FileDescriptor) fileDescriptor1Field.get(socketImpl);
extractRefs(fileDescriptor1, name + "::twoStacksFd1");
} else {
System.out.printf("socketImpl class name not matched: %s != %s%n",
socketImplClass.getName(), "java.net.TwoStacksPlainDatagramSocketImpl");
}
} catch (NoSuchFieldException | IllegalAccessException ex) {
ex.printStackTrace();
throw new AssertionError("missing field", ex);
}
}
private static void extractRefs(FileDescriptor fileDescriptor, String name) {
Object cleanup = null;
int rawfd = -1;
try {
if (fileDescriptor != null) {
Field fd1Field = FileDescriptor.class.getDeclaredField("fd");
fd1Field.setAccessible(true);
rawfd = fd1Field.getInt(fileDescriptor);
Field cleanupfdField = FileDescriptor.class.getDeclaredField("cleanup");
cleanupfdField.setAccessible(true);
cleanup = cleanupfdField.get(fileDescriptor);
pendingSockets.add(new NamedWeak(fileDescriptor, pendingQueue,
name + "::fileDescriptor: " + rawfd));
pendingSockets.add(new NamedWeak(cleanup, pendingQueue, name + "::fdCleanup: " + rawfd));
}
} catch (NoSuchFieldException | IllegalAccessException ex) {
ex.printStackTrace();
throw new AssertionError("missing field", ex);
} finally {
System.out.print(String.format(" %s:: fd: %s, fd: %d, cleanup: %s%n",
name, fileDescriptor, rawfd, cleanup));
}
}
/**
* Method to list the open file descriptors (if supported by the 'lsof' command).
*/
static void listProcFD() {
List<String> lsofDirs = List.of("/usr/bin", "/usr/sbin");
Optional<Path> lsof = lsofDirs.stream()
.map(s -> Paths.get(s, "lsof"))
.filter(f -> Files.isExecutable(f))
.findFirst();
lsof.ifPresent(exe -> {
try {
System.out.printf("Open File Descriptors:%n");
long pid = ProcessHandle.current().pid();
ProcessBuilder pb = new ProcessBuilder(exe.toString(), "-p", Integer.toString((int) pid));
pb.inheritIO();
Process p = pb.start();
p.waitFor(10, TimeUnit.SECONDS);
} catch (IOException | InterruptedException ie) {
ie.printStackTrace();
}
});
}
// Simple class to identify which refs have been queued
static class NamedWeak extends WeakReference<Object> {
private final String name;
NamedWeak(Object o, ReferenceQueue<Object> queue, String name) {
super(o, queue);
this.name = name;
}
public String toString() {
return name + "; " + super.toString();
}
}
}

View File

@ -0,0 +1,294 @@
/*
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @modules java.management java.base/java.io:+open java.base/java.net:+open
* @run main/othervm UnreferencedSockets
* @run main/othervm -Djava.net.preferIPv4Stack=true UnreferencedSockets
* @summary Check that unreferenced sockets are closed
*/
import java.io.FileDescriptor;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketImpl;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayDeque;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import com.sun.management.UnixOperatingSystemMXBean;
public class UnreferencedSockets {
/**
* The set of sockets we have to check up on.
*/
final static ArrayDeque<NamedWeak> pendingSockets = new ArrayDeque<>(100);
/**
* Queued sockets when they are unreferenced.
*/
final static ReferenceQueue<Object> pendingQueue = new ReferenceQueue<>();
// Server to echo a stream
static class Server implements Runnable {
ServerSocket ss;
Server() throws IOException {
ss = new ServerSocket(0);
pendingSockets.add(new NamedWeak(ss, pendingQueue, "serverSocket"));
extractRefs(ss, "serverSocket");
}
public int localPort() {
return ss.getLocalPort();
}
public void run() {
try {
Socket s = ss.accept();
pendingSockets.add(new NamedWeak(s, pendingQueue, "acceptedSocket"));
extractRefs(s, "acceptedSocket");
InputStream in = s.getInputStream();
int b = in.read();
OutputStream out = s.getOutputStream();
out.write(b);
// do NOT close but 'forget' the socket reference
out = null;
in = null;
s = null;
} catch (Exception ioe) {
ioe.printStackTrace();
} finally {
try {
ss.close();
ss = null;
} catch (IOException x) {
x.printStackTrace();
}
}
}
}
public static void main(String args[]) throws Exception {
// Create and close a ServerSocket to warm up the FD count for side effects.
try (ServerSocket s = new ServerSocket(0)) {
// no-op; close immediately
s.getLocalPort(); // no-op
}
long fdCount0 = getFdCount();
listProcFD();
// start a server
Server svr = new Server();
Thread thr = new Thread(svr);
thr.start();
Socket s = new Socket("localhost", svr.localPort());
pendingSockets.add(new NamedWeak(s, pendingQueue, "clientSocket"));
extractRefs(s, "clientSocket");
OutputStream out = s.getOutputStream();
out.write('x');
out.flush();
InputStream in = s.getInputStream();
int b = in.read(); // wait for it back
System.out.printf(" data sent and received%n");
// Do NOT close the Socket; forget it
Object ref;
int loops = 20;
while (!pendingSockets.isEmpty() && loops-- > 0) {
ref = pendingQueue.remove(1000L);
if (ref != null) {
pendingSockets.remove(ref);
System.out.printf(" ref queued: %s, remaining: %d%n", ref, pendingSockets.size());
} else {
s = null;
out = null;
in = null;
System.gc();
}
}
thr.join();
// List the open file descriptors
long fdCount = getFdCount();
System.out.printf("Initial fdCount: %d, final fdCount: %d%n", fdCount0, fdCount);
listProcFD();
if (loops == 0) {
throw new AssertionError("Not all references reclaimed");
}
}
// Get the count of open file descriptors, or -1 if not available
private static long getFdCount() {
OperatingSystemMXBean mxBean = ManagementFactory.getOperatingSystemMXBean();
return (mxBean instanceof UnixOperatingSystemMXBean)
? ((UnixOperatingSystemMXBean) mxBean).getOpenFileDescriptorCount()
: -1L;
}
// Reflect to find references in the socket implementation that will be gc'd
private static void extractRefs(Socket s, String name) {
try {
Field socketImplField = Socket.class.getDeclaredField("impl");
socketImplField.setAccessible(true);
Object socketImpl = socketImplField.get(s);
Field fileDescriptorField = SocketImpl.class.getDeclaredField("fd");
fileDescriptorField.setAccessible(true);
FileDescriptor fileDescriptor = (FileDescriptor) fileDescriptorField.get(socketImpl);
extractRefs(fileDescriptor, name);
Class<?> socketImplClass = socketImpl.getClass();
System.out.printf("socketImplClass: %s%n", socketImplClass);
if (socketImplClass.getClass().getName().equals("java.net.TwoStacksPlainSocketImpl")) {
Field fileDescriptor1Field = socketImplClass.getDeclaredField("fd1");
fileDescriptor1Field.setAccessible(true);
FileDescriptor fileDescriptor1 = (FileDescriptor) fileDescriptor1Field.get(socketImpl);
extractRefs(fileDescriptor1, name + "::twoStacksFd1");
}
} catch (NoSuchFieldException | IllegalAccessException ex) {
ex.printStackTrace();
throw new AssertionError("missing field", ex);
}
}
private static void extractRefs(FileDescriptor fileDescriptor, String name) {
Object cleanup = null;
int rawfd = -1;
try {
if (fileDescriptor != null) {
Field fd1Field = FileDescriptor.class.getDeclaredField("fd");
fd1Field.setAccessible(true);
rawfd = fd1Field.getInt(fileDescriptor);
Field cleanupfdField = FileDescriptor.class.getDeclaredField("cleanup");
cleanupfdField.setAccessible(true);
cleanup = cleanupfdField.get(fileDescriptor);
pendingSockets.add(new NamedWeak(fileDescriptor, pendingQueue,
name + "::fileDescriptor: " + rawfd));
pendingSockets.add(new NamedWeak(cleanup, pendingQueue, name + "::fdCleanup: " + rawfd));
}
} catch (NoSuchFieldException | IllegalAccessException ex) {
ex.printStackTrace();
throw new AssertionError("missing field", ex);
} finally {
System.out.print(String.format(" fd: %s, fd: %d, cleanup: %s%n",
fileDescriptor, rawfd, cleanup));
}
}
private static void extractRefs(ServerSocket s, String name) {
try {
Field socketImplField = ServerSocket.class.getDeclaredField("impl");
socketImplField.setAccessible(true);
Object socketImpl = socketImplField.get(s);
Field fileDescriptorField = SocketImpl.class.getDeclaredField("fd");
fileDescriptorField.setAccessible(true);
FileDescriptor fileDescriptor = (FileDescriptor) fileDescriptorField.get(socketImpl);
Field fdField = FileDescriptor.class.getDeclaredField("fd");
fdField.setAccessible(true);
int rawfd = fdField.getInt(fileDescriptor);
Field cleanupField = FileDescriptor.class.getDeclaredField("cleanup");
cleanupField.setAccessible(true);
Object cleanup = cleanupField.get(fileDescriptor);
System.out.print(String.format(" fd: %s, fd: %d, cleanup: %s, socket: %s%n",
fileDescriptor, rawfd, cleanup, s));
pendingSockets.add(new NamedWeak(fileDescriptor, pendingQueue,
name + "::fileDescriptor: " + rawfd));
pendingSockets.add(new NamedWeak(cleanup, pendingQueue, name + "::fdCleanup: " + rawfd));
} catch (NoSuchFieldException | IllegalAccessException ex) {
ex.printStackTrace();
throw new AssertionError("missing field", ex);
}
}
/**
* Method to list the open file descriptors (if supported by the 'lsof' command).
*/
static void listProcFD() {
List<String> lsofDirs = List.of("/usr/bin", "/usr/sbin");
Optional<Path> lsof = lsofDirs.stream()
.map(s -> Paths.get(s, "lsof"))
.filter(f -> Files.isExecutable(f))
.findFirst();
lsof.ifPresent(exe -> {
try {
System.out.printf("Open File Descriptors:%n");
long pid = ProcessHandle.current().pid();
ProcessBuilder pb = new ProcessBuilder(exe.toString(), "-p", Integer.toString((int) pid));
pb.inheritIO();
Process p = pb.start();
p.waitFor(10, TimeUnit.SECONDS);
} catch (IOException | InterruptedException ie) {
ie.printStackTrace();
}
});
}
// Simple class to identify which refs have been queued
static class NamedWeak extends WeakReference<Object> {
private final String name;
NamedWeak(Object o, ReferenceQueue<Object> queue, String name) {
super(o, queue);
this.name = name;
}
public String toString() {
return name + "; " + super.toString();
}
}
}

View File

@ -0,0 +1,143 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.nio.file.Files;
import java.nio.file.Path;
import jdk.test.lib.util.FileUtils;
/*
* @test
* @bug 8166253
* @summary Verify that OverlappingFileLockException is thrown when expected.
* @library .. /test/lib
* @build jdk.test.lib.util.FileUtils
* @run main/othervm FileLockGC
*/
public class FileLockGC {
public enum TestType {
NO_GC_NO_RELEASE(true),
// A hypothetical 'GC_THEN_RELEASE' case is infeasible
RELEASE(false),
RELEASE_THEN_GC(false),
GC(true);
private final boolean exceptionExpected;
TestType(boolean exceptionExpected) {
this.exceptionExpected = exceptionExpected;
}
boolean exceptionExpected() {
return exceptionExpected;
}
}
public static void main(String[] args) throws Exception {
final File f = new File(System.getProperty("test.dir", ".")
+ File.separator + "junk.txt");
final Path p = f.toPath();
int failures = 0;
for (TestType t : TestType.values()) {
try {
if (!testFileLockGC(f, t)) {
failures++;
}
} finally {
FileUtils.deleteFileIfExistsWithRetry(p);
}
}
if (failures != 0) {
throw new RuntimeException("Test had " + failures + " failure(s)");
}
}
private static boolean testFileLockGC(File f, TestType type)
throws InterruptedException, IOException {
System.out.printf("Test %s starting%n", type.toString());
final RandomAccessFile raf1 = new RandomAccessFile(f, "rw");
FileLock lock1 = raf1.getChannel().tryLock();
WeakReference<FileLock> ref1 = new WeakReference(lock1);
switch (type) {
case GC:
lock1 = null;
System.gc();
break;
case RELEASE:
lock1.release();
break;
case RELEASE_THEN_GC:
lock1.release();
lock1 = null;
System.gc();
break;
default: // NO_GC_NO_RELEASE
// lock1 is neither collected nor released
break;
}
final RandomAccessFile raf2 = new RandomAccessFile(f, "rw");
boolean success = true;
FileLock lock2 = null;
try {
lock2 = raf2.getChannel().tryLock();
if (type.exceptionExpected()) {
System.err.printf
("No expected OverlappingFileLockException for test %s%n",
type.toString());
success = false;
}
} catch (OverlappingFileLockException ofe) {
if (!type.exceptionExpected()) {
System.err.printf
("Unexpected OverlappingFileLockException for test %s%n",
type.toString());
success = false;
}
} finally {
if (lock1 != null) {
lock1.release();
}
if (lock2 != null) {
lock2.release();
}
raf2.close();
raf1.close();
System.out.printf("Test %s finished%n", type.toString());
}
return success;
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4764778
* @summary Mishandling interruption of I/O in Resource.getBytes
* @author Martin Buchholz
*/
public class InterruptedClassLoad {
public static void main(String[] args) {
class Empty {}
Thread.currentThread().interrupt();
new Empty();
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @modules java.base/jdk.internal.math
*/
import jdk.internal.math.FloatingDecimal;
public class ToString {
private static int fail = 0;
private static Throwable first;
public static void main(String argv[]) {
test("10.0");
test("1.0");
test("0.1");
test("0.01");
test("0.001");
test("1.0E-4");
if (fail != 0)
throw new RuntimeException(fail + " failure(s), first", first);
}
private static void test(String exp) {
float c = Float.parseFloat(exp);
String got = FloatingDecimal.toJavaFormatString(c);
if (!got.equals(exp))
fail("float '" + "': Expected '" + exp + "', got '" + got + "'");
double d = Double.parseDouble(exp);
got = FloatingDecimal.toJavaFormatString(d);
if (!got.equals(exp))
fail("double '" + "': Expected '" + exp + "', got '" + got + "'");
}
private static void fail(String s) {
if (first == null)
setFirst(s);
System.err.println("FAILED: " + s);
fail++;
}
private static void setFirst(String s) {
try {
throw new RuntimeException(s);
} catch (RuntimeException x) {
first = x;
}
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4063078
* @summary Allocating a ridiculously large array should not crash the VM
* @run main/othervm -Xmx32m -Xms32m ArraySize
*/
public class ArraySize {
public static void main(String[] args) throws Exception {
boolean thrown = false;
try {
byte[] buf = new byte[Integer.MAX_VALUE - 1];
System.out.print(buf[0]);
} catch (OutOfMemoryError x) {
thrown = true;
}
if (! thrown) {
throw new Exception("Didn't throw expected OutOfMemoryError");
}
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4098578
* @summary Check if the VM properly throws OutOfMemoryError
* @author Sheng Liang
* @run main/othervm -Xmx25M InfiniteList
*/
public class InfiniteList {
InfiniteList next;
long data[] = new long[50000];
public static void main(String[] args) throws Exception {
InfiniteList p, q;
p = new InfiniteList ();
p.data[p.data.length -1 ] = 999;
try {
while (p != null) {
q = new InfiniteList ();
q.next = p;
p = q;
}
throw new Exception ("OutOfMemoryError not thrown as expected.");
} catch (OutOfMemoryError e) {
return;
}
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4157675
* @summary Solaris JIT generates bad code for logic expression
* @author Tom Rodriguez
*/
public class BadLogicCode {
static int values[] = {Integer.MIN_VALUE, -1, 0, 1, 4, 16, 31,
32, 33, Integer.MAX_VALUE};
static char b[][] = {null, new char[32]};
static boolean nullPtr = false, indexOutBnd = false;
static boolean indexOutBnd2 = false;
public static void main(String args[]) throws Exception{
int i = 1, j = 4, k = 9;
nullPtr = (b[i] == null);
int bufLen = nullPtr ? 0 : b[i].length;
indexOutBnd = (values[j] < 0)
|| (values[j] > bufLen)
|| (values[k] < 0)
|| ((values[j] + values[k]) > bufLen)
||((values[j] + values[k]) < 0);
indexOutBnd2 = (values[j] < 0);
indexOutBnd2 = indexOutBnd2 || (values[j] > bufLen);
indexOutBnd2 = indexOutBnd2 || (values[k] < 0);
indexOutBnd2 = indexOutBnd2 || ((values[j] + values[k]) > bufLen);
indexOutBnd2 = indexOutBnd2 ||((values[j] + values[k]) < 0);
if (indexOutBnd != indexOutBnd2)
throw new Error("logic expression generate different results");
}
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4165973
* @summary Attempt to read inaccessible property can produce
* exception of the wrong type.
* @author Tom Rodriguez
*
* @modules java.rmi
*/
import java.security.AccessController;
import java.security.PrivilegedAction;
public class ExceptionInInit {
public static void main(String[] args) {
Test test = null;
try {
System.setSecurityManager(new java.rmi.RMISecurityManager());
Test.showTest();
} catch (ExceptionInInitializerError e) {
}
}
public static class FooBar {
static String test = "test";
FooBar(String test) {
this.test = test;
}
}
public static class Test extends FooBar {
/*
* An AccessControlException is thrown in the static initializer of the
* class FooBar. This exception should produce an ExceptionInInitializer
* error. Instead it causes a more cryptic ClassNotFound error.
*
* The following is an excerpt from the output from java.security.debug=all
*
* access: access denied (java.util.PropertyPermission test.src read)
* java.lang.Exception: Stack trace
* at java.lang.Thread.dumpStack(Thread.java:938)
* at java.security.AccessControlContext.checkPermission(AccessControlContext.java:184)
* at java.security.AccessController.checkPermission(AccessController.java:402)
* at java.lang.SecurityManager.checkPermission(SecurityManager.java:516)
* at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1035)
* at java.lang.System.getProperty(System.java:441)
* at sun.security.action.GetPropertyAction.run(GetPropertyAction.java:73)
* at java.security.AccessController.doPrivileged(Native Method)
* at ExceptionInInit$Test.&#60clinit>(ExceptionInInit.java:33)
* at ExceptionInInit.main(ExceptionInInit.java:18)
* access: domain that failed ProtectionDomain (file:/tmp/exceptionInInit/<no certificates>)
*
* The following exception is occurring when this test program tries
* to access the test.src property.
*/
private static String test =
AccessController.doPrivileged((PrivilegedAction<String>)() -> System.getProperty("test.src", "."));
Test(String test) {
super(test);
}
public static void showTest() {
System.err.println(test);
}
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4154887
* @summary self-parser test causes JDK 1.2 Beta4K segmentation fault
* @run main/othervm JITClassInit
* @author Tom Rodriguez
*/
public class JITClassInit {
public static void main(String[] args) {
Token t = new Token();
new TokenTable();
}
}
class TokenTable {
public TokenTable() {
new TokenTypeIterator(this);
}
public void for_token_type(Token t) {
t.keyword_character_class();
}
}
class Token {
public Object keyword_character_class() {
return new Object();
}
}
class NameOrKeywordToken extends Token {
static TokenTable kt = new TokenTable();
public Object keyword_character_class() {
return new Object();
}
}
class CapKeywordToken extends NameOrKeywordToken {
public Object keyword_character_class() {
return new Object();
}
};
class TokenTypeIterator {
public TokenTypeIterator(TokenTable c) {
c.for_token_type(new CapKeywordToken());
c.for_token_type(new NameOrKeywordToken());
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4221448
* @summary Use explicit check for integer arithmetic exception on win32.
*/
public class ExplicitArithmeticCheck {
public static void main(String argv[]) throws Exception {
for (int i = 0; i < 64; i++) {
boolean result = false;
int n;
try {
n = 0 / 0;
} catch (ArithmeticException e) {
result = true;
}
if (result == false) {
throw new Error("Failed to throw correct exception!");
}
result = false;
try {
n = 0 % 0;
} catch (ArithmeticException e) {
result = true;
}
if (result == false) {
throw new Error("Failed to throw correct exception!");
}
try {
n = 0x80000000 / -1;
} catch (Throwable t) {
throw new Error("Failed to throw correct exception!");
}
if (n != 0x80000000) {
throw new Error("Incorrect integer arithmetic ! ");
}
try {
n = 0x80000000 % -1;
} catch (Throwable t) {
throw new Error("Failed to throw correct exception!");
}
if (n != 0) {
throw new Error("Incorrect integer arithmetic!");
}
}
}
}

View File

@ -0,0 +1,186 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4087516
* @summary Incorrect locking leads to deadlock in monitorCacheMaybeExpand.
* @author Anand Palaniswamy
* @build MonitorCacheMaybeExpand_DeadLock
* @run main/othervm MonitorCacheMaybeExpand_DeadLock
*/
/**
* Background on the bug:
*
* The thread local monitor cache had a locking bug (till
* 1.2beta1) where two threads trying to expand the monitor cache
* at the same time would cause deadlock. The code paths that the
* two threads must be executing for this to happen is described
* in the bug report.
*
* Caveat and red-flag:
*
* Since deadlocks are very timing dependent, there is a good
* chance this test case will not catch the bug most of the time
* -- on your machine and setting, it is _possible_ that the two
* threads might not try a monitorCacheExpand at the same
* time. But in practice, on Solaris native threads, this program
* deadlocks the VM in about 2 seconds pretty consistently,
* whether MP or not.
*
* The rationale for running this test despite this rather large
* caveat is that at worst, it can do no harm.
*
* The idea:
*
* Is to create two monitor hungry threads.
*
* Originally Tom Rodriguez and I suspected that this weird state
* of two threads trying to expand monitor cache can happen only
* if:
*
* Thread 1: Is in the middle of a monitorCacheMaybeExpand.
* Thread 2: Runs GC and tries to freeClasses(). This causes
* sysFree() to be invoked, which in turn needs a
* mutex_lock -- and oops, we end up deadlocking
* with 1 on green_threads.
*
* Which is why this test tries to cause class GC at regular
* intervals.
*
* Turns out that the GC is not required. Two instances of the
* monitor hungry threads deadlock the VM pretty quick. :-) Infact
* the static initializer in the forName'd classes running
* alongside one of the hungry threads is sufficient to
* deadlock. Still keep the GC stuff just-in-case (and also
* because I wrote it :-).
*
*/
public class MonitorCacheMaybeExpand_DeadLock {
/**
* A monitor-hungry thread.
*/
static class LotsaMonitors extends Thread {
/** How many recursions? Could cause Java stack overflow. */
static final int MAX_DEPTH = 800;
/** What is our depth? */
int depth = 0;
/** Thread ID */
int tid;
/** So output will have thread number. */
public LotsaMonitors(int tid, int depth) {
super("LotsaMonitors #" + new Integer(tid).toString());
this.tid = tid;
this.depth = depth;
}
/** Start a recursion that grabs monitors. */
public void run() {
System.out.println(">>>Starting " + this.toString() + " ...");
Thread.currentThread().yield();
this.recurse();
System.out.println("<<<Finished " + this.toString());
}
/** Every call to this method grabs an extra monitor. */
synchronized void recurse() {
if (this.depth > 0) {
new LotsaMonitors(tid, depth-1).recurse();
}
}
}
/**
* The test.
*/
public static void main(String[] args) {
/* Start the two of these crazy threads. */
new LotsaMonitors(1, LotsaMonitors.MAX_DEPTH).start();
new LotsaMonitors(2, LotsaMonitors.MAX_DEPTH).start();
/* And sit there and GC for good measure. */
for (int i = 0; i < MAX_GC_ITERATIONS; i++) {
new LotsaMonitors(i+3, LotsaMonitors.MAX_DEPTH).start();
System.out.println(">>>Loading 10 classes and gc'ing ...");
Class[] classes = new Class[10];
fillClasses(classes);
classes = null;
System.gc();
Thread.currentThread().yield();
System.out.println("<<<Finished loading 10 classes and gc'ing");
}
}
/** How many times to GC? */
static final int MAX_GC_ITERATIONS = 10;
/** Load some classes into the array. */
static void fillClasses(Class[] classes) {
for (int i = 0; i < classes.length; i++) {
try {
classes[i] = Class.forName(classnames[i]);
} catch (ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
}
}
/** Some random classes to load. */
private static String[] classnames = {
"java.text.DecimalFormat",
"java.text.MessageFormat",
"java.util.GregorianCalendar",
"java.util.ResourceBundle",
"java.text.Collator",
"java.util.Date",
"java.io.Reader",
"java.io.Writer",
"java.lang.IllegalAccessException",
"java.lang.InstantiationException",
"java.lang.ClassNotFoundException",
"java.lang.CloneNotSupportedException",
"java.lang.InterruptedException",
"java.lang.NoSuchFieldException",
"java.lang.NoSuchMethodException",
"java.lang.RuntimeException",
"java.lang.ArithmeticException",
"java.lang.ArrayStoreException",
"java.lang.ClassCastException",
"java.lang.StringIndexOutOfBoundsException",
"java.lang.NegativeArraySizeException",
"java.lang.IllegalStateException",
"java.lang.IllegalArgumentException",
"java.lang.NumberFormatException",
"java.lang.IllegalThreadStateException",
"java.lang.IllegalMonitorStateException",
"java.lang.SecurityException",
"java.lang.ExceptionInInitializerError"
};
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4185411
* @summary This program crashes in 1.1, but runs okay in 1.2.
* @run main/othervm -Xss512k ReflectStackOverflow
*/
import java.lang.reflect.*;
public class ReflectStackOverflow {
private static final int COUNT = 11000;
public static void main(String[] cmdline) throws Throwable {
for (int i = 0; i < COUNT+1; i++) {
stuff(i);
}
}
private static void stuff(int count) throws Throwable {
if (count < COUNT)
return; // don't do anything the first COUNT times.
try {
final Method method =
Method.class.getMethod
("invoke", new Class[] { Object.class, Object[].class });
final Object[] args = new Object[] { method, null };
args[1] = args;
method.invoke(method, args); // "recursive reflection"
// exception should have been thrown by now...
System.out.println("how did I get here?");
} catch(Throwable t) {
int layers;
for(layers = 0; t instanceof InvocationTargetException; layers++)
t = ((InvocationTargetException)t).getTargetException();
System.err.println("Found " + layers + " layers of wrappers.");
if (!(t instanceof StackOverflowError)) {
throw t;
}
}
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4093292
* @summary Test for correct code generation by the JIT
*/
public class ShiftTest {
static final int w = 32;
private static void doTest(long ct) throws Exception {
int S22 = 0xc46cf7c2;
int S23 = 0xcfda9162;
int S24 = 0xd029aa4c;
int S25 = 0x17cf1801;
int A = (int)(ct & 0xffffffffL);
int B = (int)(ct >>> 32);
int x, y;
x = B - S25;
y = A & (w-1);
B = ((x >>> y) | (x << (w-y))) ^ A;
x = A - S24;
y = B & (w-1);
A = ((x >>> y) | (x << (w-y))) ^ B;
x = B - S23;
y = A & (w-1);
B = ((x >>> y) | (x << (w-y))) ^ A;
x = A - S22;
y = B & (w-1);
A = ((x >>> y) | (x << (w-y))) ^ B;
String astr = Integer.toHexString(A);
String bstr = Integer.toHexString(B);
System.err.println("A = " + astr + " B = " + bstr);
if ((!astr.equals("dcb38144")) ||
(!bstr.equals("1916de73"))) {
throw new RuntimeException("Unexpected shift results!");
}
System.err.println("Test passed");
}
public static void main(String[] args) throws Exception {
doTest(0x496def29b74be041L);
}
}

View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4169183
* @summary Check for correct inlining by the interpreter (widefp and strictfp).
* The default is widefp. A strictfp method was getting inlined
* into a widefp method.
*/
import java.io.PrintStream;
public class WideStrictInline {
static PrintStream out;
static float halfUlp;
static {
halfUlp = 1;
for ( int i = 127 - 24; i > 0; i-- )
halfUlp *= 2;
}
public static void main(String argv[]) throws Exception {
out = System.err;
pr(-1,"halfUlp",halfUlp);
WideStrictInline obj = new WideStrictInline();
for( int i=0; i<48; i++ )
obj.instanceMethod( i );
}
private static void pr(int i, String desc, float r) {
out.print(" i=("+i+") "+desc+" ; == "+r);
out.println(" , 0x"+Integer.toHexString(Float.floatToIntBits(r)));
}
private static strictfp float WideStrictInline(float par) {
return par;
}
public static strictfp float strictValue(int i) {
float r;
switch (i%4) {
case 0: r = -Float.MAX_VALUE; break;
case 1: r = Float.MAX_VALUE; break;
case 2: r = Float.MIN_VALUE; break;
default : r = 1L << 24;
}
return r;
}
void instanceMethod (int i) throws Exception {
float r;
switch (i%4) {
case 0:
if (!Float.isInfinite( WideStrictInline(strictValue(i)*2) +
Float.MAX_VALUE ))
{
pr(i,
"WideStrictInline(-Float.MAX_VALUE * 2) " +
"!= Float.NEGATIVE_INFINITY"
,WideStrictInline(strictValue(i)*2) + Float.MAX_VALUE);
}
r = WideStrictInline(strictValue(i)*2) + Float.MAX_VALUE;
if ( !Float.isInfinite( r ) ) {
pr(i,"r != Float.NEGATIVE_INFINITY",r);
throw new RuntimeException();
}
break;
case 1:
if (!Float.isInfinite(WideStrictInline(strictValue(i)+halfUlp) -
Float.MAX_VALUE )) {
pr(i,"WideStrictInline(Float.MAX_VALUE+halfUlp) " +
"!= Float.POSITIVE_INFINITY"
,WideStrictInline(strictValue(i)+halfUlp) - Float.MAX_VALUE);
}
r = WideStrictInline(strictValue(i)+halfUlp) - Float.MAX_VALUE;
if ( !Float.isInfinite( r ) ) {
pr(i,"r != Float.POSITIVE_INFINITY",r);
throw new RuntimeException();
}
break;
case 2:
if (WideStrictInline(strictValue(i)/2) != 0) {
pr(i,"WideStrictInline(Float.MIN_VALUE/2) != 0",
WideStrictInline(strictValue(i)/2));
}
r = WideStrictInline(strictValue(i)/2);
if ( r != 0 ) {
pr(i,"r != 0",r);
throw new RuntimeException();
}
break;
default:
if (WideStrictInline(strictValue(i)-0.5f) - strictValue(i) != 0) {
pr(i,"WideStrictInline(2^24-0.5) != 2^24",
WideStrictInline(strictValue(i)-0.5f));
}
r = WideStrictInline(strictValue(i)-0.5f);
if ( r - strictValue(i) != 0 ) {
pr(i,"r != 2^24",r);
throw new RuntimeException();
}
}
}
}