diff --git a/.github/actions/do-build/action.yml b/.github/actions/do-build/action.yml index 3deb7f4b8f8..79eddf8c70f 100644 --- a/.github/actions/do-build/action.yml +++ b/.github/actions/do-build/action.yml @@ -66,7 +66,7 @@ runs: shell: bash - name: 'Upload build logs' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: failure-logs-${{ inputs.platform }}${{ inputs.debug-suffix }} path: failure-logs @@ -74,7 +74,7 @@ runs: # This is the best way I found to abort the job with an error message - name: 'Notify about build failures' - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: core.setFailed('Build failed. See summary for details.') if: steps.check.outputs.failure == 'true' diff --git a/.github/actions/get-bootjdk/action.yml b/.github/actions/get-bootjdk/action.yml index 1e569dd47c5..25ee1d8dfa0 100644 --- a/.github/actions/get-bootjdk/action.yml +++ b/.github/actions/get-bootjdk/action.yml @@ -65,7 +65,7 @@ runs: - name: 'Check cache for BootJDK' id: get-cached-bootjdk - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: bootjdk/jdk key: boot-jdk-${{ inputs.platform }}-${{ steps.sha256.outputs.value }} diff --git a/.github/actions/get-bundles/action.yml b/.github/actions/get-bundles/action.yml index 956e1520cfb..0e52320a350 100644 --- a/.github/actions/get-bundles/action.yml +++ b/.github/actions/get-bundles/action.yml @@ -48,14 +48,14 @@ runs: steps: - name: 'Download bundles artifact' id: download-bundles - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }} path: bundles continue-on-error: true - name: 'Download bundles artifact (retry)' - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }} path: bundles diff --git a/.github/actions/get-jtreg/action.yml b/.github/actions/get-jtreg/action.yml index 1a6ffeb126b..ab0927919db 100644 --- a/.github/actions/get-jtreg/action.yml +++ b/.github/actions/get-jtreg/action.yml @@ -41,7 +41,7 @@ runs: - name: 'Check cache for JTReg' id: get-cached-jtreg - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: jtreg/installed key: jtreg-${{ steps.version.outputs.value }} diff --git a/.github/actions/get-msys2/action.yml b/.github/actions/get-msys2/action.yml index 7dac1538536..843b77ac064 100644 --- a/.github/actions/get-msys2/action.yml +++ b/.github/actions/get-msys2/action.yml @@ -30,8 +30,7 @@ runs: using: composite steps: - name: 'Install MSYS2' - # use a specific release of msys2/setup-msys2 to prevent jtreg build failures on newer release - uses: msys2/setup-msys2@7efe20baefed56359985e327d329042cde2434ff + uses: msys2/setup-msys2@v2.22.0 with: install: 'autoconf tar unzip zip make' path-type: minimal diff --git a/.github/actions/upload-bundles/action.yml b/.github/actions/upload-bundles/action.yml index 88f7f6e8107..b35ee3a42e9 100644 --- a/.github/actions/upload-bundles/action.yml +++ b/.github/actions/upload-bundles/action.yml @@ -69,7 +69,7 @@ runs: shell: bash - name: 'Upload bundles artifact' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }} path: bundles diff --git a/.github/workflows/build-cross-compile.yml b/.github/workflows/build-cross-compile.yml index d73bef53bb5..3afb910a3d8 100644 --- a/.github/workflows/build-cross-compile.yml +++ b/.github/workflows/build-cross-compile.yml @@ -61,27 +61,32 @@ jobs: debian-arch: arm64 debian-repository: https://httpredir.debian.org/debian/ debian-version: bullseye + tolerate-sysroot-errors: false - target-cpu: arm gnu-arch: arm debian-arch: armhf debian-repository: https://httpredir.debian.org/debian/ debian-version: bullseye + tolerate-sysroot-errors: false gnu-abi: eabihf - target-cpu: s390x gnu-arch: s390x debian-arch: s390x debian-repository: https://httpredir.debian.org/debian/ debian-version: bullseye + tolerate-sysroot-errors: false - target-cpu: ppc64le gnu-arch: powerpc64le debian-arch: ppc64el debian-repository: https://httpredir.debian.org/debian/ debian-version: bullseye + tolerate-sysroot-errors: false - target-cpu: riscv64 gnu-arch: riscv64 debian-arch: riscv64 debian-repository: https://httpredir.debian.org/debian/ debian-version: sid + tolerate-sysroot-errors: true steps: - name: 'Checkout the JDK source' @@ -93,13 +98,6 @@ jobs: with: platform: linux-x64 - # Use linux-x64 JDK bundle as build JDK - - name: 'Get build JDK' - id: buildjdk - uses: ./.github/actions/get-bundles - with: - platform: linux-x64 - - name: 'Get GTest' id: gtest uses: ./.github/actions/get-gtest @@ -120,7 +118,7 @@ jobs: - name: 'Check cache for sysroot' id: get-cached-sysroot - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: sysroot key: sysroot-${{ matrix.debian-arch }}-${{ hashFiles('./.github/workflows/build-cross-compile.yml') }} @@ -130,6 +128,7 @@ jobs: if: steps.get-cached-sysroot.outputs.cache-hit != 'true' - name: 'Create sysroot' + id: create-sysroot run: > sudo debootstrap --arch=${{ matrix.debian-arch }} @@ -140,6 +139,7 @@ jobs: ${{ matrix.debian-version }} sysroot ${{ matrix.debian-repository }} + continue-on-error: ${{ matrix.tolerate-sysroot-errors }} if: steps.get-cached-sysroot.outputs.cache-hit != 'true' - name: 'Prepare sysroot' @@ -151,7 +151,12 @@ jobs: rm -rf sysroot/usr/{sbin,bin,share} rm -rf sysroot/usr/lib/{apt,gcc,udev,systemd} rm -rf sysroot/usr/libexec/gcc - if: steps.get-cached-sysroot.outputs.cache-hit != 'true' + if: steps.create-sysroot.outcome == 'success' && steps.get-cached-sysroot.outputs.cache-hit != 'true' + + - name: 'Remove broken sysroot' + run: | + sudo rm -rf sysroot/ + if: steps.create-sysroot.outcome != 'success' && steps.get-cached-sysroot.outputs.cache-hit != 'true' - name: 'Configure' run: > @@ -165,13 +170,13 @@ jobs: --disable-precompiled-headers --openjdk-target=${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}} --with-sysroot=sysroot - --with-build-jdk=${{ steps.buildjdk.outputs.jdk-path }} CC=${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}}-gcc-${{ inputs.gcc-major-version }} CXX=${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}}-g++-${{ inputs.gcc-major-version }} ${{ inputs.extra-conf-options }} ${{ inputs.configure-arguments }} || ( echo "Dumping config.log:" && cat config.log && exit 1) + if: steps.create-sysroot.outcome == 'success' || steps.get-cached-sysroot.outputs.cache-hit == 'true' - name: 'Build' id: build @@ -179,3 +184,4 @@ jobs: with: make-target: 'hotspot ${{ inputs.make-arguments }}' platform: linux-${{ matrix.target-cpu }} + if: steps.create-sysroot.outcome == 'success' || steps.get-cached-sysroot.outputs.cache-hit == 'true' diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 10f704fd27f..9e2f11eb4d3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -130,8 +130,7 @@ jobs: gcc-major-version: '10' configure-arguments: ${{ github.event.inputs.configure-arguments }} make-arguments: ${{ github.event.inputs.make-arguments }} - # The linux-x64 jdk bundle is used as buildjdk for the cross-compile job - if: needs.select.outputs.linux-x64 == 'true' || needs.select.outputs.linux-cross-compile == 'true' + if: needs.select.outputs.linux-x64 == 'true' build-linux-x86: name: linux-x86 @@ -211,7 +210,6 @@ jobs: name: linux-cross-compile needs: - select - - build-linux-x64 uses: ./.github/workflows/build-cross-compile.yml with: gcc-major-version: '10' @@ -338,7 +336,7 @@ jobs: # Hack to get hold of the api environment variables that are only defined for actions - name: 'Get API configuration' id: api - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: 'return { url: process.env["ACTIONS_RUNTIME_URL"], token: process.env["ACTIONS_RUNTIME_TOKEN"] }' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5d91e057a64..6889a5b0237 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -211,7 +211,7 @@ jobs: if: always() - name: 'Upload test results' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: path: results name: ${{ steps.package.outputs.artifact-name }} @@ -219,7 +219,7 @@ jobs: # This is the best way I found to abort the job with an error message - name: 'Notify about test failures' - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: core.setFailed('${{ steps.run-tests.outputs.error-message }}') if: steps.run-tests.outputs.failure == 'true' diff --git a/.jcheck/conf b/.jcheck/conf index 71f8e5b9833..c39a4fe49e6 100644 --- a/.jcheck/conf +++ b/.jcheck/conf @@ -1,7 +1,7 @@ [general] project=jdk-updates jbs=JDK -version=17.0.11 +version=17.0.12 [checks] error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists diff --git a/doc/building.html b/doc/building.html index f92b3680009..31044787bba 100644 --- a/doc/building.html +++ b/doc/building.html @@ -174,22 +174,22 @@

Operating System Requirements

- - + + - - + + - - + + - - + +
Operating systemVendor/version usedOperating systemVendor/version used
LinuxOracle Enterprise Linux 6.4 / 7.6LinuxOracle Enterprise Linux 6.4 / 7.6
macOSMac OS X 10.13 (High Sierra)macOSMac OS X 10.13 (High Sierra)
WindowsWindows Server 2012 R2WindowsWindows Server 2012 R2
@@ -544,27 +544,27 @@

Cross compiling the e - + - + - + - + - + - + - +
Supported devkit targetsSupported devkit targets
x86_64-linux-gnux86_64-linux-gnu
aarch64-linux-gnuaarch64-linux-gnu
arm-linux-gnueabihfarm-linux-gnueabihf
ppc64-linux-gnuppc64-linux-gnu
ppc64le-linux-gnuppc64le-linux-gnu
s390x-linux-gnus390x-linux-gnu
@@ -678,103 +678,103 @@

Cross compiling with Debian sysroo - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + diff --git a/doc/building.md b/doc/building.md index a11ed884610..6a8eabfc7b5 100644 --- a/doc/building.md +++ b/doc/building.md @@ -154,11 +154,11 @@ This table lists the OS versions used by Oracle when building the JDK. Such information is always subject to change, but this table is up to date at the time of writing. - Operating system Vendor/version used - ----------------- ------------------------------------------------------- - Linux Oracle Enterprise Linux 6.4 / 7.6 - macOS Mac OS X 10.13 (High Sierra) - Windows Windows Server 2012 R2 +| Operating system | Vendor/version used | +| ----------------- | ---------------------------------- | +| Linux | Oracle Enterprise Linux 6.4 / 7.6 | +| macOS | Mac OS X 10.13 (High Sierra) | +| Windows | Windows Server 2012 R2 | The double version numbers for Linux are due to the hybrid model used at Oracle, where header files and external libraries from an older version @@ -957,14 +957,14 @@ https://sourceware.org/autobook/autobook/autobook_17.html). If no targets are given, a native toolchain for the current platform will be created. Currently, at least the following targets are known to work: - Supported devkit targets - ------------------------- - x86_64-linux-gnu - aarch64-linux-gnu - arm-linux-gnueabihf - ppc64-linux-gnu - ppc64le-linux-gnu - s390x-linux-gnu +| Supported devkit targets | +| ------------------------ | +| x86_64-linux-gnu | +| aarch64-linux-gnu | +| arm-linux-gnueabihf | +| ppc64-linux-gnu | +| ppc64le-linux-gnu | +| s390x-linux-gnu | `BASE_OS` must be one of "OEL6" for Oracle Enterprise Linux 6 or "Fedora" (if not specified "OEL6" will be the default). If the base OS @@ -1184,21 +1184,21 @@ it might require a little nudge with: Architectures that are known to successfully cross-compile like this are: - Target Debian tree Debian arch `--openjdk-target=...` `--with-jvm-variants=...` - ------------ ------------ ------------- ------------------------ -------------- - x86 buster i386 i386-linux-gnu (all) - arm buster armhf arm-linux-gnueabihf (all) - aarch64 buster arm64 aarch64-linux-gnu (all) - ppc64le buster ppc64el powerpc64le-linux-gnu (all) - s390x buster s390x s390x-linux-gnu (all) - mipsle buster mipsel mipsel-linux-gnu zero - mips64le buster mips64el mips64el-linux-gnueabi64 zero - armel buster arm arm-linux-gnueabi zero - ppc sid powerpc powerpc-linux-gnu zero - ppc64be sid ppc64 powerpc64-linux-gnu (all) - m68k sid m68k m68k-linux-gnu zero - alpha sid alpha alpha-linux-gnu zero - sh4 sid sh4 sh4-linux-gnu zero +| Target | Debian tree | Debian arch | `--openjdk-target=...` | `--with-jvm-variants=...` | +| ------------ | ------------ | ------------- | ------------------------ | ------------------------- | +| x86 | buster | i386 | i386-linux-gnu | (all) | +| arm | buster | armhf | arm-linux-gnueabihf | (all) | +| aarch64 | buster | arm64 | aarch64-linux-gnu | (all) | +| ppc64le | buster | ppc64el | powerpc64le-linux-gnu | (all) | +| s390x | buster | s390x | s390x-linux-gnu | (all) | +| mipsle | buster | mipsel | mipsel-linux-gnu | zero | +| mips64le | buster | mips64el | mips64el-linux-gnueabi64 | zero | +| armel | buster | arm | arm-linux-gnueabi | zero | +| ppc | sid | powerpc | powerpc-linux-gnu | zero | +| ppc64be | sid | ppc64 | powerpc64-linux-gnu | (all) | +| m68k | sid | m68k | m68k-linux-gnu | zero | +| alpha | sid | alpha | alpha-linux-gnu | zero | +| sh4 | sid | sh4 | sh4-linux-gnu | zero | ### Building for ARM/aarch64 diff --git a/doc/testing.html b/doc/testing.html index 047a7dc1ba7..a64a891b5b8 100644 --- a/doc/testing.html +++ b/doc/testing.html @@ -237,10 +237,10 @@

Non-US locale

$ export LANG="en_US" && make test TEST=...
 $ make test JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US" TEST=...

PKCS11 Tests

-

It is highly recommended to use the latest NSS version when running PKCS11 tests. Improper NSS version may lead to unexpected failures which are hard to diagnose. For example, sun/security/pkcs11/Secmod/AddTrustedCert.java may fail on Ubuntu 18.04 with the default NSS version in the system. To run these tests correctly, the system property test.nss.lib.paths is required on Ubuntu 18.04 to specify the alternative NSS lib directories.

+

It is highly recommended to use the latest NSS version when running PKCS11 tests. Improper NSS version may lead to unexpected failures which are hard to diagnose. For example, sun/security/pkcs11/Secmod/AddTrustedCert.java may fail on Ubuntu 18.04 with the default NSS version in the system. To run these tests correctly, the system property <jdk.test.lib.artifacts.<NAME> is required on Ubuntu 18.04 to specify the alternative NSS lib directories.The<NAME> component should be replaced with the name element of the appropriate @Artifact class. (Seetest/jdk/sun/security/pkcs11/PKCS11Test.java)

For example:

$ make test TEST="jtreg:sun/security/pkcs11/Secmod/AddTrustedCert.java" \
-    JTREG="JAVA_OPTIONS=-Dtest.nss.lib.paths=/path/to/your/latest/NSS-libs"
+ JTREG="JAVA_OPTIONS=-Djdk.test.lib.artifacts.nsslib-linux_aarch64=/path/to/NSS-libs"

For more notes about the PKCS11 tests, please refer to test/jdk/sun/security/pkcs11/README.

Client UI Tests

System key shortcuts

diff --git a/doc/testing.md b/doc/testing.md index 34cd2b0bcaf..3cdc0d662d6 100644 --- a/doc/testing.md +++ b/doc/testing.md @@ -536,14 +536,16 @@ It is highly recommended to use the latest NSS version when running PKCS11 tests. Improper NSS version may lead to unexpected failures which are hard to diagnose. For example, sun/security/pkcs11/Secmod/AddTrustedCert.java may fail on Ubuntu 18.04 with the default NSS version in the system. To run these tests -correctly, the system property `test.nss.lib.paths` is required on Ubuntu 18.04 -to specify the alternative NSS lib directories. +correctly, the system property `jdk.test.lib.artifacts.` is required on +Ubuntu 18.04 to specify the alternative NSS lib directory. The `` +component should be replaced with the name element of the appropriate +`@Artifact` class. (See `test/jdk/sun/security/pkcs11/PKCS11Test.java`) For example: ``` $ make test TEST="jtreg:sun/security/pkcs11/Secmod/AddTrustedCert.java" \ - JTREG="JAVA_OPTIONS=-Dtest.nss.lib.paths=/path/to/your/latest/NSS-libs" + JTREG="JAVA_OPTIONS=-Djdk.test.lib.artifacts.nsslib-linux_aarch64=/path/to/NSS-libs" ``` For more notes about the PKCS11 tests, please refer to diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index 4260b2ea28c..f5ce6d27992 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 @@ -28,7 +28,7 @@ # Setup flags for C/C++ compiler # -############################################################################### +################################################################################ # # How to compile shared libraries. # @@ -37,7 +37,10 @@ AC_DEFUN([FLAGS_SETUP_SHARED_LIBS], if test "x$TOOLCHAIN_TYPE" = xgcc; then # Default works for linux, might work on other platforms as well. SHARED_LIBRARY_FLAGS='-shared' - SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN[$]1' + # --disable-new-dtags forces use of RPATH instead of RUNPATH for rpaths. + # This protects internal library dependencies within the JDK from being + # overridden using LD_LIBRARY_PATH. See JDK-8326891 for more information. + SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN[$]1 -Wl,--disable-new-dtags' SET_SHARED_LIBRARY_ORIGIN="-Wl,-z,origin $SET_EXECUTABLE_ORIGIN" SET_SHARED_LIBRARY_NAME='-Wl,-soname=[$]1' SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=[$]1' @@ -55,6 +58,9 @@ AC_DEFUN([FLAGS_SETUP_SHARED_LIBS], # Default works for linux, might work on other platforms as well. SHARED_LIBRARY_FLAGS='-shared' SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN[$]1' + if test "x$OPENJDK_TARGET_OS" = xlinux; then + SET_EXECUTABLE_ORIGIN="$SET_EXECUTABLE_ORIGIN -Wl,--disable-new-dtags" + fi SET_SHARED_LIBRARY_NAME='-Wl,-soname=[$]1' SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=[$]1' diff --git a/make/common/MakeBase.gmk b/make/common/MakeBase.gmk index 8e63b8b4c92..49ad3d60f90 100644 --- a/make/common/MakeBase.gmk +++ b/make/common/MakeBase.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2024, 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 @@ -153,6 +153,10 @@ define SetupLogging endif endif + ifneq ($$(findstring $$(LOG_LEVEL), debug trace),) + SHELL := $$(SHELL) -x + endif + ifeq ($$(LOG_LEVEL), trace) SHELL_NO_RECURSE := $$(SHELL) # Shell redefinition trick inspired by http://www.cmcrossroads.com/ask-mr-make/6535-tracing-rule-execution-in-gnu-make diff --git a/make/common/MakeIO.gmk b/make/common/MakeIO.gmk index 342e4f5c4b5..7cd6fa1877d 100644 --- a/make/common/MakeIO.gmk +++ b/make/common/MakeIO.gmk @@ -257,7 +257,7 @@ ifeq ($(HAS_FILE_FUNCTION), true) else # Use printf to get consistent behavior on all platforms. WriteFile = \ - $(shell $(PRINTF) "%s" $(call ShellQuote, $1) > $2) + $(shell $(PRINTF) "%s\n" $(strip $(call ShellQuote, $1)) > $2) endif # Param 1 - Text to write @@ -268,5 +268,5 @@ ifeq ($(HAS_FILE_FUNCTION), true) else # Use printf to get consistent behavior on all platforms. AppendFile = \ - $(shell $(PRINTF) "%s" $(call ShellQuote, $1) >> $2) + $(shell $(PRINTF) "%s\n" $(strip $(call ShellQuote, $1)) >> $2) endif diff --git a/make/conf/github-actions.conf b/make/conf/github-actions.conf index 746581ba97c..1d2c643d0d4 100644 --- a/make/conf/github-actions.conf +++ b/make/conf/github-actions.conf @@ -29,13 +29,13 @@ GTEST_VERSION=1.8.1 JTREG_VERSION=7.3.1+1 LINUX_X64_BOOT_JDK_EXT=tar.gz -LINUX_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.6%2B10/OpenJDK17U-jdk_x64_linux_hotspot_17.0.6_10.tar.gz -LINUX_X64_BOOT_JDK_SHA256=a0b1b9dd809d51a438f5fa08918f9aca7b2135721097f0858cf29f77a35d4289 +LINUX_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.11%2B9/OpenJDK17U-jdk_x64_linux_hotspot_17.0.11_9.tar.gz +LINUX_X64_BOOT_JDK_SHA256=aa7fb6bb342319d227a838af5c363bfa1b4a670c209372f9e6585bd79da6220c WINDOWS_X64_BOOT_JDK_EXT=zip -WINDOWS_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.6%2B10/OpenJDK17U-jdk_x64_windows_hotspot_17.0.6_10.zip -WINDOWS_X64_BOOT_JDK_SHA256=d544c4f00d414a1484c0a5c1758544f30f308c4df33f9a28bd4a404215d0d444 +WINDOWS_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.11%2B9/OpenJDK17U-jdk_x64_windows_hotspot_17.0.11_9.zip +WINDOWS_X64_BOOT_JDK_SHA256=fdd6664d4131370398fbc8bfbb7b46dbfec4a22a090a511fe5c379dae188c390 MACOS_X64_BOOT_JDK_EXT=tar.gz -MACOS_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.6%2B10/OpenJDK17U-jdk_x64_mac_hotspot_17.0.6_10.tar.gz -MACOS_X64_BOOT_JDK_SHA256=faa2927584cf2bd0a35d2ac727b9f22725e23b2b24abfb3b2ac7140f4d65fbb4 +MACOS_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.11%2B9/OpenJDK17U-jdk_x64_mac_hotspot_17.0.11_9.tar.gz +MACOS_X64_BOOT_JDK_SHA256=f8b96724618f4df557c47f11048d1084e98ed3eb87f0dbd5b84f768a80c3348e diff --git a/make/conf/version-numbers.conf b/make/conf/version-numbers.conf index d3d1bc750e5..37266259ef2 100644 --- a/make/conf/version-numbers.conf +++ b/make/conf/version-numbers.conf @@ -28,12 +28,12 @@ DEFAULT_VERSION_FEATURE=17 DEFAULT_VERSION_INTERIM=0 -DEFAULT_VERSION_UPDATE=11 +DEFAULT_VERSION_UPDATE=12 DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_EXTRA1=0 DEFAULT_VERSION_EXTRA2=0 DEFAULT_VERSION_EXTRA3=0 -DEFAULT_VERSION_DATE=2024-04-16 +DEFAULT_VERSION_DATE=2024-07-16 DEFAULT_VERSION_CLASSFILE_MAJOR=61 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 diff --git a/make/data/cacerts/certainlyroote1 b/make/data/cacerts/certainlyroote1 new file mode 100644 index 00000000000..3f0d0face0e --- /dev/null +++ b/make/data/cacerts/certainlyroote1 @@ -0,0 +1,20 @@ +Owner: CN=Certainly Root E1, O=Certainly, C=US +Issuer: CN=Certainly Root E1, O=Certainly, C=US +Serial number: 62533b1470333275cf98d9ab9bfccf8 +Valid from: Thu Apr 01 00:00:00 GMT 2021 until: Sun Apr 01 00:00:00 GMT 2046 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw +CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu +bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ +BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s +eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK ++IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2 +QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4 +hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm +ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG +BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR +-----END CERTIFICATE----- diff --git a/make/data/cacerts/certainlyrootr1 b/make/data/cacerts/certainlyrootr1 new file mode 100644 index 00000000000..dbb99fad32c --- /dev/null +++ b/make/data/cacerts/certainlyrootr1 @@ -0,0 +1,38 @@ +Owner: CN=Certainly Root R1, O=Certainly, C=US +Issuer: CN=Certainly Root R1, O=Certainly, C=US +Serial number: 8e0ff94b907168653354f4d44439b7e0 +Valid from: Thu Apr 01 00:00:00 GMT 2021 until: Sun Apr 01 00:00:00 GMT 2046 +Signature algorithm name: SHA256withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw +PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy +dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9 +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0 +YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2 +1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT +vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed +aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0 +1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5 +r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5 +cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ +wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ +6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA +2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH +Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR +eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u +d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr +PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d +8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi +1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd +rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di +taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7 +lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj +yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn +Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy +yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n +wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6 +OV+KmalBWQewLK8= +-----END CERTIFICATE----- diff --git a/make/data/currency/CurrencyData.properties b/make/data/currency/CurrencyData.properties index 12c0c69801e..26f4aa24d88 100644 --- a/make/data/currency/CurrencyData.properties +++ b/make/data/currency/CurrencyData.properties @@ -32,7 +32,7 @@ formatVersion=3 # Version of the currency code information in this class. # It is a serial number that accompanies with each amendment. -dataVersion=175 +dataVersion=176 # List of all valid ISO 4217 currency codes. # To ensure compatibility, do not remove codes. @@ -55,7 +55,7 @@ all=ADP020-AED784-AFA004-AFN971-ALL008-AMD051-ANG532-AOA973-ARS032-ATS040-AUD036 SRD968-SRG740-SSP728-STD678-STN930-SVC222-SYP760-SZL748-THB764-TJS972-TMM795-TMT934-TND788-TOP776-\ TPE626-TRL792-TRY949-TTD780-TWD901-TZS834-UAH980-UGX800-USD840-USN997-USS998-UYI940-\ UYU858-UZS860-VEB862-VED926-VEF937-VES928-VND704-VUV548-WST882-XAF950-XAG961-XAU959-XBA955-\ - XBB956-XBC957-XBD958-XCD951-XDR960-XFO000-XFU000-XOF952-XPD964-XPF953-\ + XBB956-XBC957-XBD958-XCD951-XCG532-XDR960-XFO000-XFU000-XOF952-XPD964-XPF953-\ XPT962-XSU994-XTS963-XUA965-XXX999-YER886-YUM891-ZAR710-ZMK894-ZMW967-ZWD716-ZWL932-\ ZWN942-ZWR935 @@ -189,11 +189,11 @@ CR=CRC # COTE D'IVOIRE CI=XOF # CROATIA -HR=HRK;2022-12-31-23-00-00;EUR +HR=EUR # CUBA CU=CUP # Cura\u00e7ao -CW=ANG +CW=ANG;2025-04-01-04-00-00;XCG # CYPRUS CY=EUR # CZECHIA @@ -510,7 +510,7 @@ SR=SRD # SVALBARD AND JAN MAYEN SJ=NOK # Sint Maarten (Dutch part) -SX=ANG +SX=ANG;2025-04-01-04-00-00;XCG # ESWATINI SZ=SZL # SWEDEN diff --git a/make/data/lsrdata/language-subtag-registry.txt b/make/data/lsrdata/language-subtag-registry.txt index 92e0a26f0cd..4737c50e425 100644 --- a/make/data/lsrdata/language-subtag-registry.txt +++ b/make/data/lsrdata/language-subtag-registry.txt @@ -1,4 +1,4 @@ -File-Date: 2022-08-08 +File-Date: 2024-03-07 %% Type: language Subtag: aa @@ -882,6 +882,7 @@ Type: language Subtag: sa Description: Sanskrit Added: 2005-10-16 +Scope: macrolanguage %% Type: language Subtag: sc @@ -2143,6 +2144,8 @@ Type: language Subtag: ajp Description: South Levantine Arabic Added: 2009-07-29 +Deprecated: 2023-03-17 +Preferred-Value: apc Macrolanguage: ar %% Type: language @@ -2790,7 +2793,7 @@ Added: 2009-07-29 %% Type: language Subtag: apc -Description: North Levantine Arabic +Description: Levantine Arabic Added: 2009-07-29 Macrolanguage: ar %% @@ -8026,6 +8029,12 @@ Description: Lowland Oaxaca Chontal Added: 2009-07-29 %% Type: language +Subtag: cls +Description: Classical Sanskrit +Added: 2024-03-04 +Macrolanguage: sa +%% +Type: language Subtag: clt Description: Lautu Chin Added: 2012-08-12 @@ -8910,6 +8919,11 @@ Description: Kuwaataay Added: 2009-07-29 %% Type: language +Subtag: cxh +Description: Cha'ari +Added: 2023-03-17 +%% +Type: language Subtag: cya Description: Nopala Chatino Added: 2009-07-29 @@ -10176,6 +10190,11 @@ Description: Disa Added: 2009-07-29 %% Type: language +Subtag: dsk +Description: Dokshi +Added: 2023-03-17 +%% +Type: language Subtag: dsl Description: Danish Sign Language Added: 2009-07-29 @@ -10503,6 +10522,11 @@ Description: Jola-Fonyi Added: 2009-07-29 %% Type: language +Subtag: dyr +Description: Dyarim +Added: 2023-03-17 +%% +Type: language Subtag: dyu Description: Dyula Added: 2005-10-16 @@ -10522,7 +10546,6 @@ Type: language Subtag: dzd Description: Daza Added: 2009-07-29 -Deprecated: 2015-02-12 %% Type: language Subtag: dze @@ -11146,6 +11169,11 @@ Description: Semimi Added: 2009-07-29 %% Type: language +Subtag: eud +Description: Eudeve +Added: 2023-03-17 +%% +Type: language Subtag: euq Description: Basque (family) Added: 2009-07-29 @@ -14805,6 +14833,11 @@ Added: 2009-07-29 Macrolanguage: iu %% Type: language +Subtag: ikh +Description: Ikhin-Arokho +Added: 2023-03-17 +%% +Type: language Subtag: iki Description: Iko Added: 2009-07-29 @@ -15380,6 +15413,11 @@ Deprecated: 2013-09-10 Comments: see eza, gmz, iqw, izz %% Type: language +Subtag: izm +Description: Kizamani +Added: 2023-03-17 +%% +Type: language Subtag: izr Description: Izere Added: 2009-07-29 @@ -16922,6 +16960,8 @@ Type: language Subtag: kgm Description: Karipúna Added: 2009-07-29 +Deprecated: 2023-03-17 +Preferred-Value: plu %% Type: language Subtag: kgn @@ -18339,7 +18379,7 @@ Scope: collection %% Type: language Subtag: krp -Description: Korop +Description: Durop Added: 2009-07-29 %% Type: language @@ -18392,6 +18432,8 @@ Type: language Subtag: ksa Description: Shuwa-Zamani Added: 2009-07-29 +Deprecated: 2023-03-17 +Comments: see izm, rsw %% Type: language Subtag: ksb @@ -19476,7 +19518,7 @@ Added: 2009-07-29 %% Type: language Subtag: lag -Description: Langi +Description: Rangi Added: 2009-07-29 %% Type: language @@ -20011,6 +20053,12 @@ Description: Lengo Added: 2009-07-29 %% Type: language +Subtag: lgs +Description: Guinea-Bissau Sign Language +Description: Língua Gestual Guineense +Added: 2023-03-17 +%% +Type: language Subtag: lgt Description: Pahi Added: 2009-07-29 @@ -20655,6 +20703,7 @@ Added: 2009-07-29 %% Type: language Subtag: loh +Description: Laarim Description: Narim Added: 2009-07-29 %% @@ -21129,6 +21178,11 @@ Description: Lavukaleve Added: 2009-07-29 %% Type: language +Subtag: lvl +Description: Lwel +Added: 2023-03-17 +%% +Type: language Subtag: lvs Description: Standard Latvian Added: 2010-03-11 @@ -26188,6 +26242,8 @@ Type: language Subtag: nom Description: Nocamán Added: 2009-07-29 +Deprecated: 2023-03-17 +Preferred-Value: cbr %% Type: language Subtag: non @@ -26378,6 +26434,7 @@ Type: language Subtag: nrf Description: Jèrriais Description: Guernésiais +Description: Sercquiais Added: 2015-02-12 %% Type: language @@ -27087,6 +27144,11 @@ Description: Zeme Naga Added: 2009-07-29 %% Type: language +Subtag: nzr +Description: Dir-Nyamzak-Mbarimi +Added: 2023-03-17 +%% +Type: language Subtag: nzs Description: New Zealand Sign Language Added: 2009-07-29 @@ -28845,6 +28907,8 @@ Type: language Subtag: plj Description: Polci Added: 2009-07-29 +Deprecated: 2023-03-17 +Comments: see nzr, pze, uly, zlu %% Type: language Subtag: plk @@ -28970,6 +29034,8 @@ Type: language Subtag: pmk Description: Pamlico Added: 2009-07-29 +Deprecated: 2023-03-17 +Preferred-Value: crr %% Type: language Subtag: pml @@ -29446,6 +29512,8 @@ Type: language Subtag: prp Description: Parsi Added: 2009-07-29 +Deprecated: 2023-03-17 +Preferred-Value: gu %% Type: language Subtag: prq @@ -29857,6 +29925,11 @@ Description: Pyen Added: 2009-07-29 %% Type: language +Subtag: pze +Description: Pesse +Added: 2023-03-17 +%% +Type: language Subtag: pzh Description: Pazeh Added: 2022-02-25 @@ -30850,6 +30923,11 @@ Description: Ririo Added: 2009-07-29 %% Type: language +Subtag: rrm +Description: Moriori +Added: 2024-03-04 +%% +Type: language Subtag: rro Description: Waima Added: 2009-07-29 @@ -30873,7 +30951,7 @@ Deprecated: 2017-02-23 Type: language Subtag: rsk Description: Ruthenian -Description: Rusyn +Description: Rusnak Added: 2022-02-25 %% Type: language @@ -30892,6 +30970,11 @@ Description: Rwandan Sign Language Added: 2022-02-25 %% Type: language +Subtag: rsw +Description: Rishiwa +Added: 2023-03-17 +%% +Type: language Subtag: rtc Description: Rungtu Chin Added: 2012-08-12 @@ -32328,6 +32411,7 @@ Type: language Subtag: slq Description: Salchuq Added: 2009-07-29 +Deprecated: 2023-03-17 %% Type: language Subtag: slr @@ -33685,6 +33769,8 @@ Type: language Subtag: szd Description: Seru Added: 2009-07-29 +Deprecated: 2023-03-17 +Preferred-Value: umi %% Type: language Subtag: sze @@ -35065,6 +35151,8 @@ Type: language Subtag: tmk Description: Northwestern Tamang Added: 2009-07-29 +Deprecated: 2023-03-17 +Preferred-Value: tdg %% Type: language Subtag: tml @@ -35481,6 +35569,8 @@ Type: language Subtag: tpw Description: Tupí Added: 2009-07-29 +Deprecated: 2023-03-17 +Preferred-Value: tpn %% Type: language Subtag: tpx @@ -36076,6 +36166,11 @@ Description: Te'un Added: 2009-07-29 %% Type: language +Subtag: tvi +Description: Tulai +Added: 2023-03-17 +%% +Type: language Subtag: tvk Description: Southeast Ambrym Added: 2009-07-29 @@ -36727,6 +36822,11 @@ Description: Ulwa Added: 2010-03-11 %% Type: language +Subtag: uly +Description: Buli +Added: 2023-03-17 +%% +Type: language Subtag: uma Description: Umatilla Added: 2009-07-29 @@ -37318,6 +37418,11 @@ Description: Iduna Added: 2009-07-29 %% Type: language +Subtag: vjk +Description: Bajjika +Added: 2023-03-17 +%% +Type: language Subtag: vka Description: Kariyarra Added: 2009-07-29 @@ -37567,6 +37672,12 @@ Description: Venezuelan Sign Language Added: 2009-07-29 %% Type: language +Subtag: vsn +Description: Vedic Sanskrit +Added: 2024-03-04 +Macrolanguage: sa +%% +Type: language Subtag: vsv Description: Valencian Sign Language Description: Llengua de signes valenciana @@ -38316,7 +38427,7 @@ Added: 2009-07-29 %% Type: language Subtag: wnb -Description: Wanambre +Description: Mokati Added: 2009-07-29 %% Type: language @@ -38619,6 +38730,11 @@ Description: Wotapuri-Katarqalai Added: 2009-07-29 %% Type: language +Subtag: wtb +Description: Matambwe +Added: 2023-03-17 +%% +Type: language Subtag: wtf Description: Watiwa Added: 2009-07-29 @@ -40085,6 +40201,8 @@ Type: language Subtag: xss Description: Assan Added: 2009-07-29 +Deprecated: 2023-03-17 +Preferred-Value: zko %% Type: language Subtag: xsu @@ -40668,6 +40786,11 @@ Description: Chepya Added: 2009-07-29 %% Type: language +Subtag: ycr +Description: Yilan Creole +Added: 2023-03-17 +%% +Type: language Subtag: yda Description: Yanda Added: 2013-09-10 @@ -40947,6 +41070,11 @@ Description: Northern Yukaghir Added: 2009-07-29 %% Type: language +Subtag: ykh +Description: Khamnigan Mongol +Added: 2023-03-17 +%% +Type: language Subtag: yki Description: Yoke Added: 2009-07-29 @@ -41921,6 +42049,11 @@ Added: 2009-07-29 Macrolanguage: za %% Type: language +Subtag: zem +Description: Zeem +Added: 2023-03-17 +%% +Type: language Subtag: zen Description: Zenaga Added: 2005-10-16 @@ -42047,6 +42180,8 @@ Type: language Subtag: zkb Description: Koibal Added: 2009-07-29 +Deprecated: 2023-03-17 +Preferred-Value: kjh %% Type: language Subtag: zkd @@ -42150,6 +42285,11 @@ Added: 2009-07-29 Scope: collection %% Type: language +Subtag: zlu +Description: Zul +Added: 2023-03-17 +%% +Type: language Subtag: zlw Description: West Slavic languages Added: 2009-07-29 @@ -42654,6 +42794,8 @@ Type: language Subtag: zua Description: Zeem Added: 2009-07-29 +Deprecated: 2023-03-17 +Comments: see cxh, dsk, dyr, tvi, zem %% Type: language Subtag: zuh @@ -42861,6 +43003,7 @@ Type: extlang Subtag: ajp Description: South Levantine Arabic Added: 2009-07-29 +Deprecated: 2023-03-17 Preferred-Value: ajp Prefix: ar Macrolanguage: ar @@ -42874,7 +43017,7 @@ Prefix: sgn %% Type: extlang Subtag: apc -Description: North Levantine Arabic +Description: Levantine Arabic Added: 2009-07-29 Preferred-Value: apc Prefix: ar @@ -43695,6 +43838,14 @@ Prefix: ms Macrolanguage: ms %% Type: extlang +Subtag: lgs +Description: Guinea-Bissau Sign Language +Description: Língua Gestual Guineense +Added: 2023-03-17 +Preferred-Value: lgs +Prefix: sgn +%% +Type: extlang Subtag: liw Description: Col Added: 2009-07-29 @@ -44747,6 +44898,11 @@ Description: Cherokee Added: 2005-10-16 %% Type: script +Subtag: Chis +Description: Chisoi +Added: 2023-10-16 +%% +Type: script Subtag: Chrs Description: Chorasmian Added: 2019-09-11 @@ -44842,6 +44998,11 @@ Description: Ge'ez Added: 2005-10-16 %% Type: script +Subtag: Gara +Description: Garay +Added: 2023-10-16 +%% +Type: script Subtag: Geok Description: Khutsuri (Asomtavruli and Nuskhuri) Added: 2005-10-16 @@ -44887,6 +45048,11 @@ Description: Gujarati Added: 2005-10-16 %% Type: script +Subtag: Gukh +Description: Gurung Khema +Added: 2023-10-16 +%% +Type: script Subtag: Guru Description: Gurmukhi Added: 2005-10-16 @@ -45057,6 +45223,11 @@ Description: Kpelle Added: 2010-04-10 %% Type: script +Subtag: Krai +Description: Kirat Rai +Added: 2023-10-16 +%% +Type: script Subtag: Kthi Description: Kaithi Added: 2007-12-05 @@ -45304,6 +45475,11 @@ Description: Santali Added: 2006-07-21 %% Type: script +Subtag: Onao +Description: Ol Onal +Added: 2023-10-16 +%% +Type: script Subtag: Orkh Description: Old Turkic Description: Orkhon Runic @@ -45483,6 +45659,11 @@ Description: Siddhamātṛkā Added: 2013-12-02 %% Type: script +Subtag: Sidt +Description: Sidetic +Added: 2023-10-16 +%% +Type: script Subtag: Sind Description: Khudawadi Description: Sindhi @@ -45586,6 +45767,11 @@ Description: Tai Viet Added: 2007-12-05 %% Type: script +Subtag: Tayo +Description: Tai Yo +Added: 2023-10-16 +%% +Type: script Subtag: Telu Description: Telugu Added: 2005-10-16 @@ -45634,11 +45820,26 @@ Description: Tangsa Added: 2021-03-05 %% Type: script +Subtag: Todr +Description: Todhri +Added: 2023-10-16 +%% +Type: script +Subtag: Tols +Description: Tolong Siki +Added: 2023-10-16 +%% +Type: script Subtag: Toto Description: Toto Added: 2020-05-12 %% Type: script +Subtag: Tutg +Description: Tulu-Tigalari +Added: 2023-10-16 +%% +Type: script Subtag: Ugar Description: Ugaritic Added: 2005-10-16 @@ -46013,6 +46214,11 @@ Description: Clipperton Island Added: 2009-07-29 %% Type: region +Subtag: CQ +Description: Sark +Added: 2023-02-07 +%% +Type: region Subtag: CR Description: Costa Rica Added: 2005-10-16 @@ -47371,6 +47577,13 @@ Comments: Aluku dialect of the "Busi Nenge Tongo" English-based Creole continuum in Eastern Suriname and Western French Guiana %% Type: variant +Subtag: anpezo +Description: Anpezo standard of Ladin +Added: 2024-03-04 +Prefix: lld +Comments: Represents the standard written form of Ladin in Anpezo +%% +Type: variant Subtag: ao1990 Description: Portuguese Language Orthographic Agreement of 1990 (Acordo Ortográfico da Língua Portuguesa de 1990) @@ -47474,6 +47687,23 @@ Added: 2010-07-28 Prefix: sa %% Type: variant +Subtag: bciav +Description: BCI Blissymbolics AV +Added: 2023-05-11 +Prefix: zbl +Comments: Name given to a subset of the variety of Blissymbolics curated + by Blissymbolics Communication International, as represented by + entries in the BCI Authorized Vocabulary +%% +Type: variant +Subtag: bcizbl +Description: BCI Blissymbolics +Added: 2023-05-11 +Prefix: zbl +Comments: Name given to the variety of Blissymbolics curated by + Blissymbolics Communication International +%% +Type: variant Subtag: biscayan Description: Biscayan dialect of Basque Added: 2010-04-13 @@ -47489,6 +47719,15 @@ Comments: The dialect of San Giorgio/Bila is one of the four major local dialects of Resian %% Type: variant +Subtag: blasl +Description: Black American Sign Language dialect +Added: 2023-07-31 +Prefix: ase +Prefix: sgn-ase +Comments: Black American Sign Language (BASL) or Black Sign Variation + (BSV) is a dialect of American Sign Language (ASL) +%% +Type: variant Subtag: bohoric Description: Slovene in Bohorič alphabet Added: 2012-06-27 @@ -47565,6 +47804,22 @@ Added: 2012-02-05 Prefix: en %% Type: variant +Subtag: fascia +Description: Fascia standard of Ladin +Added: 2024-03-04 +Prefix: lld +Comments: Represents the standard written form of Ladin in Fascia which + unified the three subvarieties Cazet, Brach and Moenat +%% +Type: variant +Subtag: fodom +Description: Fodom standard of Ladin +Added: 2024-03-04 +Prefix: lld +Comments: Represents the standard written form of Ladin in Livinallongo + and Colle Santa Lucia +%% +Type: variant Subtag: fonipa Description: International Phonetic Alphabet Added: 2006-12-11 @@ -47605,6 +47860,13 @@ Prefix: oc Comments: Occitan variant spoken in Gascony %% Type: variant +Subtag: gherd +Description: Gherdëina standard of Ladin +Added: 2024-03-04 +Prefix: lld +Comments: Represents the standard written form of Ladin in Gherdëina +%% +Type: variant Subtag: grclass Description: Classical Occitan orthography Added: 2018-04-22 @@ -47906,6 +48168,15 @@ Comments: Peano’s Interlingua, created in 1903 by Giuseppe Peano as an Added: 2020-03-12 %% Type: variant +Subtag: pehoeji +Description: Hokkien Vernacular Romanization System +Description: Pe̍h-ōe-jī orthography/romanization +Added: 2024-03-04 +Prefix: nan-Latn +Comments: Modern Hokkien Vernacular Romanization System, evolved from + the New Dictionary in the Amoy by John Van Nest Talmage in 1894 +%% +Type: variant Subtag: petr1708 Description: Petrine orthography Added: 2010-10-10 @@ -48040,6 +48311,16 @@ Added: 2021-07-17 Prefix: da %% Type: variant +Subtag: tailo +Description: Taiwanese Hokkien Romanization System for Hokkien + languages +Description: Tâi-lô orthography/romanization +Added: 2024-03-04 +Prefix: nan-Latn +Comments: Taiwanese Hokkien Romanization System (Tâi-lô) published in + 2006 by the Taiwan Ministry of Education +%% +Type: variant Subtag: tarask Description: Belarusian in Taraskievica orthography Added: 2007-04-27 @@ -48103,6 +48384,15 @@ Comments: The most ancient dialect of Sanskrit used in verse and prose composed until about the 4th century B.C.E. %% Type: variant +Subtag: valbadia +Description: Val Badia standard of Ladin +Added: 2024-03-04 +Prefix: lld +Comments: Represents the standard written form of Ladin in the Val + Badia, unifying the three variants Marô, Mesaval and Badiot spoken + in this valley +%% +Type: variant Subtag: valencia Description: Valencian Added: 2007-03-06 diff --git a/make/data/tzdata/VERSION b/make/data/tzdata/VERSION index 560884d1a82..b138ed7fa78 100644 --- a/make/data/tzdata/VERSION +++ b/make/data/tzdata/VERSION @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2023d +tzdata2024a diff --git a/make/data/tzdata/africa b/make/data/tzdata/africa index b4789b16c71..72b188f074d 100644 --- a/make/data/tzdata/africa +++ b/make/data/tzdata/africa @@ -53,6 +53,10 @@ # Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94. # https://www.jstor.org/stable/1774359 # +# For the 1911/1912 establishment of standard time in French possessions, see: +# Société Française de Physique, Recueil de constantes physiques (1913), +# page 752, 18b. +# # European-style abbreviations are commonly used along the Mediterranean. # For sub-Saharan Africa abbreviations were less standardized. # Previous editions of this database used WAT, CAT, SAT, and EAT @@ -136,7 +140,7 @@ Zone Atlantic/Cape_Verde -1:34:04 - LMT 1912 Jan 01 2:00u # Praia # Chad # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone Africa/Ndjamena 1:00:12 - LMT 1912 # N'Djamena +Zone Africa/Ndjamena 1:00:12 - LMT 1912 Jan 1 # N'Djamena 1:00 - WAT 1979 Oct 14 1:00 1:00 WAST 1980 Mar 8 1:00 - WAT @@ -162,7 +166,7 @@ Zone Africa/Ndjamena 1:00:12 - LMT 1912 # N'Djamena # Inaccessible, Nightingale: uninhabited # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone Africa/Abidjan -0:16:08 - LMT 1912 +Zone Africa/Abidjan -0:16:08 - LMT 1912 Jan 1 0:00 - GMT ############################################################################### diff --git a/make/data/tzdata/asia b/make/data/tzdata/asia index f86f84b2d27..3a54291919d 100644 --- a/make/data/tzdata/asia +++ b/make/data/tzdata/asia @@ -2480,18 +2480,33 @@ Zone Asia/Amman 2:23:44 - LMT 1931 # effective December 21st, 2018.... # http://adilet.zan.kz/rus/docs/P1800000817 (russian language). +# From Zhanbolat Raimbekov (2024-01-19): +# Kazakhstan (all parts) switching to UTC+5 on March 1, 2024 +# https://www.gov.kz/memleket/entities/mti/press/news/details/688998?lang=ru +# [in Russian] +# (2024-01-20): https://primeminister.kz/ru/decisions/19012024-20 +# +# From Alexander Krivenyshev (2024-01-19): +# According to a different news and the official web site for the Ministry of +# Trade and Integration of the Republic of Kazakhstan: +# https://en.inform.kz/news/kazakhstan-to-switch-to-single-hour-zone-mar-1-54ad0b/ + # Zone NAME STDOFF RULES FORMAT [UNTIL] # # Almaty (formerly Alma-Ata), representing most locations in Kazakhstan -# This includes KZ-AKM, KZ-ALA, KZ-ALM, KZ-AST, KZ-BAY, KZ-VOS, KZ-ZHA, -# KZ-KAR, KZ-SEV, KZ-PAV, and KZ-YUZ. +# This includes Abai/Abay (ISO 3166-2 code KZ-10), Aqmola/Akmola (KZ-11), +# Almaty (KZ-19), Almaty city (KZ-75), Astana city (KZ-71), +# East Kazkhstan (KZ-63), Jambyl/Zhambyl (KZ-31), Jetisu/Zhetysu (KZ-33), +# Karaganda (KZ-35), North Kazakhstan (KZ-59), Pavlodar (KZ-55), +# Shyumkent city (KZ-79), Turkistan (KZ-61), and Ulytau (KZ-62). Zone Asia/Almaty 5:07:48 - LMT 1924 May 2 # or Alma-Ata 5:00 - +05 1930 Jun 21 6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s 5:00 RussiaAsia +05/+06 1992 Jan 19 2:00s 6:00 RussiaAsia +06/+07 2004 Oct 31 2:00s - 6:00 - +06 -# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) (KZ-KZY) + 6:00 - +06 2024 Mar 1 0:00 + 5:00 - +05 +# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) (KZ-43) Zone Asia/Qyzylorda 4:21:52 - LMT 1924 May 2 4:00 - +04 1930 Jun 21 5:00 - +05 1981 Apr 1 @@ -2504,8 +2519,7 @@ Zone Asia/Qyzylorda 4:21:52 - LMT 1924 May 2 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s 6:00 - +06 2018 Dec 21 0:00 5:00 - +05 -# -# Qostanay (aka Kostanay, Kustanay) (KZ-KUS) +# Qostanay (aka Kostanay, Kustanay) (KZ-39) # The 1991/2 rules are unclear partly because of the 1997 Turgai # reorganization. Zone Asia/Qostanay 4:14:28 - LMT 1924 May 2 @@ -2516,9 +2530,9 @@ Zone Asia/Qostanay 4:14:28 - LMT 1924 May 2 5:00 RussiaAsia +05/+06 1991 Mar 31 2:00s 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s - 6:00 - +06 - -# Aqtöbe (aka Aktobe, formerly Aktyubinsk) (KZ-AKT) + 6:00 - +06 2024 Mar 1 0:00 + 5:00 - +05 +# Aqtöbe (aka Aktobe, formerly Aktyubinsk) (KZ-15) Zone Asia/Aqtobe 3:48:40 - LMT 1924 May 2 4:00 - +04 1930 Jun 21 5:00 - +05 1981 Apr 1 @@ -2528,7 +2542,7 @@ Zone Asia/Aqtobe 3:48:40 - LMT 1924 May 2 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00s 5:00 RussiaAsia +05/+06 2004 Oct 31 2:00s 5:00 - +05 -# Mangghystaū (KZ-MAN) +# Mangghystaū (KZ-47) # Aqtau was not founded until 1963, but it represents an inhabited region, # so include timestamps before 1963. Zone Asia/Aqtau 3:21:04 - LMT 1924 May 2 @@ -2540,7 +2554,7 @@ Zone Asia/Aqtau 3:21:04 - LMT 1924 May 2 5:00 RussiaAsia +05/+06 1994 Sep 25 2:00s 4:00 RussiaAsia +04/+05 2004 Oct 31 2:00s 5:00 - +05 -# Atyraū (KZ-ATY) is like Mangghystaū except it switched from +# Atyraū (KZ-23) is like Mangghystaū except it switched from # +04/+05 to +05/+06 in spring 1999, not fall 1994. Zone Asia/Atyrau 3:27:44 - LMT 1924 May 2 3:00 - +03 1930 Jun 21 @@ -2551,7 +2565,7 @@ Zone Asia/Atyrau 3:27:44 - LMT 1924 May 2 5:00 RussiaAsia +05/+06 1999 Mar 28 2:00s 4:00 RussiaAsia +04/+05 2004 Oct 31 2:00s 5:00 - +05 -# West Kazakhstan (KZ-ZAP) +# West Kazakhstan (KZ-27) # From Paul Eggert (2016-03-18): # The 1989 transition is from USSR act No. 227 (1989-03-14). Zone Asia/Oral 3:25:24 - LMT 1924 May 2 # or Ural'sk @@ -3453,19 +3467,26 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # ... winter time will begin in Palestine from Saturday 10-28-2023, # 02:00 AM by 60 minutes back. # -# From Paul Eggert (2023-03-22): +# From Heba Hamad (2024-01-25): +# the summer time for the years 2024,2025 will begin in Palestine +# from Saturday at 02:00 AM by 60 minutes forward as shown below: +# year date +# 2024 2024-04-20 +# 2025 2025-04-12 +# +# From Paul Eggert (2024-01-25): # For now, guess that spring and fall transitions will normally # continue to use 2022's rules, that during DST Palestine will switch # to standard time at 02:00 the last Saturday before Ramadan and back -# to DST at 02:00 the first Saturday after Ramadan, and that +# to DST at 02:00 the second Saturday after Ramadan, and that # if the normal spring-forward or fall-back transition occurs during # Ramadan the former is delayed and the latter advanced. # To implement this, I predicted Ramadan-oriented transition dates for -# 2023 through 2086 by running the following program under GNU Emacs 28.2, +# 2026 through 2086 by running the following program under GNU Emacs 29.2, # with the results integrated by hand into the table below. # Predictions after 2086 are approximated without Ramadan. # -# (let ((islamic-year 1444)) +# (let ((islamic-year 1447)) # (require 'cal-islam) # (while (< islamic-year 1510) # (let ((a (calendar-islamic-to-absolute (list 9 1 islamic-year))) @@ -3474,6 +3495,7 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # (while (/= saturday (mod (setq a (1- a)) 7))) # (while (/= saturday (mod b 7)) # (setq b (1+ b))) +# (setq b (+ 7 b)) # (setq a (calendar-gregorian-from-absolute a)) # (setq b (calendar-gregorian-from-absolute b)) # (insert @@ -3524,84 +3546,84 @@ Rule Palestine 2021 only - Oct 29 1:00 0 - Rule Palestine 2022 only - Mar 27 0:00 1:00 S Rule Palestine 2022 2035 - Oct Sat<=30 2:00 0 - Rule Palestine 2023 only - Apr 29 2:00 1:00 S -Rule Palestine 2024 only - Apr 13 2:00 1:00 S -Rule Palestine 2025 only - Apr 5 2:00 1:00 S +Rule Palestine 2024 only - Apr 20 2:00 1:00 S +Rule Palestine 2025 only - Apr 12 2:00 1:00 S Rule Palestine 2026 2054 - Mar Sat<=30 2:00 1:00 S Rule Palestine 2036 only - Oct 18 2:00 0 - Rule Palestine 2037 only - Oct 10 2:00 0 - Rule Palestine 2038 only - Sep 25 2:00 0 - Rule Palestine 2039 only - Sep 17 2:00 0 - -Rule Palestine 2039 only - Oct 22 2:00 1:00 S -Rule Palestine 2039 2067 - Oct Sat<=30 2:00 0 - Rule Palestine 2040 only - Sep 1 2:00 0 - -Rule Palestine 2040 only - Oct 13 2:00 1:00 S +Rule Palestine 2040 only - Oct 20 2:00 1:00 S +Rule Palestine 2040 2067 - Oct Sat<=30 2:00 0 - Rule Palestine 2041 only - Aug 24 2:00 0 - -Rule Palestine 2041 only - Sep 28 2:00 1:00 S +Rule Palestine 2041 only - Oct 5 2:00 1:00 S Rule Palestine 2042 only - Aug 16 2:00 0 - -Rule Palestine 2042 only - Sep 20 2:00 1:00 S +Rule Palestine 2042 only - Sep 27 2:00 1:00 S Rule Palestine 2043 only - Aug 1 2:00 0 - -Rule Palestine 2043 only - Sep 12 2:00 1:00 S +Rule Palestine 2043 only - Sep 19 2:00 1:00 S Rule Palestine 2044 only - Jul 23 2:00 0 - -Rule Palestine 2044 only - Aug 27 2:00 1:00 S +Rule Palestine 2044 only - Sep 3 2:00 1:00 S Rule Palestine 2045 only - Jul 15 2:00 0 - -Rule Palestine 2045 only - Aug 19 2:00 1:00 S +Rule Palestine 2045 only - Aug 26 2:00 1:00 S Rule Palestine 2046 only - Jun 30 2:00 0 - -Rule Palestine 2046 only - Aug 11 2:00 1:00 S +Rule Palestine 2046 only - Aug 18 2:00 1:00 S Rule Palestine 2047 only - Jun 22 2:00 0 - -Rule Palestine 2047 only - Jul 27 2:00 1:00 S +Rule Palestine 2047 only - Aug 3 2:00 1:00 S Rule Palestine 2048 only - Jun 6 2:00 0 - -Rule Palestine 2048 only - Jul 18 2:00 1:00 S +Rule Palestine 2048 only - Jul 25 2:00 1:00 S Rule Palestine 2049 only - May 29 2:00 0 - -Rule Palestine 2049 only - Jul 3 2:00 1:00 S +Rule Palestine 2049 only - Jul 10 2:00 1:00 S Rule Palestine 2050 only - May 21 2:00 0 - -Rule Palestine 2050 only - Jun 25 2:00 1:00 S +Rule Palestine 2050 only - Jul 2 2:00 1:00 S Rule Palestine 2051 only - May 6 2:00 0 - -Rule Palestine 2051 only - Jun 17 2:00 1:00 S +Rule Palestine 2051 only - Jun 24 2:00 1:00 S Rule Palestine 2052 only - Apr 27 2:00 0 - -Rule Palestine 2052 only - Jun 1 2:00 1:00 S +Rule Palestine 2052 only - Jun 8 2:00 1:00 S Rule Palestine 2053 only - Apr 12 2:00 0 - -Rule Palestine 2053 only - May 24 2:00 1:00 S +Rule Palestine 2053 only - May 31 2:00 1:00 S Rule Palestine 2054 only - Apr 4 2:00 0 - -Rule Palestine 2054 only - May 16 2:00 1:00 S -Rule Palestine 2055 only - May 1 2:00 1:00 S -Rule Palestine 2056 only - Apr 22 2:00 1:00 S -Rule Palestine 2057 only - Apr 7 2:00 1:00 S -Rule Palestine 2058 max - Mar Sat<=30 2:00 1:00 S +Rule Palestine 2054 only - May 23 2:00 1:00 S +Rule Palestine 2055 only - May 8 2:00 1:00 S +Rule Palestine 2056 only - Apr 29 2:00 1:00 S +Rule Palestine 2057 only - Apr 14 2:00 1:00 S +Rule Palestine 2058 only - Apr 6 2:00 1:00 S +Rule Palestine 2059 max - Mar Sat<=30 2:00 1:00 S Rule Palestine 2068 only - Oct 20 2:00 0 - Rule Palestine 2069 only - Oct 12 2:00 0 - Rule Palestine 2070 only - Oct 4 2:00 0 - Rule Palestine 2071 only - Sep 19 2:00 0 - Rule Palestine 2072 only - Sep 10 2:00 0 - -Rule Palestine 2072 only - Oct 15 2:00 1:00 S +Rule Palestine 2072 only - Oct 22 2:00 1:00 S Rule Palestine 2072 max - Oct Sat<=30 2:00 0 - Rule Palestine 2073 only - Sep 2 2:00 0 - -Rule Palestine 2073 only - Oct 7 2:00 1:00 S +Rule Palestine 2073 only - Oct 14 2:00 1:00 S Rule Palestine 2074 only - Aug 18 2:00 0 - -Rule Palestine 2074 only - Sep 29 2:00 1:00 S +Rule Palestine 2074 only - Oct 6 2:00 1:00 S Rule Palestine 2075 only - Aug 10 2:00 0 - -Rule Palestine 2075 only - Sep 14 2:00 1:00 S +Rule Palestine 2075 only - Sep 21 2:00 1:00 S Rule Palestine 2076 only - Jul 25 2:00 0 - -Rule Palestine 2076 only - Sep 5 2:00 1:00 S +Rule Palestine 2076 only - Sep 12 2:00 1:00 S Rule Palestine 2077 only - Jul 17 2:00 0 - -Rule Palestine 2077 only - Aug 28 2:00 1:00 S +Rule Palestine 2077 only - Sep 4 2:00 1:00 S Rule Palestine 2078 only - Jul 9 2:00 0 - -Rule Palestine 2078 only - Aug 13 2:00 1:00 S +Rule Palestine 2078 only - Aug 20 2:00 1:00 S Rule Palestine 2079 only - Jun 24 2:00 0 - -Rule Palestine 2079 only - Aug 5 2:00 1:00 S +Rule Palestine 2079 only - Aug 12 2:00 1:00 S Rule Palestine 2080 only - Jun 15 2:00 0 - -Rule Palestine 2080 only - Jul 20 2:00 1:00 S +Rule Palestine 2080 only - Jul 27 2:00 1:00 S Rule Palestine 2081 only - Jun 7 2:00 0 - -Rule Palestine 2081 only - Jul 12 2:00 1:00 S +Rule Palestine 2081 only - Jul 19 2:00 1:00 S Rule Palestine 2082 only - May 23 2:00 0 - -Rule Palestine 2082 only - Jul 4 2:00 1:00 S +Rule Palestine 2082 only - Jul 11 2:00 1:00 S Rule Palestine 2083 only - May 15 2:00 0 - -Rule Palestine 2083 only - Jun 19 2:00 1:00 S +Rule Palestine 2083 only - Jun 26 2:00 1:00 S Rule Palestine 2084 only - Apr 29 2:00 0 - -Rule Palestine 2084 only - Jun 10 2:00 1:00 S +Rule Palestine 2084 only - Jun 17 2:00 1:00 S Rule Palestine 2085 only - Apr 21 2:00 0 - -Rule Palestine 2085 only - Jun 2 2:00 1:00 S +Rule Palestine 2085 only - Jun 9 2:00 1:00 S Rule Palestine 2086 only - Apr 13 2:00 0 - -Rule Palestine 2086 only - May 18 2:00 1:00 S +Rule Palestine 2086 only - May 25 2:00 1:00 S # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Gaza 2:17:52 - LMT 1900 Oct @@ -3629,7 +3651,7 @@ Zone Asia/Hebron 2:20:23 - LMT 1900 Oct # Philippines -# From Paul Eggert (2018-11-18): +# From Paul Eggert (2024-01-21): # The Spanish initially used American (west-of-Greenwich) time. # It is unknown what time Manila kept when the British occupied it from # 1762-10-06 through 1764-04; for now assume it kept American time. @@ -3637,7 +3659,7 @@ Zone Asia/Hebron 2:20:23 - LMT 1900 Oct # Philippines, issued a proclamation announcing that 1844-12-30 was to # be immediately followed by 1845-01-01; see R.H. van Gent's # History of the International Date Line -# https://www.staff.science.uu.nl/~gent0113/idl/idl_philippines.htm +# https://webspace.science.uu.nl/~gent0113/idl/idl_philippines.htm # The rest of the data entries are from Shanks & Pottenger. # From Jesper Nørgaard Welen (2006-04-26): @@ -4064,7 +4086,8 @@ Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2 # The English-language name of Vietnam's most populous city is "Ho Chi Minh # City"; use Ho_Chi_Minh below to avoid a name of more than 14 characters. -# From Paul Eggert (2022-07-27) after a 2014 heads-up from Trần Ngọc Quân: +# From Paul Eggert (2024-01-14) after a 2014 heads-up from Trần Ngọc Quân +# and a 2024-01-14 heads-up from Đoàn Trần Công Danh: # Trần Tiến Bình's authoritative book "Lịch Việt Nam: thế kỷ XX-XXI (1901-2100)" # (Nhà xuất bản Văn Hoá - Thông Tin, Hanoi, 2005), pp 49-50, # is quoted verbatim in: @@ -4094,14 +4117,35 @@ Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2 # # Trần cites the following sources; it's unclear which supplied the info above. # -# Hoàng Xuân Hãn: "Lịch và lịch Việt Nam". Tập san Khoa học Xã hội, -# No. 9, Paris, February 1982. +# Hoàng Xuân Hãn: "Lịch và lịch Việt Nam". Tập san Khoa học Xã hội, +# No. 9, Paris, February 1982. +# +# Lê Thành Lân: "Lịch và niên biểu lịch sử hai mươi thế kỷ (0001-2010)", +# NXB Thống kê, Hanoi, 2000. # -# Lê Thành Lân: "Lịch và niên biểu lịch sử hai mươi thế kỷ (0001-2010)", -# NXB Thống kê, Hanoi, 2000. +# Lê Thành Lân: "Lịch hai thế kỷ (1802-2010) và các lịch vĩnh cửu", +# NXB Thuận Hoá, Huế, 1995. # -# Lê Thành Lân: "Lịch hai thế kỷ (1802-2010) và các lịch vĩnh cửu", -# NXB Thuận Hoá, Huế, 1995. +# Here is the decision for the September 1945 transition: +# Võ Nguyên Giáp, Việt Nam Dân Quốc Công Báo, No. 1 (1945-09-29), page 13 +# http://baochi.nlv.gov.vn/baochi/cgi-bin/baochi?a=d&d=JwvzO19450929.2.5&dliv=none +# It says that on 1945-09-01 at 24:00, Vietnam moved back two hours, to +07. +# It also mentions a 1945-03-29 decree (by a Japanese Goveror-General) +# to set the time zone to +09, but does not say whether that decree +# merely legalized an earlier change to +09. +# +# July 1955 transition: +# Ngô Đình Diệm, Công Báo Việt Nam, No. 92 (1955-07-02), page 1780-1781 +# Ordinance (Dụ) No. 46 (1955-06-25) +# http://ddsnext.crl.edu/titles/32341#?c=0&m=29&s=0&cv=4&r=0&xywh=-89%2C342%2C1724%2C1216 +# It says that on 1955-07-01 at 01:00, South Vietnam moved back 1 hour (to +07). +# +# December 1959 transition: +# Ngô Đình Diệm, Công Báo Việt Nam Cộng Hòa, 1960 part 1 (1960-01-02), page 62 +# Decree (Sắc lệnh) No. 362-TTP (1959-12-30) +# http://ddsnext.crl.edu/titles/32341#?c=0&m=138&s=0&cv=793&r=0&xywh=-54%2C1504%2C1705%2C1202 +# It says that on 1959-12-31 at 23:00, South Vietnam moved forward 1 hour (to +08). + # Zone NAME STDOFF RULES FORMAT [UNTIL] #STDOFF 7:06:30.13 @@ -4109,9 +4153,9 @@ Zone Asia/Ho_Chi_Minh 7:06:30 - LMT 1906 Jul 1 7:06:30 - PLMT 1911 May 1 # Phù Liễn MT 7:00 - +07 1942 Dec 31 23:00 8:00 - +08 1945 Mar 14 23:00 - 9:00 - +09 1945 Sep 2 + 9:00 - +09 1945 Sep 1 24:00 7:00 - +07 1947 Apr 1 - 8:00 - +08 1955 Jul 1 + 8:00 - +08 1955 Jul 1 01:00 7:00 - +07 1959 Dec 31 23:00 8:00 - +08 1975 Jun 13 7:00 - +07 diff --git a/make/data/tzdata/australasia b/make/data/tzdata/australasia index 366cfd10cc1..624735be652 100644 --- a/make/data/tzdata/australasia +++ b/make/data/tzdata/australasia @@ -443,11 +443,11 @@ Zone Pacific/Fiji 11:55:44 - LMT 1915 Oct 26 # Suva # French Polynesia # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone Pacific/Gambier -8:59:48 - LMT 1912 Oct # Rikitea +Zone Pacific/Gambier -8:59:48 - LMT 1912 Oct 1 # Rikitea -9:00 - -09 -Zone Pacific/Marquesas -9:18:00 - LMT 1912 Oct +Zone Pacific/Marquesas -9:18:00 - LMT 1912 Oct 1 -9:30 - -0930 -Zone Pacific/Tahiti -9:58:16 - LMT 1912 Oct # Papeete +Zone Pacific/Tahiti -9:58:16 - LMT 1912 Oct 1 # Papeete -10:00 - -10 # Clipperton (near North America) is administered from French Polynesia; # it is uninhabited. @@ -825,7 +825,7 @@ Zone Pacific/Apia 12:33:04 - LMT 1892 Jul 5 # Solomon Is # excludes Bougainville, for which see Papua New Guinea # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone Pacific/Guadalcanal 10:39:48 - LMT 1912 Oct # Honiara +Zone Pacific/Guadalcanal 10:39:48 - LMT 1912 Oct 1 # Honiara 11:00 - +11 # Tokelau @@ -986,6 +986,10 @@ Zone Pacific/Efate 11:13:16 - LMT 1912 Jan 13 # Vila # Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94. # https://www.jstor.org/stable/1774359 # +# For the 1911/1912 establishment of standard time in French possessions, see: +# Société Française de Physique, Recueil de constantes physiques (1913), +# page 752, 18b. +# # A reliable and entertaining source about time zones is # Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997). # @@ -2062,7 +2066,7 @@ Zone Pacific/Efate 11:13:16 - LMT 1912 Jan 13 # Vila # ordaining - by a masterpiece of diplomatic flattery - that # the Fourth of July should be celebrated twice in that year." # This happened in 1892, according to the Evening News (Sydney) of 1892-07-20. -# https://www.staff.science.uu.nl/~gent0113/idl/idl.htm +# https://webspace.science.uu.nl/~gent0113/idl/idl_alaska_samoa.htm # Although Shanks & Pottenger says they both switched to UT -11:30 # in 1911, and to -11 in 1950. many earlier sources give -11 diff --git a/make/data/tzdata/etcetera b/make/data/tzdata/etcetera index 8ae294f524a..27147715ef6 100644 --- a/make/data/tzdata/etcetera +++ b/make/data/tzdata/etcetera @@ -28,7 +28,7 @@ # These entries are for uses not otherwise covered by the tz database. # Their main practical use is for platforms like Android that lack -# support for POSIX-style TZ strings. On such platforms these entries +# support for POSIX.1-2017-style TZ strings. On such platforms these entries # can be useful if the timezone database is wrong or if a ship or # aircraft at sea is not in a timezone. diff --git a/make/data/tzdata/europe b/make/data/tzdata/europe index f1b084f64d0..18865f33b6c 100644 --- a/make/data/tzdata/europe +++ b/make/data/tzdata/europe @@ -1013,9 +1013,34 @@ Zone Europe/Sofia 1:33:16 - LMT 1880 # Czech Republic (Czechia) # Slovakia # -# From Paul Eggert (2018-04-15): -# The source for Czech data is: Kdy začíná a končí letní čas. 2018-04-15. +# From Ivan Benovic (2024-01-30): +# https://www.slov-lex.sk/pravne-predpisy/SK/ZZ/1946/54/ +# (This is an official link to the Czechoslovak Summer Time Act of +# March 8, 1946 that authorizes the Czechoslovak government to set the +# exact dates of change to summer time and back to Central European Time. +# The act also implicitly confirms Central European Time as the +# official time zone of Czechoslovakia and currently remains in force +# in both the Czech Republic and Slovakia.) +# https://www.psp.cz/eknih/1945pns/tisky/t0216_00.htm +# (This is a link to the original legislative proposal dating back to +# February 22, 1946. The accompanying memorandum to the proposal says +# that an advisory committee on European railroad transportation that +# met in Brussels in October 1945 decided that the change of time +# should be carried out in all participating countries in a strictly +# coordinated manner....) +# +# From Paul Eggert (2024-01-30): +# The source for Czech data is: Kdy začíná a končí letní čas. # https://kalendar.beda.cz/kdy-zacina-a-konci-letni-cas +# Its main text disagrees with its quoted sources only in 1918, +# where the main text says spring and autumn transitions +# occurred at 02:00 and 03:00 respectively (as usual), +# whereas the 1918 source "Oznámení o zavedení letního času v roce 1918" +# says transitions were at 01:00 and 02:00 respectively. +# As the 1918 source appears to be a humorous piece, and it is +# unlikely that Prague would have disagreed with its neighbors by an hour, +# go with the main text for now. +# # We know of no English-language name for historical Czech winter time; # abbreviate it as "GMT", as it happened to be GMT. # diff --git a/make/data/tzdata/leapseconds b/make/data/tzdata/leapseconds index ab2c1af4bed..8e7df3de984 100644 --- a/make/data/tzdata/leapseconds +++ b/make/data/tzdata/leapseconds @@ -26,13 +26,10 @@ # This file is in the public domain. # This file is generated automatically from the data in the public-domain -# NIST format leap-seconds.list file, which can be copied from -# -# or . -# The NIST file is used instead of its IERS upstream counterpart +# NIST/IERS format leap-seconds.list file, which can be copied from # -# because under US law the NIST file is public domain -# whereas the IERS file's copyright and license status is unclear. +# or, in a variant with different comments, from +# . # For more about leap-seconds.list, please see # The NTP Timescale and Leap Seconds # . @@ -95,11 +92,11 @@ Leap 2016 Dec 31 23:59:60 + S # Any additional leap seconds will come after this. # This Expires line is commented out for now, # so that pre-2020a zic implementations do not reject this file. -#Expires 2024 Jun 28 00:00:00 +#Expires 2024 Dec 28 00:00:00 # POSIX timestamps for the data in this file: -#updated 1467936000 (2016-07-08 00:00:00 UTC) -#expires 1719532800 (2024-06-28 00:00:00 UTC) +#updated 1704708379 (2024-01-08 10:06:19 UTC) +#expires 1735344000 (2024-12-28 00:00:00 UTC) -# Updated through IERS Bulletin C66 -# File expires on: 28 June 2024 +# Updated through IERS Bulletin C (https://hpiers.obspm.fr/iers/bul/bulc/bulletinc.dat) +# File expires on 28 December 2024 diff --git a/make/data/tzdata/northamerica b/make/data/tzdata/northamerica index b96269a0e26..a8b2ef3f7fa 100644 --- a/make/data/tzdata/northamerica +++ b/make/data/tzdata/northamerica @@ -1291,6 +1291,10 @@ Zone America/Menominee -5:50:27 - LMT 1885 Sep 18 12:00 # # [PDF] (1914-03) # +# For the 1911/1912 establishment of standard time in French possessions, see: +# Société Française de Physique, Recueil de constantes physiques (1913), +# page 752, 18b. +# # See the 'europe' file for Greenland. # Canada @@ -1377,7 +1381,7 @@ Zone America/Menominee -5:50:27 - LMT 1885 Sep 18 12:00 # From Paul Eggert (2014-10-18): # H. David Matthews and Mary Vincent's map # "It's about TIME", _Canadian Geographic_ (September-October 1998) -# http://www.canadiangeographic.ca/Magazine/SO98/alacarte.asp +# https://web.archive.org/web/19990827055050/https://canadiangeographic.ca/SO98/geomap.htm # contains detailed boundaries for regions observing nonstandard # time and daylight saving time arrangements in Canada circa 1998. # @@ -1665,6 +1669,15 @@ Zone America/Moncton -4:19:08 - LMT 1883 Dec 9 # Some cities in the United States have pushed the deadline back # three weeks and will change over from daylight saving in October. +# From Chris Walton (2024-01-09): +# The [Toronto] changes in 1947, 1948, and 1949 took place at 2:00 a.m. local +# time instead of midnight.... Toronto Daily Star - ... +# April 2, 1947 - Page 39 ... April 7, 1948 - Page 13 ... +# April 2, 1949 - Page 1 ... April 7, 1949 - Page 24 ... +# November 25, 1949 - Page 52 ... April 21, 1950 - Page 14 ... +# September 19, 1950 - Page 46 ... September 20, 1950 - Page 3 ... +# November 24, 1950 - Page 21 + # From Arthur David Olson (2010-07-17): # # "Standard Time and Time Zones in Canada" appeared in @@ -1726,13 +1739,9 @@ Rule Toronto 1927 1937 - Sep Sun>=25 2:00 0 S Rule Toronto 1928 1937 - Apr Sun>=25 2:00 1:00 D Rule Toronto 1938 1940 - Apr lastSun 2:00 1:00 D Rule Toronto 1938 1939 - Sep lastSun 2:00 0 S -Rule Toronto 1945 1946 - Sep lastSun 2:00 0 S -Rule Toronto 1946 only - Apr lastSun 2:00 1:00 D -Rule Toronto 1947 1949 - Apr lastSun 0:00 1:00 D -Rule Toronto 1947 1948 - Sep lastSun 0:00 0 S -Rule Toronto 1949 only - Nov lastSun 0:00 0 S -Rule Toronto 1950 1973 - Apr lastSun 2:00 1:00 D -Rule Toronto 1950 only - Nov lastSun 2:00 0 S +Rule Toronto 1945 1948 - Sep lastSun 2:00 0 S +Rule Toronto 1946 1973 - Apr lastSun 2:00 1:00 D +Rule Toronto 1949 1950 - Nov lastSun 2:00 0 S Rule Toronto 1951 1956 - Sep lastSun 2:00 0 S # Shanks & Pottenger say Toronto ended DST a week early in 1971, # namely on 1971-10-24, but Mark Brader wrote (2003-05-31) that this @@ -3455,7 +3464,7 @@ Zone America/Jamaica -5:07:10 - LMT 1890 # Kingston # Martinique # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/Martinique -4:04:20 - LMT 1890 # Fort-de-France - -4:04:20 - FFMT 1911 May # Fort-de-France MT + -4:04:20 - FFMT 1911 May 1 # Fort-de-France MT -4:00 - AST 1980 Apr 6 -4:00 1:00 ADT 1980 Sep 28 -4:00 - AST @@ -3562,7 +3571,7 @@ Zone America/Puerto_Rico -4:24:25 - LMT 1899 Mar 28 12:00 # San Juan # St Pierre and Miquelon # There are too many St Pierres elsewhere, so we'll use 'Miquelon'. # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Miquelon -3:44:40 - LMT 1911 May 15 # St Pierre +Zone America/Miquelon -3:44:40 - LMT 1911 Jun 15 # St Pierre -4:00 - AST 1980 May -3:00 - -03 1987 -3:00 Canada -03/-02 diff --git a/make/data/tzdata/southamerica b/make/data/tzdata/southamerica index da2c6239262..d77acc08857 100644 --- a/make/data/tzdata/southamerica +++ b/make/data/tzdata/southamerica @@ -1593,8 +1593,11 @@ Zone Atlantic/Stanley -3:51:24 - LMT 1890 -3:00 - -03 # French Guiana +# For the 1911/1912 establishment of standard time in French possessions, see: +# Société Française de Physique, Recueil de constantes physiques (1913), +# page 752, 18b. # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Cayenne -3:29:20 - LMT 1911 Jul +Zone America/Cayenne -3:29:20 - LMT 1911 Jul 1 -4:00 - -04 1967 Oct -3:00 - -03 diff --git a/make/devkit/createJMHBundle.sh b/make/devkit/createJMHBundle.sh index c3c97947dab..b2b10769d15 100644 --- a/make/devkit/createJMHBundle.sh +++ b/make/devkit/createJMHBundle.sh @@ -1,6 +1,6 @@ #!/bin/bash -e # -# Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2024, 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 @@ -29,6 +29,7 @@ JMH_VERSION=1.37 COMMONS_MATH3_VERSION=3.6.1 JOPT_SIMPLE_VERSION=5.0.4 +MAVEN_MIRROR=${MAVEN_MIRROR:-https://repo.maven.apache.org/maven2} BUNDLE_NAME=jmh-$JMH_VERSION.tar.gz @@ -41,7 +42,7 @@ cd $JAR_DIR rm -f * fetchJar() { - url="https://repo.maven.apache.org/maven2/$1/$2/$3/$2-$3.jar" + url="${MAVEN_MIRROR}/$1/$2/$3/$2-$3.jar" if command -v curl > /dev/null; then curl -O --fail $url elif command -v wget > /dev/null; then diff --git a/make/hotspot/gensrc/GensrcAdlc.gmk b/make/hotspot/gensrc/GensrcAdlc.gmk index a3969fc6988..63252a56045 100644 --- a/make/hotspot/gensrc/GensrcAdlc.gmk +++ b/make/hotspot/gensrc/GensrcAdlc.gmk @@ -48,7 +48,7 @@ ifeq ($(call check-jvm-feature, compiler2), true) endif # Set the C++ standard - ADLC_CFLAGS += $(ADLC_LANGSTD_CXXFLAG) + ADLC_CFLAGS += $(ADLC_LANGSTD_CXXFLAGS) # NOTE: The old build didn't set -DASSERT for windows but it doesn't seem to # hurt. diff --git a/make/jdk/src/classes/build/tools/generatecurrencydata/GenerateCurrencyData.java b/make/jdk/src/classes/build/tools/generatecurrencydata/GenerateCurrencyData.java index 561edbef034..9655e08016c 100644 --- a/make/jdk/src/classes/build/tools/generatecurrencydata/GenerateCurrencyData.java +++ b/make/jdk/src/classes/build/tools/generatecurrencydata/GenerateCurrencyData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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 @@ -32,6 +32,7 @@ import java.io.FileOutputStream; import java.io.InputStream; import java.text.SimpleDateFormat; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Locale; @@ -339,9 +340,15 @@ private static void buildOtherTables() { validCurrencyCodes.substring(i * 7 + 3, i * 7 + 6)); checkCurrencyCode(currencyCode); int tableEntry = mainTable[(currencyCode.charAt(0) - 'A') * A_TO_Z + (currencyCode.charAt(1) - 'A')]; - if (tableEntry == INVALID_COUNTRY_ENTRY || - (tableEntry & SPECIAL_CASE_COUNTRY_MASK) != 0 || - (tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) != (currencyCode.charAt(2) - 'A')) { + + // Do not allow a future currency to be classified as an otherCurrency, + // otherwise it will leak out into Currency:getAvailableCurrencies + boolean futureCurrency = Arrays.asList(specialCaseNewCurrencies).contains(currencyCode); + boolean simpleCurrency = (tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) == (currencyCode.charAt(2) - 'A'); + + // If neither a simple currency, or one defined in the future + // then the current currency is applicable to be added to the otherTable + if (!futureCurrency && !simpleCurrency) { if (otherCurrenciesCount == maxOtherCurrencies) { throw new RuntimeException("too many other currencies"); } diff --git a/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java b/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java index e25833670ed..bd5d069c559 100644 --- a/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java +++ b/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, 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 @@ -40,7 +40,7 @@ import java.util.Map; import java.util.TimeZone; import java.util.TreeMap; -import java.util.stream.Collectors; +import java.util.regex.Pattern; /** * This tool reads the IANA Language Subtag Registry data file downloaded from @@ -138,10 +138,29 @@ private static void processDeprecatedData(String type, } } else { // language, extlang, legacy, and redundant if (!initialLanguageMap.containsKey(preferred)) { - sb = new StringBuilder(preferred); - sb.append(','); - sb.append(tag); - initialLanguageMap.put(preferred, sb); + // IANA update 4/13 introduced case where a preferred value + // can have a preferred value itself. + // eg: ar-ajp has pref ajp which has pref apc + boolean foundInOther = false; + Pattern pattern = Pattern.compile(","+preferred+"(,|$)"); + // Check if current pref exists inside a value for another pref + List doublePrefs = initialLanguageMap + .values() + .stream() + .filter(e -> pattern.matcher(e.toString()).find()) + .toList(); + for (StringBuilder otherPrefVal : doublePrefs) { + otherPrefVal.append(","); + otherPrefVal.append(tag); + foundInOther = true; + } + if (!foundInOther) { + // does not exist in any other pref's values, so add as new entry + sb = new StringBuilder(preferred); + sb.append(','); + sb.append(tag); + initialLanguageMap.put(preferred, sb); + } } else { sb = initialLanguageMap.get(preferred); sb.append(','); @@ -158,7 +177,7 @@ private static void generateEquivalentMap() { // "yue" is defined both as extlang and redundant. Remove the dup. subtags = Arrays.stream(initialLanguageMap.get(preferred).toString().split(",")) .distinct() - .collect(Collectors.toList()) + .toList() .toArray(new String[0]); if (subtags.length == 2) { @@ -265,11 +284,11 @@ private static void generateSourceCode(String fileName) { Paths.get(fileName))) { writer.write(getOpenJDKCopyright()); writer.write(headerText - + (int)(sortedLanguageMap1.size() / 0.75f + 1) + ");\n" + + sortedLanguageMap1.size() + ");\n" + " multiEquivsMap = new HashMap<>(" - + (int)(sortedLanguageMap2.size() / 0.75f + 1) + ");\n" + + sortedLanguageMap2.size() + ");\n" + " regionVariantEquivMap = new HashMap<>(" - + (int)(sortedRegionVariantMap.size() / 0.75f + 1) + ");\n\n" + + sortedRegionVariantMap.size() + ");\n\n" + " // This is an auto-generated file and should not be manually edited.\n" + " // LSR Revision: " + LSRrevisionDate); writer.newLine(); diff --git a/make/langtools/diags-examples.xml b/make/langtools/diags-examples.xml index ca2a082a445..9802d066693 100644 --- a/make/langtools/diags-examples.xml +++ b/make/langtools/diags-examples.xml @@ -35,20 +35,20 @@ Usage: By default, the reports will be generated in langtools/build/diags-examples/report/. --> - + - + - + @@ -68,12 +68,18 @@ By default, the reports will be generated in langtools/build/diags-examples/repo + + + + + + diff --git a/make/modules/java.desktop/lib/Awt2dLibraries.gmk b/make/modules/java.desktop/lib/Awt2dLibraries.gmk index f3df643dbb8..3bbff03638b 100644 --- a/make/modules/java.desktop/lib/Awt2dLibraries.gmk +++ b/make/modules/java.desktop/lib/Awt2dLibraries.gmk @@ -416,7 +416,6 @@ else LIBFREETYPE_LIBS := -lfreetype endif - # gcc_ftobjs.c := maybe-uninitialized required for GCC 7 builds. $(eval $(call SetupJdkLibrary, BUILD_LIBFREETYPE, \ NAME := freetype, \ OPTIMIZATION := HIGHEST, \ @@ -425,7 +424,6 @@ else EXTRA_HEADER_DIRS := $(BUILD_LIBFREETYPE_HEADER_DIRS), \ DISABLED_WARNINGS_microsoft := 4018 4267 4244 4312 4819, \ DISABLED_WARNINGS_gcc := implicit-fallthrough cast-function-type bad-function-cast dangling-pointer stringop-overflow, \ - DISABLED_WARNINGS_gcc_ftobjs.c := maybe-uninitialized, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ )) diff --git a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp index d2cbdbdba26..209f50efe8f 100644 --- a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -167,8 +167,10 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, if (index->is_register()) { // apply the shift and accumulate the displacement if (shift > 0) { - LIR_Opr tmp = new_pointer_register(); - __ shift_left(index, shift, tmp); + // Use long register to avoid overflow when shifting large index values left. + LIR_Opr tmp = new_register(T_LONG); + __ convert(Bytecodes::_i2l, index, tmp); + __ shift_left(tmp, shift, tmp); index = tmp; } if (large_disp != 0) { diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index 9f33e7526fe..039e9c17b46 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -143,11 +143,19 @@ void VM_Version::initialize() { } } - // Ampere CPUs: Ampere-1 and Ampere-1A - if (_cpu == CPU_AMPERE && ((_model == CPU_MODEL_AMPERE_1) || (_model == CPU_MODEL_AMPERE_1A))) { + // Ampere CPUs + if (_cpu == CPU_AMPERE && ((_model == CPU_MODEL_AMPERE_1) || + (_model == CPU_MODEL_AMPERE_1A) || + (_model == CPU_MODEL_AMPERE_1B))) { if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) { FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true); } + if (FLAG_IS_DEFAULT(OnSpinWaitInst)) { + FLAG_SET_DEFAULT(OnSpinWaitInst, "isb"); + } + if (FLAG_IS_DEFAULT(OnSpinWaitInstCount)) { + FLAG_SET_DEFAULT(OnSpinWaitInstCount, 2); + } } // ThunderX diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp index 8f03b7e4437..3f186f56e75 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp @@ -107,8 +107,9 @@ class VM_Version : public Abstract_VM_Version { CPU_MODEL_ALTRA = 0xd0c, /* CPU implementer is CPU_ARM, Neoverse N1 */ CPU_MODEL_ALTRAMAX = 0xd0c, /* CPU implementer is CPU_ARM, Neoverse N1 */ CPU_MODEL_AMPERE_1 = 0xac3, /* CPU implementer is CPU_AMPERE */ - CPU_MODEL_AMPERE_1A = 0xac4 /* CPU implementer is CPU_AMPERE */ - }; + CPU_MODEL_AMPERE_1A = 0xac4, /* CPU implementer is CPU_AMPERE */ + CPU_MODEL_AMPERE_1B = 0xac5 /* AMPERE_1B core Implements ARMv8.7 with CSSC, MTE, SM3/SM4 extensions */ +}; enum Feature_Flag { #define CPU_FEATURE_FLAGS(decl) \ diff --git a/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp b/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp index 3d18e728363..1aee2cd7192 100644 --- a/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp @@ -475,6 +475,9 @@ void ArrayCopyStub::emit_code(LIR_Assembler* ce) { __ extsw(R7_ARG5, length()->as_register()); ce->emit_static_call_stub(); + if (ce->compilation()->bailed_out()) { + return; // CodeCache is full + } bool success = ce->emit_trampoline_stub_for_call(SharedRuntime::get_resolve_static_call_stub()); if (!success) { return; } diff --git a/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp b/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp index 2c685920367..0a5ab12d3a4 100644 --- a/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -164,8 +164,10 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, if (index->is_register()) { // Apply the shift and accumulate the displacement. if (shift > 0) { - LIR_Opr tmp = new_pointer_register(); - __ shift_left(index, shift, tmp); + // Use long register to avoid overflow when shifting large index values left. + LIR_Opr tmp = new_register(T_LONG); + __ convert(Bytecodes::_i2l, index, tmp); + __ shift_left(tmp, shift, tmp); index = tmp; } if (large_disp != 0) { diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index 06711461666..d26e3c883e7 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -2064,7 +2064,10 @@ int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { C2_MacroAssembler _masm(&cbuf); address base = __ start_a_stub(size_exception_handler()); - if (base == NULL) return 0; // CodeBuffer::expand failed + if (base == nullptr) { + ciEnv::current()->record_failure("CodeCache is full"); + return 0; // CodeBuffer::expand failed + } int offset = __ offset(); __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), @@ -2081,7 +2084,10 @@ int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { C2_MacroAssembler _masm(&cbuf); address base = __ start_a_stub(size_deopt_handler()); - if (base == NULL) return 0; // CodeBuffer::expand failed + if (base == nullptr) { + ciEnv::current()->record_failure("CodeCache is full"); + return 0; // CodeBuffer::expand failed + } int offset = __ offset(); __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), @@ -2778,15 +2784,16 @@ encode %{ intptr_t val = $src$$constant; relocInfo::relocType constant_reloc = $src->constant_reloc(); // src address const_toc_addr; + RelocationHolder r; // Initializes type to none. if (constant_reloc == relocInfo::oop_type) { // Create an oop constant and a corresponding relocation. - AddressLiteral a = __ allocate_oop_address((jobject)val); + AddressLiteral a = __ constant_oop_address((jobject)val); const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); - __ relocate(a.rspec()); + r = a.rspec(); } else if (constant_reloc == relocInfo::metadata_type) { + // Notify OOP recorder (don't need the relocation) AddressLiteral a = __ constant_metadata_address((Metadata *)val); const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); - __ relocate(a.rspec()); } else { // Create a non-oop constant, no relocation needed. const_toc_addr = __ long_constant((jlong)$src$$constant); @@ -2796,6 +2803,7 @@ encode %{ ciEnv::current()->record_out_of_memory_failure(); return; } + __ relocate(r); // If set above. // Get the constant's TOC offset. toc_offset = __ offset_to_method_toc(const_toc_addr); @@ -2809,15 +2817,16 @@ encode %{ intptr_t val = $src$$constant; relocInfo::relocType constant_reloc = $src->constant_reloc(); // src address const_toc_addr; + RelocationHolder r; // Initializes type to none. if (constant_reloc == relocInfo::oop_type) { // Create an oop constant and a corresponding relocation. - AddressLiteral a = __ allocate_oop_address((jobject)val); + AddressLiteral a = __ constant_oop_address((jobject)val); const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); - __ relocate(a.rspec()); + r = a.rspec(); } else if (constant_reloc == relocInfo::metadata_type) { + // Notify OOP recorder (don't need the relocation) AddressLiteral a = __ constant_metadata_address((Metadata *)val); const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); - __ relocate(a.rspec()); } else { // non-oop pointers, e.g. card mark base, heap top // Create a non-oop constant, no relocation needed. const_toc_addr = __ long_constant((jlong)$src$$constant); @@ -2827,6 +2836,7 @@ encode %{ ciEnv::current()->record_out_of_memory_failure(); return; } + __ relocate(r); // If set above. // Get the constant's TOC offset. const int toc_offset = __ offset_to_method_toc(const_toc_addr); // Store the toc offset of the constant. diff --git a/src/hotspot/cpu/riscv/frame_riscv.hpp b/src/hotspot/cpu/riscv/frame_riscv.hpp index d71ee908aa5..307768ce876 100644 --- a/src/hotspot/cpu/riscv/frame_riscv.hpp +++ b/src/hotspot/cpu/riscv/frame_riscv.hpp @@ -133,7 +133,7 @@ // Entry frames // n.b. these values are determined by the layout defined in // stubGenerator for the Java call stub - entry_frame_after_call_words = 34, + entry_frame_after_call_words = 35, entry_frame_call_wrapper_offset = -10, // we don't need a save area diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index c2640966987..874a7a124fd 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -650,7 +650,7 @@ void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Reg void MacroAssembler::la(Register Rd, const address dest) { int64_t offset = dest - pc(); - if (is_simm32(offset)) { + if (is_valid_32bit_offset(offset)) { auipc(Rd, (int32_t)offset + 0x800); //0x800, Note:the 11th sign bit addi(Rd, Rd, ((int64_t)offset << 52) >> 52); } else { diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 6d6a6496565..be1c69c0dc2 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -617,6 +617,14 @@ class MacroAssembler: public Assembler { int pop_v(unsigned int bitset, Register stack); #endif // COMPILER2 + // The signed 20-bit upper imm can materialize at most negative 0xF...F80000000, two G. + // The following signed 12-bit imm can at max subtract 0x800, two K, from that previously loaded two G. + bool is_valid_32bit_offset(int64_t x) { + constexpr int64_t twoG = (2 * G); + constexpr int64_t twoK = (2 * K); + return x < (twoG - twoK) && x >= (-twoG - twoK); + } + public: void push_reg(Register Rs); void pop_reg(Register Rd); @@ -767,7 +775,7 @@ class MacroAssembler: public Assembler { void NAME(Register Rd, address dest) { \ assert_cond(dest != NULL); \ int64_t distance = dest - pc(); \ - if (is_simm32(distance)) { \ + if (is_valid_32bit_offset(distance)) { \ auipc(Rd, (int32_t)distance + 0x800); \ Assembler::NAME(Rd, Rd, ((int32_t)distance << 20) >> 20); \ } else { \ @@ -823,7 +831,7 @@ class MacroAssembler: public Assembler { void NAME(FloatRegister Rd, address dest, Register temp = t0) { \ assert_cond(dest != NULL); \ int64_t distance = dest - pc(); \ - if (is_simm32(distance)) { \ + if (is_valid_32bit_offset(distance)) { \ auipc(temp, (int32_t)distance + 0x800); \ Assembler::NAME(Rd, temp, ((int32_t)distance << 20) >> 20); \ } else { \ @@ -883,7 +891,7 @@ class MacroAssembler: public Assembler { assert_cond(dest != NULL); \ assert_different_registers(Rs, temp); \ int64_t distance = dest - pc(); \ - if (is_simm32(distance)) { \ + if (is_valid_32bit_offset(distance)) { \ auipc(temp, (int32_t)distance + 0x800); \ Assembler::NAME(Rs, temp, ((int32_t)distance << 20) >> 20); \ } else { \ @@ -927,7 +935,7 @@ class MacroAssembler: public Assembler { void NAME(FloatRegister Rs, address dest, Register temp = t0) { \ assert_cond(dest != NULL); \ int64_t distance = dest - pc(); \ - if (is_simm32(distance)) { \ + if (is_valid_32bit_offset(distance)) { \ auipc(temp, (int32_t)distance + 0x800); \ Assembler::NAME(Rs, temp, ((int32_t)distance << 20) >> 20); \ } else { \ diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index 64705da20dc..7fe0392ea5c 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -127,8 +127,9 @@ class StubGenerator: public StubCodeGenerator { // [ return_from_Java ] <--- sp // [ argument word n ] // ... - // -34 [ argument word 1 ] - // -33 [ saved f27 ] <--- sp_after_call + // -35 [ argument word 1 ] + // -34 [ saved FRM in Floating-point Control and Status Register ] <--- sp_after_call + // -33 [ saved f27 ] // -32 [ saved f26 ] // -31 [ saved f25 ] // -30 [ saved f24 ] @@ -165,8 +166,9 @@ class StubGenerator: public StubCodeGenerator { // Call stub stack layout word offsets from fp enum call_stub_layout { - sp_after_call_off = -33, + sp_after_call_off = -34, + frm_off = sp_after_call_off, f27_off = -33, f26_off = -32, f25_off = -31, @@ -214,6 +216,7 @@ class StubGenerator: public StubCodeGenerator { const Address sp_after_call (fp, sp_after_call_off * wordSize); + const Address frm_save (fp, frm_off * wordSize); const Address call_wrapper (fp, call_wrapper_off * wordSize); const Address result (fp, result_off * wordSize); const Address result_type (fp, result_type_off * wordSize); @@ -296,6 +299,16 @@ class StubGenerator: public StubCodeGenerator { __ fsd(f26, f26_save); __ fsd(f27, f27_save); + __ frrm(t0); + __ sd(t0, frm_save); + // Set frm to the state we need. We do want Round to Nearest. We + // don't want non-IEEE rounding modes. + Label skip_fsrmi; + guarantee(__ RoundingMode::rne == 0, "must be"); + __ beqz(t0, skip_fsrmi); + __ fsrmi(__ RoundingMode::rne); + __ bind(skip_fsrmi); + // install Java thread in global register now we have saved // whatever value it held __ mv(xthread, c_rarg7); @@ -413,6 +426,14 @@ class StubGenerator: public StubCodeGenerator { __ ld(x9, x9_save); + // restore frm + Label skip_fsrm; + __ ld(t0, frm_save); + __ frrm(t1); + __ beq(t0, t1, skip_fsrm); + __ fsrm(t0); + __ bind(skip_fsrm); + __ ld(c_rarg0, call_wrapper); __ ld(c_rarg1, result); __ ld(c_rarg2, result_type); diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index 1e4bdb0ddd4..3ef6ffa2934 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -55,6 +55,10 @@ class VM_Version : public Abstract_VM_Version { _enabled = true; _value = value; } + void disable_feature() { + _enabled = false; + _value = -1; + } const char* const pretty() { return _pretty; } const uint64_t feature_bit() { return _feature_bit; } const bool feature_string() { return _feature_string; } @@ -63,16 +67,21 @@ class VM_Version : public Abstract_VM_Version { virtual void update_flag() = 0; }; - #define UPDATE_DEFAULT(flag) \ - void update_flag() { \ - assert(enabled(), "Must be."); \ - if (FLAG_IS_DEFAULT(flag)) { \ - FLAG_SET_DEFAULT(flag, true); \ - } \ - } \ - - #define NO_UPDATE_DEFAULT \ - void update_flag() {} \ + #define UPDATE_DEFAULT(flag) \ + void update_flag() { \ + assert(enabled(), "Must be."); \ + if (FLAG_IS_DEFAULT(flag)) { \ + FLAG_SET_DEFAULT(flag, true); \ + } else { \ + /* Sync CPU features with flags */ \ + if (!flag) { \ + disable_feature(); \ + } \ + } \ + } \ + + #define NO_UPDATE_DEFAULT \ + void update_flag() {} \ // Frozen standard extensions // I RV64I diff --git a/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp b/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp index c6d5085079f..67d838bdcea 100644 --- a/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2017 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -157,8 +157,10 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, return new LIR_Address(base, index, type); } else { if (shift > 0) { - LIR_Opr tmp = new_pointer_register(); - __ shift_left(index, shift, tmp); + // Use long register to avoid overflow when shifting large index values left. + LIR_Opr tmp = new_register(T_LONG); + __ convert(Bytecodes::_i2l, index, tmp); + __ shift_left(tmp, shift, tmp); index = tmp; } return new LIR_Address(base, index, disp, type); diff --git a/src/hotspot/cpu/s390/vm_version_s390.cpp b/src/hotspot/cpu/s390/vm_version_s390.cpp index d7b68f907c7..cdd8097e98a 100644 --- a/src/hotspot/cpu/s390/vm_version_s390.cpp +++ b/src/hotspot/cpu/s390/vm_version_s390.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2021 SAP SE. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 SAP SE. 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 @@ -82,8 +82,8 @@ static const char* z_features[] = {" ", "system-z, g5-z196, ldisp_fast, extimm, pcrel_load/store, cmpb, cond_load/store, interlocked_update", "system-z, g6-ec12, ldisp_fast, extimm, pcrel_load/store, cmpb, cond_load/store, interlocked_update, txm", "system-z, g7-z13, ldisp_fast, extimm, pcrel_load/store, cmpb, cond_load/store, interlocked_update, txm, vectorinstr", - "system-z, g8-z14, ldisp_fast, extimm, pcrel_load/store, cmpb, cond_load/store, interlocked_update, txm, vectorinstr, instrext2, venh1)", - "system-z, g9-z15, ldisp_fast, extimm, pcrel_load/store, cmpb, cond_load/store, interlocked_update, txm, vectorinstr, instrext2, venh1, instrext3, VEnh2 )" + "system-z, g8-z14, ldisp_fast, extimm, pcrel_load/store, cmpb, cond_load/store, interlocked_update, txm, vectorinstr, instrext2, venh1", + "system-z, g9-z15, ldisp_fast, extimm, pcrel_load/store, cmpb, cond_load/store, interlocked_update, txm, vectorinstr, instrext2, venh1, instrext3, venh2" }; void VM_Version::initialize() { @@ -366,7 +366,7 @@ void VM_Version::set_features_string() { strcpy(buf, "z/Architecture (unknown generation)"); } else if (model_ix > 0) { _model_string = z_name[model_ix]; - jio_snprintf(buf, sizeof(buf), "%s, out-of-support_as_of_", z_features[model_ix], z_EOS[model_ix]); + jio_snprintf(buf, sizeof(buf), "%s, out-of-support_as_of_%s", z_features[model_ix], z_EOS[model_ix]); } else if (model_ix < 0) { tty->print_cr("*** WARNING *** Ambiguous z/Architecture detection!"); tty->print_cr(" oldest detected generation is %s", z_features[-model_ix]); diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index 104bf127c27..32e014059da 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -1146,10 +1146,9 @@ bool os::dll_address_to_library_name(address addr, char* buf, // Loads .dll/.so and in case of error it checks if .dll/.so was built // for the same architecture as Hotspot is running on. -void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { +static void* dll_load_library(const char *filename, char *ebuf, int ebuflen) { log_info(os)("attempting shared library load of %s", filename); - if (ebuf && ebuflen > 0) { ebuf[0] = '\0'; ebuf[ebuflen - 1] = '\0'; @@ -1183,6 +1182,26 @@ void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { } return NULL; } +// Load library named +// If filename matches .so, and loading fails, repeat with .a. +void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { + void* result = nullptr; + char* const file_path = strdup(filename); + char* const pointer_to_dot = strrchr(file_path, '.'); + const char old_extension[] = ".so"; + const char new_extension[] = ".a"; + STATIC_ASSERT(sizeof(old_extension) >= sizeof(new_extension)); + // First try to load the existing file. + result = dll_load_library(filename, ebuf, ebuflen); + // If the load fails,we try to reload by changing the extension to .a for .so files only. + // Shared object in .so format dont have braces, hence they get removed for archives with members. + if (result == nullptr && pointer_to_dot != nullptr && strcmp(pointer_to_dot, old_extension) == 0) { + snprintf(pointer_to_dot, sizeof(old_extension), "%s", new_extension); + result = dll_load_library(file_path, ebuf, ebuflen); + } + FREE_C_HEAP_ARRAY(char, file_path); + return result; +} void os::print_dll_info(outputStream *st) { st->print_cr("Dynamic libraries:"); diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index fb2903adc55..f86f3938c78 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2015, 2022 SAP SE. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024 SAP SE. 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 @@ -355,7 +355,7 @@ pid_t os::Linux::gettid() { julong os::Linux::host_swap() { struct sysinfo si; sysinfo(&si); - return (julong)si.totalswap; + return (julong)(si.totalswap * si.mem_unit); } // Most versions of linux have a bug where the number of processors are @@ -2087,7 +2087,6 @@ const char* distro_files[] = { "/etc/mandrake-release", "/etc/sun-release", "/etc/redhat-release", - "/etc/SuSE-release", "/etc/lsb-release", "/etc/turbolinux-release", "/etc/gentoo-release", @@ -2095,6 +2094,7 @@ const char* distro_files[] = { "/etc/angstrom-version", "/etc/system-release", "/etc/os-release", + "/etc/SuSE-release", // Deprecated in favor of os-release since SuSE 12 NULL }; void os::Linux::print_distro_info(outputStream* st) { @@ -2194,6 +2194,8 @@ void os::Linux::print_proc_sys_info(outputStream* st) { "/proc/sys/kernel/threads-max", st); _print_ascii_file_h("/proc/sys/vm/max_map_count (maximum number of memory map areas a process may have)", "/proc/sys/vm/max_map_count", st); + _print_ascii_file_h("/proc/sys/vm/swappiness (control to define how aggressively the kernel swaps out anonymous memory)", + "/proc/sys/vm/swappiness", st); _print_ascii_file_h("/proc/sys/kernel/pid_max (system-wide limit on number of process identifiers)", "/proc/sys/kernel/pid_max", st); } @@ -2206,6 +2208,8 @@ void os::Linux::print_system_memory_info(outputStream* st) { // https://www.kernel.org/doc/Documentation/vm/transhuge.txt _print_ascii_file_h("/sys/kernel/mm/transparent_hugepage/enabled", "/sys/kernel/mm/transparent_hugepage/enabled", st); + _print_ascii_file_h("/sys/kernel/mm/transparent_hugepage/hpage_pmd_size", + "/sys/kernel/mm/transparent_hugepage/hpage_pmd_size", st); _print_ascii_file_h("/sys/kernel/mm/transparent_hugepage/defrag (defrag/compaction efforts parameter)", "/sys/kernel/mm/transparent_hugepage/defrag", st); } diff --git a/src/hotspot/os_cpu/linux_riscv/atomic_linux_riscv.hpp b/src/hotspot/os_cpu/linux_riscv/atomic_linux_riscv.hpp index ba7a35c9994..4e8aad562af 100644 --- a/src/hotspot/os_cpu/linux_riscv/atomic_linux_riscv.hpp +++ b/src/hotspot/os_cpu/linux_riscv/atomic_linux_riscv.hpp @@ -35,7 +35,7 @@ #if defined(__clang_major__) #define FULL_COMPILER_ATOMIC_SUPPORT -#elif (__GNUC__ > 13) || ((__GNUC__ == 13) && (__GNUC_MINOR__ >= 2)) +#elif (__GNUC__ > 13) || ((__GNUC__ == 13) && (__GNUC_MINOR__ > 2)) #define FULL_COMPILER_ATOMIC_SUPPORT #endif @@ -114,6 +114,44 @@ inline T Atomic::PlatformCmpxchg<1>::operator()(T volatile* dest __attribute__(( } #endif +#ifndef FULL_COMPILER_ATOMIC_SUPPORT +// The implementation of `__atomic_compare_exchange` lacks sign extensions +// in GCC 13.2 and lower when using with 32-bit unsigned integers on RV64, +// so we should implement it manually. +// GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114130. +// See also JDK-8326936. +template<> +template +inline T Atomic::PlatformCmpxchg<4>::operator()(T volatile* dest __attribute__((unused)), + T compare_value, + T exchange_value, + atomic_memory_order order) const { + STATIC_ASSERT(4 == sizeof(T)); + + int32_t old_value; + uint64_t rc_temp; + + if (order != memory_order_relaxed) { + FULL_MEM_BARRIER; + } + + __asm__ __volatile__ ( + "1: lr.w %0, %2 \n\t" + " bne %0, %3, 2f \n\t" + " sc.w %1, %4, %2 \n\t" + " bnez %1, 1b \n\t" + "2: \n\t" + : /*%0*/"=&r" (old_value), /*%1*/"=&r" (rc_temp), /*%2*/"+A" (*dest) + : /*%3*/"r" ((int64_t)(int32_t)compare_value), /*%4*/"r" (exchange_value) + : "memory" ); + + if (order != memory_order_relaxed) { + FULL_MEM_BARRIER; + } + return (T)old_value; +} +#endif + template template inline T Atomic::PlatformXchg::operator()(T volatile* dest, @@ -148,54 +186,21 @@ inline T Atomic::PlatformCmpxchg::operator()(T volatile* dest __attri atomic_memory_order order) const { #ifndef FULL_COMPILER_ATOMIC_SUPPORT - STATIC_ASSERT(byte_size >= 4); + STATIC_ASSERT(byte_size > 4); #endif STATIC_ASSERT(byte_size == sizeof(T)); - T value = compare_value; if (order != memory_order_relaxed) { FULL_MEM_BARRIER; } - __atomic_compare_exchange(dest, &value, &exchange_value, /* weak */ false, + __atomic_compare_exchange(dest, &compare_value, &exchange_value, /* weak */ false, __ATOMIC_RELAXED, __ATOMIC_RELAXED); if (order != memory_order_relaxed) { FULL_MEM_BARRIER; } - return value; -} - -template<> -template -inline T Atomic::PlatformCmpxchg<4>::operator()(T volatile* dest __attribute__((unused)), - T compare_value, - T exchange_value, - atomic_memory_order order) const { - STATIC_ASSERT(4 == sizeof(T)); - - T old_value; - long rc; - - if (order != memory_order_relaxed) { - FULL_MEM_BARRIER; - } - - __asm__ __volatile__ ( - "1: sext.w %1, %3 \n\t" // sign-extend compare_value - " lr.w %0, %2 \n\t" - " bne %0, %1, 2f \n\t" - " sc.w %1, %4, %2 \n\t" - " bnez %1, 1b \n\t" - "2: \n\t" - : /*%0*/"=&r" (old_value), /*%1*/"=&r" (rc), /*%2*/"+A" (*dest) - : /*%3*/"r" (compare_value), /*%4*/"r" (exchange_value) - : "memory" ); - - if (order != memory_order_relaxed) { - FULL_MEM_BARRIER; - } - return old_value; + return compare_value; } template diff --git a/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp b/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp index ddbb57a79a2..6905cfcdba3 100644 --- a/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp +++ b/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp @@ -108,13 +108,22 @@ void VM_Version::setup_cpu_available_features() { char buf[1024] = {}; if (uarch != nullptr && strcmp(uarch, "") != 0) { // Use at max half the buffer. - snprintf(buf, sizeof(buf)/2, "%s,", uarch); + snprintf(buf, sizeof(buf)/2, "%s ", uarch); } os::free((void*) uarch); strcat(buf, "rv64"); int i = 0; while (_feature_list[i] != nullptr) { if (_feature_list[i]->enabled()) { + // Change flag default + _feature_list[i]->update_flag(); + + // Feature will be disabled by update_flag() if flag + // is set to false by the user on the command line. + if (!_feature_list[i]->enabled()) { + continue; + } + log_debug(os, cpu)("Enabled RV64 feature \"%s\" (%ld)", _feature_list[i]->pretty(), _feature_list[i]->value()); @@ -122,13 +131,14 @@ void VM_Version::setup_cpu_available_features() { if (_feature_list[i]->feature_string()) { const char* tmp = _feature_list[i]->pretty(); if (strlen(tmp) == 1) { + strcat(buf, " "); strcat(buf, tmp); } else { // Feature string is expected to be lower case. // Turn Zxxx into zxxx char prebuf[3] = {}; assert(strlen(tmp) > 1, "Must be"); - prebuf[0] = '_'; + prebuf[0] = ' '; prebuf[1] = (char)tolower(tmp[0]); strcat(buf, prebuf); strcat(buf, &tmp[1]); @@ -138,8 +148,6 @@ void VM_Version::setup_cpu_available_features() { if (_feature_list[i]->feature_bit() != 0) { _features |= _feature_list[i]->feature_bit(); } - // Change flag default - _feature_list[i]->update_flag(); } i++; } diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp index a569bd71084..be1e14ad86c 100644 --- a/src/hotspot/share/asm/codeBuffer.hpp +++ b/src/hotspot/share/asm/codeBuffer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, 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 @@ -195,7 +195,7 @@ class CodeSection { } void set_locs_point(address pc) { assert(pc >= locs_point(), "relocation addr may not decrease"); - assert(allocates2(pc), "relocation addr must be in this section"); + assert(allocates2(pc), "relocation addr " INTPTR_FORMAT " must be in this section from " INTPTR_FORMAT " to " INTPTR_FORMAT, p2i(pc), p2i(_start), p2i(_limit)); _locs_point = pc; } diff --git a/src/hotspot/share/asm/register.hpp b/src/hotspot/share/asm/register.hpp index 66f58d52953..f57dc09437e 100644 --- a/src/hotspot/share/asm/register.hpp +++ b/src/hotspot/share/asm/register.hpp @@ -99,263 +99,17 @@ const type name = ((type)name##_##type##EnumValue) // Debugging support -inline void assert_different_registers( - AbstractRegister a, - AbstractRegister b -) { - assert( - a != b, - "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT "", p2i(a), p2i(b) - ); -} - - -inline void assert_different_registers( - AbstractRegister a, - AbstractRegister b, - AbstractRegister c -) { - assert( - a != b && a != c - && b != c, - "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT - ", c=" INTPTR_FORMAT "", - p2i(a), p2i(b), p2i(c) - ); -} - - -inline void assert_different_registers( - AbstractRegister a, - AbstractRegister b, - AbstractRegister c, - AbstractRegister d -) { - assert( - a != b && a != c && a != d - && b != c && b != d - && c != d, - "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT - ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT "", - p2i(a), p2i(b), p2i(c), p2i(d) - ); -} - - -inline void assert_different_registers( - AbstractRegister a, - AbstractRegister b, - AbstractRegister c, - AbstractRegister d, - AbstractRegister e -) { - assert( - a != b && a != c && a != d && a != e - && b != c && b != d && b != e - && c != d && c != e - && d != e, - "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT - ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT "", - p2i(a), p2i(b), p2i(c), p2i(d), p2i(e) - ); -} - - -inline void assert_different_registers( - AbstractRegister a, - AbstractRegister b, - AbstractRegister c, - AbstractRegister d, - AbstractRegister e, - AbstractRegister f -) { - assert( - a != b && a != c && a != d && a != e && a != f - && b != c && b != d && b != e && b != f - && c != d && c != e && c != f - && d != e && d != f - && e != f, - "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT - ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT - ", f=" INTPTR_FORMAT "", - p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f) - ); -} - - -inline void assert_different_registers( - AbstractRegister a, - AbstractRegister b, - AbstractRegister c, - AbstractRegister d, - AbstractRegister e, - AbstractRegister f, - AbstractRegister g -) { - assert( - a != b && a != c && a != d && a != e && a != f && a != g - && b != c && b != d && b != e && b != f && b != g - && c != d && c != e && c != f && c != g - && d != e && d != f && d != g - && e != f && e != g - && f != g, - "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT - ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT - ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT "", - p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g) - ); -} - - -inline void assert_different_registers( - AbstractRegister a, - AbstractRegister b, - AbstractRegister c, - AbstractRegister d, - AbstractRegister e, - AbstractRegister f, - AbstractRegister g, - AbstractRegister h -) { - assert( - a != b && a != c && a != d && a != e && a != f && a != g && a != h - && b != c && b != d && b != e && b != f && b != g && b != h - && c != d && c != e && c != f && c != g && c != h - && d != e && d != f && d != g && d != h - && e != f && e != g && e != h - && f != g && f != h - && g != h, - "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT - ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT - ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT "", - p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h) - ); -} - - -inline void assert_different_registers( - AbstractRegister a, - AbstractRegister b, - AbstractRegister c, - AbstractRegister d, - AbstractRegister e, - AbstractRegister f, - AbstractRegister g, - AbstractRegister h, - AbstractRegister i -) { - assert( - a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i - && b != c && b != d && b != e && b != f && b != g && b != h && b != i - && c != d && c != e && c != f && c != g && c != h && c != i - && d != e && d != f && d != g && d != h && d != i - && e != f && e != g && e != h && e != i - && f != g && f != h && f != i - && g != h && g != i - && h != i, - "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT - ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT - ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT - ", i=" INTPTR_FORMAT "", - p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i) - ); -} - -inline void assert_different_registers( - AbstractRegister a, - AbstractRegister b, - AbstractRegister c, - AbstractRegister d, - AbstractRegister e, - AbstractRegister f, - AbstractRegister g, - AbstractRegister h, - AbstractRegister i, - AbstractRegister j -) { - assert( - a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j - && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j - && c != d && c != e && c != f && c != g && c != h && c != i && c != j - && d != e && d != f && d != g && d != h && d != i && d != j - && e != f && e != g && e != h && e != i && e != j - && f != g && f != h && f != i && f != j - && g != h && g != i && g != j - && h != i && h != j - && i != j, - "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT - ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT - ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT - ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT "", - p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j) - ); -} - -inline void assert_different_registers( - AbstractRegister a, - AbstractRegister b, - AbstractRegister c, - AbstractRegister d, - AbstractRegister e, - AbstractRegister f, - AbstractRegister g, - AbstractRegister h, - AbstractRegister i, - AbstractRegister j, - AbstractRegister k -) { - assert( - a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k - && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k - && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k - && d != e && d != f && d != g && d != h && d != i && d != j && d !=k - && e != f && e != g && e != h && e != i && e != j && e !=k - && f != g && f != h && f != i && f != j && f !=k - && g != h && g != i && g != j && g !=k - && h != i && h != j && h !=k - && i != j && i !=k - && j !=k, - "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT - ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT - ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT - ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT "", - p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k) - ); -} - -inline void assert_different_registers( - AbstractRegister a, - AbstractRegister b, - AbstractRegister c, - AbstractRegister d, - AbstractRegister e, - AbstractRegister f, - AbstractRegister g, - AbstractRegister h, - AbstractRegister i, - AbstractRegister j, - AbstractRegister k, - AbstractRegister l -) { - assert( - a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k && a !=l - && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k && b !=l - && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k && c !=l - && d != e && d != f && d != g && d != h && d != i && d != j && d !=k && d !=l - && e != f && e != g && e != h && e != i && e != j && e !=k && e !=l - && f != g && f != h && f != i && f != j && f !=k && f !=l - && g != h && g != i && g != j && g !=k && g !=l - && h != i && h != j && h !=k && h !=l - && i != j && i !=k && i !=l - && j !=k && j !=l - && k !=l, - "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT - ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT - ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT - ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT - ", l=" INTPTR_FORMAT "", - p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k), p2i(l) - ); +template +inline void assert_different_registers(R first_register, Rx... more_registers) { +#ifdef ASSERT + const R regs[] = { first_register, more_registers... }; + // Verify there are no equal entries. + for (size_t i = 0; i < ARRAY_SIZE(regs) - 1; ++i) { + for (size_t j = i + 1; j < ARRAY_SIZE(regs); ++j) { + assert(regs[i] != regs[j], "Multiple uses of register: %s", regs[i]->name()); + } + } +#endif } #endif // SHARE_ASM_REGISTER_HPP diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp index f14a8379976..597cc75fa11 100644 --- a/src/hotspot/share/ci/ciEnv.cpp +++ b/src/hotspot/share/ci/ciEnv.cpp @@ -1185,6 +1185,27 @@ ciInstance* ciEnv::unloaded_ciinstance() { // Don't change thread state and acquire any locks. // Safe to call from VM error reporter. + +// Look up the location descriptor for the given class and return it as a string. +// Returns the class name as a fallback if no location is found. +const char *ciEnv::replay_name(ciKlass* k) const { + if (k->is_instance_klass()) { + return replay_name(k->as_instance_klass()->get_instanceKlass()); + } + return k->name()->as_quoted_ascii(); +} + +// Look up the location descriptor for the given class and return it as a string. +// Returns the class name as a fallback if no location is found. +const char *ciEnv::replay_name(const InstanceKlass* ik) const { + // JDK-8271911 is not in JDK 17, so we fall back to using the class name below. + const char* name = nullptr; // dyno_name(ik); + if (name != nullptr) { + return name; + } + return ik->name()->as_quoted_ascii(); +} + void ciEnv::dump_compile_data(outputStream* out) { CompileTask* task = this->task(); if (task) { @@ -1223,6 +1244,9 @@ void ciEnv::dump_replay_data_unsafe(outputStream* out) { GrowableArray* objects = _factory->get_ci_metadata(); out->print_cr("# %d ciObject found", objects->length()); + // The very first entry is the InstanceKlass of the root method of the current compilation in order to get the right + // protection domain to load subsequent classes during replay compilation. + out->print_cr("instanceKlass %s", CURRENT_ENV->replay_name(task()->method()->method_holder())); for (int i = 0; i < objects->length(); i++) { objects->at(i)->dump_replay_data(out); } diff --git a/src/hotspot/share/ci/ciEnv.hpp b/src/hotspot/share/ci/ciEnv.hpp index 3afe66ce1a6..f9f172e8d8d 100644 --- a/src/hotspot/share/ci/ciEnv.hpp +++ b/src/hotspot/share/ci/ciEnv.hpp @@ -466,6 +466,9 @@ class ciEnv : StackObj { void dump_replay_data(outputStream* out); void dump_replay_data_unsafe(outputStream* out); void dump_compile_data(outputStream* out); + + const char *replay_name(const InstanceKlass* ik) const; + const char *replay_name(ciKlass* i) const; }; #endif // SHARE_CI_CIENV_HPP diff --git a/src/hotspot/share/ci/ciReplay.cpp b/src/hotspot/share/ci/ciReplay.cpp index 2476ca52840..acdc1ed1bf0 100644 --- a/src/hotspot/share/ci/ciReplay.cpp +++ b/src/hotspot/share/ci/ciReplay.cpp @@ -103,6 +103,7 @@ class CompileReplay : public StackObj { FILE* _stream; Thread* _thread; Handle _protection_domain; + bool _protection_domain_initialized; Handle _loader; GrowableArray _ci_method_records; @@ -130,6 +131,7 @@ class CompileReplay : public StackObj { _thread = THREAD; _loader = Handle(_thread, SystemDictionary::java_system_loader()); _protection_domain = Handle(); + _protection_domain_initialized = false; _stream = fopen(filename, "rt"); if (_stream == NULL) { @@ -685,6 +687,18 @@ class CompileReplay : public StackObj { void process_instanceKlass(TRAPS) { // just load the referenced class Klass* k = parse_klass(CHECK); + if (!_protection_domain_initialized && k != NULL) { + assert(_protection_domain() == NULL, "must be uninitialized"); + // The first entry is the holder class of the method for which a replay compilation is requested. + // Use the same protection domain to load all subsequent classes in order to resolve all classes + // in signatures of inlinees. This ensures that inlining can be done as stated in the replay file. + _protection_domain = Handle(_thread, k->protection_domain()); + } + + // Only initialize the protection domain handle with the protection domain of the very first entry. + // This also ensures that older replay files work. + _protection_domain_initialized = true; + } // ciInstanceKlass tag* diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp index 0287b73e503..05561110ad7 100644 --- a/src/hotspot/share/classfile/classLoader.cpp +++ b/src/hotspot/share/classfile/classLoader.cpp @@ -1141,7 +1141,7 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TR const char* const class_name = name->as_C_string(); - EventMark m("loading class %s", class_name); + EventMarkClassLoading m("Loading class %s", class_name); const char* const file_name = file_name_for_class_name(class_name, name->utf8_length()); diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp index 1b5a22e19ea..73d17a3dd6b 100644 --- a/src/hotspot/share/classfile/classLoaderData.cpp +++ b/src/hotspot/share/classfile/classLoaderData.cpp @@ -961,7 +961,11 @@ void ClassLoaderData::print_on(outputStream* out) const { _holder.print_on(out); out->print_cr(""); } - out->print_cr(" - class loader " INTPTR_FORMAT, p2i(_class_loader.ptr_raw())); + if (!_unloading) { + out->print_cr(" - class loader " INTPTR_FORMAT, p2i(_class_loader.peek())); + } else { + out->print_cr(" - class loader "); + } out->print_cr(" - metaspace " INTPTR_FORMAT, p2i(_metaspace)); out->print_cr(" - unloading %s", _unloading ? "true" : "false"); out->print_cr(" - class mirror holder %s", _has_class_mirror_holder ? "true" : "false"); diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index d5c31932e31..bf817989dc1 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -2076,18 +2076,17 @@ oop java_lang_Throwable::message(oop throwable) { return throwable->obj_field(_detailMessage_offset); } -oop java_lang_Throwable::cause(oop throwable) { - return throwable->obj_field(_cause_offset); +const char* java_lang_Throwable::message_as_utf8(oop throwable) { + oop msg = java_lang_Throwable::message(throwable); + const char* msg_utf8 = nullptr; + if (msg != nullptr) { + msg_utf8 = java_lang_String::as_utf8_string(msg); + } + return msg_utf8; } -// Return Symbol for detailed_message or NULL -Symbol* java_lang_Throwable::detail_message(oop throwable) { - PreserveExceptionMark pm(Thread::current()); - oop detailed_message = java_lang_Throwable::message(throwable); - if (detailed_message != NULL) { - return java_lang_String::as_symbol(detailed_message); - } - return NULL; +oop java_lang_Throwable::cause(oop throwable) { + return throwable->obj_field(_cause_offset); } void java_lang_Throwable::set_message(oop throwable, oop value) { @@ -2739,15 +2738,19 @@ Handle java_lang_Throwable::create_initialization_error(JavaThread* current, Han assert(throwable.not_null(), "shouldn't be"); // Now create the message from the original exception and thread name. - Symbol* message = java_lang_Throwable::detail_message(throwable()); ResourceMark rm(current); stringStream st; + const char *message = nullptr; + oop detailed_message = java_lang_Throwable::message(throwable()); + if (detailed_message != nullptr) { + message = java_lang_String::as_utf8_string(detailed_message); + } st.print("Exception %s%s ", throwable()->klass()->name()->as_klass_external_name(), message == nullptr ? "" : ":"); - if (message == NULL) { + if (message == nullptr) { st.print("[in thread \"%s\"]", current->name()); } else { - st.print("%s [in thread \"%s\"]", message->as_C_string(), current->name()); + st.print("%s [in thread \"%s\"]", message, current->name()); } Symbol* exception_name = vmSymbols::java_lang_ExceptionInInitializerError(); diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index 4a3d37e50dc..f1883878141 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -549,12 +549,14 @@ class java_lang_Throwable: AllStatic { static void set_backtrace(oop throwable, oop value); static int depth(oop throwable); static void set_depth(oop throwable, int value); - static int get_detailMessage_offset() { CHECK_INIT(_detailMessage_offset); } // Message + static int get_detailMessage_offset() { CHECK_INIT(_detailMessage_offset); } static oop message(oop throwable); - static oop cause(oop throwable); + static const char* message_as_utf8(oop throwable); static void set_message(oop throwable, oop value); - static Symbol* detail_message(oop throwable); + + static oop cause(oop throwable); + static void print_stack_element(outputStream *st, Method* method, int bci); static void compute_offsets(); diff --git a/src/hotspot/share/classfile/resolutionErrors.cpp b/src/hotspot/share/classfile/resolutionErrors.cpp index 24a5bcab3a8..4e647871d2a 100644 --- a/src/hotspot/share/classfile/resolutionErrors.cpp +++ b/src/hotspot/share/classfile/resolutionErrors.cpp @@ -36,8 +36,8 @@ // create new error entry void ResolutionErrorTable::add_entry(int index, unsigned int hash, const constantPoolHandle& pool, int cp_index, - Symbol* error, Symbol* message, - Symbol* cause, Symbol* cause_msg) + Symbol* error, const char* message, + Symbol* cause, const char* cause_msg) { assert_locked_or_safepoint(SystemDictionary_lock); assert(!pool.is_null() && error != NULL, "adding NULL obj"); @@ -95,11 +95,8 @@ void ResolutionErrorEntry::set_error(Symbol* e) { } } -void ResolutionErrorEntry::set_message(Symbol* c) { - _message = c; - if (_message != NULL) { - _message->increment_refcount(); - } +void ResolutionErrorEntry::set_message(const char* c) { + _message = c != nullptr ? os::strdup(c) : nullptr; } void ResolutionErrorEntry::set_cause(Symbol* c) { @@ -109,13 +106,11 @@ void ResolutionErrorEntry::set_cause(Symbol* c) { } } -void ResolutionErrorEntry::set_cause_msg(Symbol* c) { - _cause_msg = c; - if (_cause_msg != NULL) { - _cause_msg->increment_refcount(); - } +void ResolutionErrorEntry::set_cause_msg(const char* c) { + _cause_msg = c != nullptr ? os::strdup(c) : nullptr; } +// The incoming nest host error message is already in the C-Heap. void ResolutionErrorEntry::set_nest_host_error(const char* message) { _nest_host_error = message; } @@ -126,13 +121,13 @@ void ResolutionErrorTable::free_entry(ResolutionErrorEntry *entry) { entry->error()->decrement_refcount(); } if (entry->message() != NULL) { - entry->message()->decrement_refcount(); + FREE_C_HEAP_ARRAY(char, entry->message()); } if (entry->cause() != NULL) { entry->cause()->decrement_refcount(); } if (entry->cause_msg() != NULL) { - entry->cause_msg()->decrement_refcount(); + FREE_C_HEAP_ARRAY(char, entry->cause_msg()); } if (entry->nest_host_error() != NULL) { FREE_C_HEAP_ARRAY(char, entry->nest_host_error()); diff --git a/src/hotspot/share/classfile/resolutionErrors.hpp b/src/hotspot/share/classfile/resolutionErrors.hpp index 8a9c9951ba1..31a56385860 100644 --- a/src/hotspot/share/classfile/resolutionErrors.hpp +++ b/src/hotspot/share/classfile/resolutionErrors.hpp @@ -61,11 +61,11 @@ class ResolutionErrorTable : public Hashtable { } void add_entry(int index, unsigned int hash, - const constantPoolHandle& pool, int which, Symbol* error, Symbol* message, - Symbol* cause, Symbol* cause_msg); + const constantPoolHandle& pool, int cp_index, Symbol* error, const char* error_msg, + Symbol* cause, const char* cause_msg); void add_entry(int index, unsigned int hash, - const constantPoolHandle& pool, int which, const char* message); + const constantPoolHandle& pool, int cp_index, const char* message); // find error given the constant pool and constant pool index ResolutionErrorEntry* find_entry(int index, unsigned int hash, @@ -96,9 +96,9 @@ class ResolutionErrorEntry : public HashtableEntry { private: int _cp_index; Symbol* _error; - Symbol* _message; + const char* _message; Symbol* _cause; - Symbol* _cause_msg; + const char* _cause_msg; const char* _nest_host_error; public: @@ -110,16 +110,19 @@ class ResolutionErrorEntry : public HashtableEntry { Symbol* error() const { return _error; } void set_error(Symbol* e); - Symbol* message() const { return _message; } - void set_message(Symbol* c); + const char* message() const { return _message; } + // The incoming message is copied to the C-Heap. + void set_message(const char* c); Symbol* cause() const { return _cause; } void set_cause(Symbol* c); - Symbol* cause_msg() const { return _cause_msg; } - void set_cause_msg(Symbol* c); + const char* cause_msg() const { return _cause_msg; } + // The incoming cause_msg is copied to the C-Heap. + void set_cause_msg(const char* c); const char* nest_host_error() const { return _nest_host_error; } + // The incoming nest host error message is already in the C-Heap. void set_nest_host_error(const char* message); ResolutionErrorEntry* next() const { diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index 3d476eba09b..96fbf375bca 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -1846,8 +1846,8 @@ bool SystemDictionary::add_loader_constraint(Symbol* class_name, // Add entry to resolution error table to record the error when the first // attempt to resolve a reference to a class has failed. void SystemDictionary::add_resolution_error(const constantPoolHandle& pool, int which, - Symbol* error, Symbol* message, - Symbol* cause, Symbol* cause_msg) { + Symbol* error, const char* message, + Symbol* cause, const char* cause_msg) { unsigned int hash = resolution_errors()->compute_hash(pool, which); int index = resolution_errors()->hash_to_index(hash); { @@ -1866,7 +1866,7 @@ void SystemDictionary::delete_resolution_error(ConstantPool* pool) { // Lookup resolution error table. Returns error if found, otherwise NULL. Symbol* SystemDictionary::find_resolution_error(const constantPoolHandle& pool, int which, - Symbol** message, Symbol** cause, Symbol** cause_msg) { + const char** message, Symbol** cause, const char** cause_msg) { unsigned int hash = resolution_errors()->compute_hash(pool, which); int index = resolution_errors()->hash_to_index(hash); { diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp index f4d40685ddc..a075e4de38b 100644 --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp @@ -281,10 +281,10 @@ class SystemDictionary : AllStatic { // Record the error when the first attempt to resolve a reference from a constant // pool entry to a class fails. static void add_resolution_error(const constantPoolHandle& pool, int which, Symbol* error, - Symbol* message, Symbol* cause = NULL, Symbol* cause_msg = NULL); + const char* message, Symbol* cause = NULL, const char* cause_msg = NULL); static void delete_resolution_error(ConstantPool* pool); static Symbol* find_resolution_error(const constantPoolHandle& pool, int which, - Symbol** message, Symbol** cause, Symbol** cause_msg); + const char** message, Symbol** cause, const char** cause_msg); // Record a nest host resolution/validation error diff --git a/src/hotspot/share/gc/epsilon/epsilonHeap.cpp b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp index b4cc8dd8a79..fc722759fbb 100644 --- a/src/hotspot/share/gc/epsilon/epsilonHeap.cpp +++ b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp @@ -1,5 +1,6 @@ /* - * Copyright (c) 2017, 2020, Red Hat, Inc. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -126,17 +127,22 @@ HeapWord* EpsilonHeap::allocate_work(size_t size) { } // Expand and loop back if space is available - size_t space_left = max_capacity() - capacity(); - size_t want_space = MAX2(size, EpsilonMinHeapExpand); - - if (want_space < space_left) { + size_t size_in_bytes = size * HeapWordSize; + size_t uncommitted_space = max_capacity() - capacity(); + size_t unused_space = max_capacity() - used(); + size_t want_space = MAX2(size_in_bytes, EpsilonMinHeapExpand); + assert(unused_space >= uncommitted_space, + "Unused (" SIZE_FORMAT ") >= uncommitted (" SIZE_FORMAT ")", + unused_space, uncommitted_space); + + if (want_space < uncommitted_space) { // Enough space to expand in bulk: bool expand = _virtual_space.expand_by(want_space); assert(expand, "Should be able to expand"); - } else if (size < space_left) { + } else if (size_in_bytes < unused_space) { // No space to expand in bulk, and this allocation is still possible, // take all the remaining space: - bool expand = _virtual_space.expand_by(space_left); + bool expand = _virtual_space.expand_by(uncommitted_space); assert(expand, "Should be able to expand"); } else { // No space left: diff --git a/src/hotspot/share/gc/g1/g1Allocator.cpp b/src/hotspot/share/gc/g1/g1Allocator.cpp index f36501583e4..1aca61234e5 100644 --- a/src/hotspot/share/gc/g1/g1Allocator.cpp +++ b/src/hotspot/share/gc/g1/g1Allocator.cpp @@ -91,7 +91,7 @@ bool G1Allocator::is_retained_old_region(HeapRegion* hr) { return _retained_old_gc_alloc_region == hr; } -void G1Allocator::reuse_retained_old_region(G1EvacuationInfo& evacuation_info, +void G1Allocator::reuse_retained_old_region(G1EvacuationInfo* evacuation_info, OldGCAllocRegion* old, HeapRegion** retained_old) { HeapRegion* retained_region = *retained_old; @@ -120,11 +120,11 @@ void G1Allocator::reuse_retained_old_region(G1EvacuationInfo& evacuation_info, _g1h->old_set_remove(retained_region); old->set(retained_region); _g1h->hr_printer()->reuse(retained_region); - evacuation_info.set_alloc_regions_used_before(retained_region->used()); + evacuation_info->set_alloc_regions_used_before(retained_region->used()); } } -void G1Allocator::init_gc_alloc_regions(G1EvacuationInfo& evacuation_info) { +void G1Allocator::init_gc_alloc_regions(G1EvacuationInfo* evacuation_info) { assert_at_safepoint_on_vm_thread(); _survivor_is_full = false; @@ -140,14 +140,14 @@ void G1Allocator::init_gc_alloc_regions(G1EvacuationInfo& evacuation_info) { &_retained_old_gc_alloc_region); } -void G1Allocator::release_gc_alloc_regions(G1EvacuationInfo& evacuation_info) { +void G1Allocator::release_gc_alloc_regions(G1EvacuationInfo* evacuation_info) { uint survivor_region_count = 0; for (uint node_index = 0; node_index < _num_alloc_regions; node_index++) { survivor_region_count += survivor_gc_alloc_region(node_index)->count(); survivor_gc_alloc_region(node_index)->release(); } - evacuation_info.set_allocation_regions(survivor_region_count + - old_gc_alloc_region()->count()); + evacuation_info->set_allocation_regions(survivor_region_count + + old_gc_alloc_region()->count()); // If we have an old GC alloc region to release, we'll save it in // _retained_old_gc_alloc_region. If we don't diff --git a/src/hotspot/share/gc/g1/g1Allocator.hpp b/src/hotspot/share/gc/g1/g1Allocator.hpp index 5fbe0f52f99..c9bf3015dfc 100644 --- a/src/hotspot/share/gc/g1/g1Allocator.hpp +++ b/src/hotspot/share/gc/g1/g1Allocator.hpp @@ -68,7 +68,7 @@ class G1Allocator : public CHeapObj { void set_survivor_full(); void set_old_full(); - void reuse_retained_old_region(G1EvacuationInfo& evacuation_info, + void reuse_retained_old_region(G1EvacuationInfo* evacuation_info, OldGCAllocRegion* old, HeapRegion** retained); @@ -105,8 +105,8 @@ class G1Allocator : public CHeapObj { void init_mutator_alloc_regions(); void release_mutator_alloc_regions(); - void init_gc_alloc_regions(G1EvacuationInfo& evacuation_info); - void release_gc_alloc_regions(G1EvacuationInfo& evacuation_info); + void init_gc_alloc_regions(G1EvacuationInfo* evacuation_info); + void release_gc_alloc_regions(G1EvacuationInfo* evacuation_info); void abandon_gc_alloc_regions(); bool is_retained_old_region(HeapRegion* hr); diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 2f9af5ed4f2..eb3586231bd 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -979,7 +979,11 @@ class PostCompactionPrinterClosure: public HeapRegionClosure { : _hr_printer(hr_printer) { } }; -void G1CollectedHeap::print_hrm_post_compaction() { +void G1CollectedHeap::print_heap_after_full_collection() { + // Post collection region logging. + // We should do this after we potentially resize the heap so + // that all the COMMIT / UNCOMMIT events are generated before + // the compaction events. if (_hr_printer.is_active()) { PostCompactionPrinterClosure cl(hr_printer()); heap_region_iterate(&cl); @@ -1091,17 +1095,6 @@ void G1CollectedHeap::verify_after_full_collection() { _ref_processor_cm->verify_no_references_recorded(); } -void G1CollectedHeap::print_heap_after_full_collection(G1HeapTransition* heap_transition) { - // Post collection logging. - // We should do this after we potentially resize the heap so - // that all the COMMIT / UNCOMMIT events are generated before - // the compaction events. - print_hrm_post_compaction(); - heap_transition->print(); - print_heap_after_gc(); - print_heap_regions(); -} - bool G1CollectedHeap::do_full_collection(bool explicit_gc, bool clear_all_soft_refs, bool do_maximum_compaction) { @@ -1115,8 +1108,9 @@ bool G1CollectedHeap::do_full_collection(bool explicit_gc, const bool do_clear_all_soft_refs = clear_all_soft_refs || soft_ref_policy()->should_clear_all_soft_refs(); - G1FullCollector collector(this, explicit_gc, do_clear_all_soft_refs, do_maximum_compaction); + G1FullGCMark gc_mark; GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause(), true); + G1FullCollector collector(this, explicit_gc, do_clear_all_soft_refs, do_maximum_compaction, gc_mark.tracer()); collector.prepare_collection(); collector.collect(); @@ -2566,9 +2560,6 @@ void G1CollectedHeap::trace_heap(GCWhen::Type when, const GCTracer* gc_tracer) { void G1CollectedHeap::gc_prologue(bool full) { assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer"); - // This summary needs to be printed before incrementing total collections. - rem_set()->print_periodic_summary_info("Before GC RS summary", total_collections()); - // Update common counters. increment_total_collections(full /* full gc */); if (full || collector_state()->in_concurrent_start_gc()) { @@ -2601,9 +2592,6 @@ void G1CollectedHeap::gc_epilogue(bool full) { increment_old_marking_cycles_completed(false /* concurrent */, true /* liveness_completed */); } - // We are at the end of the GC. Total collections has already been increased. - rem_set()->print_periodic_summary_info("After GC RS summary", total_collections() - 1); - #if COMPILER2_OR_JVMCI assert(DerivedPointerTable::is_empty(), "derived pointer present"); #endif @@ -2617,9 +2605,6 @@ void G1CollectedHeap::gc_epilogue(bool full) { // policy with the new heap occupancy Universe::heap()->update_capacity_and_used_at_gc(); - // Print NUMA statistics. - _numa->print_statistics(); - _collection_pause_end = Ticks::now(); } @@ -2805,10 +2790,10 @@ void G1CollectedHeap::start_new_collection_set() { phase_times()->record_start_new_cset_time_ms((os::elapsedTime() - start) * 1000.0); } -void G1CollectedHeap::calculate_collection_set(G1EvacuationInfo& evacuation_info, double target_pause_time_ms) { +void G1CollectedHeap::calculate_collection_set(G1EvacuationInfo* evacuation_info, double target_pause_time_ms) { _collection_set.finalize_initial_collection_set(target_pause_time_ms, &_survivor); - evacuation_info.set_collectionset_regions(collection_set()->region_length() + + evacuation_info->set_collectionset_regions(collection_set()->region_length() + collection_set()->optional_region_length()); _cm->verify_no_collection_set_oops(); @@ -2903,6 +2888,64 @@ void G1CollectedHeap::gc_tracer_report_gc_end(bool concurrent_operation_is_full_ _gc_timer_stw->time_partitions()); } +G1HeapPrinterMark::G1HeapPrinterMark(G1CollectedHeap* g1h) : _g1h(g1h), _heap_transition(g1h) { + // This summary needs to be printed before incrementing total collections. + _g1h->rem_set()->print_periodic_summary_info("Before GC RS summary", _g1h->total_collections()); + _g1h->print_heap_before_gc(); + _g1h->print_heap_regions(); +} + +G1HeapPrinterMark::~G1HeapPrinterMark() { + _g1h->policy()->print_age_table(); + // not (yet) in 17u: _g1h->rem_set()->print_coarsen_stats(); + // We are at the end of the GC. Total collections has already been increased. + _g1h->rem_set()->print_periodic_summary_info("After GC RS summary", _g1h->total_collections() - 1); + + _heap_transition.print(); + _g1h->print_heap_regions(); + _g1h->print_heap_after_gc(); + // Print NUMA statistics. + _g1h->numa()->print_statistics(); +} + +G1JFRTracerMark::G1JFRTracerMark(STWGCTimer* timer, GCTracer* tracer) : + _timer(timer), _tracer(tracer) { + + _timer->register_gc_start(); + _tracer->report_gc_start(G1CollectedHeap::heap()->gc_cause(), _timer->gc_start()); + G1CollectedHeap::heap()->trace_heap_before_gc(_tracer); +} + +G1JFRTracerMark::~G1JFRTracerMark() { + G1CollectedHeap::heap()->trace_heap_after_gc(_tracer); + _timer->register_gc_end(); + _tracer->report_gc_end(_timer->gc_end(), _timer->time_partitions()); +} + +class G1YoungGCJFRTracerMark : public G1JFRTracerMark { + G1EvacuationInfo _evacuation_info; + + G1NewTracer* tracer() const { return (G1NewTracer*)_tracer; } + +public: + + G1EvacuationInfo* evacuation_info() { return &_evacuation_info; } + + G1YoungGCJFRTracerMark(STWGCTimer* gc_timer_stw, G1NewTracer* gc_tracer_stw, GCCause::Cause cause) : + G1JFRTracerMark(gc_timer_stw, gc_tracer_stw), _evacuation_info() { } + + void report_pause_type(G1GCPauseType type) { + tracer()->report_young_gc_pause(type); + } + + ~G1YoungGCJFRTracerMark() { + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + + tracer()->report_evacuation_info(&_evacuation_info); + tracer()->report_tenuring_threshold(g1h->policy()->tenuring_threshold()); + } +}; + void G1CollectedHeap::do_collection_pause_at_safepoint_helper(double target_pause_time_ms) { GCIdMark gc_id_mark; @@ -2911,14 +2954,8 @@ void G1CollectedHeap::do_collection_pause_at_safepoint_helper(double target_paus policy()->note_gc_start(); - gc_tracer_report_gc_start(); - wait_for_root_region_scanning(); - print_heap_before_gc(); - print_heap_regions(); - trace_heap_before_gc(_gc_tracer_stw); - _verifier->verify_region_sets_optional(); _verifier->verify_dirty_young_regions(); @@ -2944,9 +2981,7 @@ void G1CollectedHeap::do_collection_pause_at_safepoint_helper(double target_paus // Inner scope for scope based logging, timers, and stats collection { - G1EvacuationInfo evacuation_info; - - GCTraceCPUTime tcpu; + GCTraceCPUTime tcpu(_gc_tracer_stw); char young_gc_name[MaxYoungGCNameLength]; set_young_gc_name(young_gc_name); @@ -2959,11 +2994,20 @@ void G1CollectedHeap::do_collection_pause_at_safepoint_helper(double target_paus active_workers = workers()->update_active_workers(active_workers); log_info(gc,task)("Using %u workers of %u for evacuation", active_workers, workers()->total_workers()); + // JFR + G1YoungGCJFRTracerMark jtm(_gc_timer_stw, _gc_tracer_stw, gc_cause()); G1MonitoringScope ms(g1mm(), false /* full_gc */, collector_state()->in_mixed_phase() /* all_memory_pools_affected */); + // Create the heap printer before internal pause timing to have + // heap information printed as last part of detailed GC log. + G1HeapPrinterMark hpm(this); + // Young GC internal pause timing + // Not (yet) in 17: G1YoungGCNotifyPauseMark npm; - G1HeapTransition heap_transition(this); + // Verification may use the gang workers, so they must be set up before. + // Individual parallel phases may override this. + // Not (yet) in 17: set_young_collection_default_active_worker_threads(); { IsGCActiveMark x; @@ -2995,7 +3039,7 @@ void G1CollectedHeap::do_collection_pause_at_safepoint_helper(double target_paus // of the collection set!). _allocator->release_mutator_alloc_regions(); - calculate_collection_set(evacuation_info, target_pause_time_ms); + calculate_collection_set(jtm.evacuation_info(), target_pause_time_ms); G1RedirtyCardsQueueSet rdcqs(G1BarrierSet::dirty_card_queue_set().allocator()); G1ParScanThreadStateSet per_thread_states(this, @@ -3003,7 +3047,7 @@ void G1CollectedHeap::do_collection_pause_at_safepoint_helper(double target_paus workers()->active_workers(), collection_set()->young_region_length(), collection_set()->optional_region_length()); - pre_evacuate_collection_set(evacuation_info, &per_thread_states); + pre_evacuate_collection_set(jtm.evacuation_info(), &per_thread_states); bool may_do_optional_evacuation = _collection_set.optional_region_length() != 0; // Actually do the work... @@ -3012,7 +3056,7 @@ void G1CollectedHeap::do_collection_pause_at_safepoint_helper(double target_paus if (may_do_optional_evacuation) { evacuate_optional_collection_set(&per_thread_states); } - post_evacuate_collection_set(evacuation_info, &rdcqs, &per_thread_states); + post_evacuate_collection_set(jtm.evacuation_info(), &rdcqs, &per_thread_states); start_new_collection_set(); @@ -3031,7 +3075,7 @@ void G1CollectedHeap::do_collection_pause_at_safepoint_helper(double target_paus // Need to report the collection pause now since record_collection_pause_end() // modifies it to the next state. - _gc_tracer_stw->report_young_gc_pause(collector_state()->young_gc_pause_type(concurrent_operation_is_full_mark)); + jtm.report_pause_type(collector_state()->young_gc_pause_type(concurrent_operation_is_full_mark)); double sample_end_time_sec = os::elapsedTime(); double pause_time_ms = (sample_end_time_sec - sample_start_time_sec) * MILLIUNITS; @@ -3049,7 +3093,6 @@ void G1CollectedHeap::do_collection_pause_at_safepoint_helper(double target_paus } policy()->print_phases(); - heap_transition.print(); _hrm.verify_optional(); _verifier->verify_region_sets_optional(); @@ -3057,17 +3100,11 @@ void G1CollectedHeap::do_collection_pause_at_safepoint_helper(double target_paus TASKQUEUE_STATS_ONLY(print_taskqueue_stats()); TASKQUEUE_STATS_ONLY(reset_taskqueue_stats()); - print_heap_after_gc(); - print_heap_regions(); - trace_heap_after_gc(_gc_tracer_stw); - // We must call G1MonitoringSupport::update_sizes() in the same scoping level // as an active TraceMemoryManagerStats object (i.e. before the destructor for the // TraceMemoryManagerStats is called) so that the G1 memory pools are updated // before any GC notifications are raised. g1mm()->update_sizes(); - - gc_tracer_report_gc_end(concurrent_operation_is_full_mark, evacuation_info); } // It should now be safe to tell the concurrent mark thread to start // without its logging output interfering with the logging output @@ -3490,7 +3527,7 @@ class G1PrepareEvacuationTask : public AbstractGangTask { } }; -void G1CollectedHeap::pre_evacuate_collection_set(G1EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states) { +void G1CollectedHeap::pre_evacuate_collection_set(G1EvacuationInfo* evacuation_info, G1ParScanThreadStateSet* per_thread_states) { _bytes_used_during_gc = 0; _expand_heap_after_alloc_failure = true; @@ -3756,7 +3793,7 @@ void G1CollectedHeap::evacuate_optional_collection_set(G1ParScanThreadStateSet* _collection_set.abandon_optional_collection_set(per_thread_states); } -void G1CollectedHeap::post_evacuate_collection_set(G1EvacuationInfo& evacuation_info, +void G1CollectedHeap::post_evacuate_collection_set(G1EvacuationInfo* evacuation_info, G1RedirtyCardsQueueSet* rdcqs, G1ParScanThreadStateSet* per_thread_states) { G1GCPhaseTimes* p = phase_times(); @@ -3777,7 +3814,7 @@ void G1CollectedHeap::post_evacuate_collection_set(G1EvacuationInfo& evacuation_ post_evacuate_cleanup_1(per_thread_states, rdcqs); - post_evacuate_cleanup_2(&_preserved_marks_set, rdcqs, &evacuation_info, per_thread_states->surviving_young_words()); + post_evacuate_cleanup_2(&_preserved_marks_set, rdcqs, evacuation_info, per_thread_states->surviving_young_words()); assert_used_and_recalculate_used_equal(this); @@ -3785,10 +3822,8 @@ void G1CollectedHeap::post_evacuate_collection_set(G1EvacuationInfo& evacuation_ record_obj_copy_mem_stats(); - evacuation_info.set_collectionset_used_before(collection_set()->bytes_used_before()); - evacuation_info.set_bytes_used(_bytes_used_during_gc); - - policy()->print_age_table(); + evacuation_info->set_collectionset_used_before(collection_set()->bytes_used_before()); + evacuation_info->set_bytes_used(_bytes_used_during_gc); } void G1CollectedHeap::record_obj_copy_mem_stats() { diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index d2e90a86424..50aaac4cd53 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -149,6 +149,7 @@ class G1CollectedHeap : public CollectedHeap { friend class G1PLABAllocator; // Other related classes. + friend class G1HeapPrinterMark; friend class HeapRegionClaimer; // Testing classes. @@ -304,10 +305,6 @@ class G1CollectedHeap : public CollectedHeap { // this method will be found dead by the marking cycle). void allocate_dummy_regions() PRODUCT_RETURN; - // If the HR printer is active, dump the state of the regions in the - // heap after a compaction. - void print_hrm_post_compaction(); - // Create a memory mapper for auxiliary data structures of the given size and // translation factor. static G1RegionToSpaceMapper* create_aux_memory_mapper(const char* description, @@ -529,7 +526,7 @@ class G1CollectedHeap : public CollectedHeap { void prepare_heap_for_mutators(); void abort_refinement(); void verify_after_full_collection(); - void print_heap_after_full_collection(G1HeapTransition* heap_transition); + void print_heap_after_full_collection(); // Helper method for satisfy_failed_allocation() HeapWord* satisfy_failed_allocation_helper(size_t word_size, @@ -799,7 +796,7 @@ class G1CollectedHeap : public CollectedHeap { void verify_before_young_collection(G1HeapVerifier::G1VerifyType type); void verify_after_young_collection(G1HeapVerifier::G1VerifyType type); - void calculate_collection_set(G1EvacuationInfo& evacuation_info, double target_pause_time_ms); + void calculate_collection_set(G1EvacuationInfo* evacuation_info, double target_pause_time_ms); // Actually do the work of evacuating the parts of the collection set. // The has_optional_evacuation_work flag for the initial collection set @@ -825,8 +822,8 @@ class G1CollectedHeap : public CollectedHeap { void evacuate_next_optional_regions(G1ParScanThreadStateSet* per_thread_states); public: - void pre_evacuate_collection_set(G1EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* pss); - void post_evacuate_collection_set(G1EvacuationInfo& evacuation_info, + void pre_evacuate_collection_set(G1EvacuationInfo* evacuation_info, G1ParScanThreadStateSet* pss); + void post_evacuate_collection_set(G1EvacuationInfo* evacuation_info, G1RedirtyCardsQueueSet* rdcqs, G1ParScanThreadStateSet* pss); @@ -1466,6 +1463,7 @@ class G1CollectedHeap : public CollectedHeap { void print_regions_on(outputStream* st) const; public: + virtual void print_on(outputStream* st) const; virtual void print_extended_on(outputStream* st) const; virtual void print_on_error(outputStream* st) const; @@ -1483,6 +1481,28 @@ class G1CollectedHeap : public CollectedHeap { virtual bool print_location(outputStream* st, void* addr) const; }; +// Scoped object that performs common pre- and post-gc heap printing operations. +class G1HeapPrinterMark : public StackObj { + G1CollectedHeap* _g1h; + G1HeapTransition _heap_transition; + +public: + G1HeapPrinterMark(G1CollectedHeap* g1h); + ~G1HeapPrinterMark(); +}; + +// Scoped object that performs common pre- and post-gc operations related to +// JFR events. +class G1JFRTracerMark : public StackObj { +protected: + STWGCTimer* _timer; + GCTracer* _tracer; + +public: + G1JFRTracerMark(STWGCTimer* timer, GCTracer* tracer); + ~G1JFRTracerMark(); +}; + class G1ParEvacuateFollowersClosure : public VoidClosure { private: double _start_term; diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp index 2f06c0d53c7..5902b9ace46 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp @@ -595,6 +595,8 @@ class G1ConcurrentMark : public CHeapObj { ConcurrentGCTimer* gc_timer_cm() const { return _gc_timer_cm; } + G1OldTracer* gc_tracer_cm() const { return _gc_tracer_cm; } + private: // Rebuilds the remembered sets for chosen regions in parallel and concurrently to the application. void rebuild_rem_set_concurrently(); diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index f4c58c90afa..137bf6fadf5 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -112,9 +112,10 @@ uint G1FullCollector::calc_active_workers() { G1FullCollector::G1FullCollector(G1CollectedHeap* heap, bool explicit_gc, bool clear_soft_refs, - bool do_maximum_compaction) : + bool do_maximum_compaction, + G1FullGCTracer* tracer) : _heap(heap), - _scope(heap->g1mm(), explicit_gc, clear_soft_refs, do_maximum_compaction), + _scope(heap->g1mm(), explicit_gc, clear_soft_refs, do_maximum_compaction, tracer), _num_workers(calc_active_workers()), _oop_queue_set(_num_workers), _array_queue_set(_num_workers), @@ -171,9 +172,6 @@ class PrepareRegionsClosure : public HeapRegionClosure { void G1FullCollector::prepare_collection() { _heap->policy()->record_full_collection_start(); - _heap->print_heap_before_gc(); - _heap->print_heap_regions(); - _heap->abort_concurrent_cycle(); _heap->verify_before_full_collection(scope()->is_explicit_gc()); @@ -229,7 +227,7 @@ void G1FullCollector::complete_collection() { _heap->verify_after_full_collection(); - _heap->print_heap_after_full_collection(scope()->heap_transition()); + _heap->print_heap_after_full_collection(); } void G1FullCollector::before_marking_update_attribute_table(HeapRegion* hr) { diff --git a/src/hotspot/share/gc/g1/g1FullCollector.hpp b/src/hotspot/share/gc/g1/g1FullCollector.hpp index 176d7b9f5ce..5f0e5b1ff2c 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.hpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.hpp @@ -31,6 +31,8 @@ #include "gc/g1/g1FullGCOopClosures.hpp" #include "gc/g1/g1FullGCScope.hpp" #include "gc/g1/g1RegionMarkStatsCache.hpp" +#include "gc/shared/gcId.hpp" +#include "gc/shared/gcTraceTime.hpp" #include "gc/shared/preservedMarks.hpp" #include "gc/shared/referenceProcessor.hpp" #include "gc/shared/taskqueue.hpp" @@ -55,6 +57,18 @@ class G1FullGCSubjectToDiscoveryClosure: public BoolObjectClosure { } }; +// Full GC Mark that holds GC id and CPU time trace. Needs to be separate +// from the G1FullCollector and G1FullGCScope to allow the Full GC logging +// to have the same structure as the Young GC logging. +class G1FullGCMark : StackObj { + GCIdMark _gc_id; + G1FullGCTracer _tracer; + GCTraceCPUTime _cpu_time; +public: + G1FullGCMark() : _gc_id(), _tracer(), _cpu_time(&_tracer) { } + G1FullGCTracer* tracer() { return &_tracer; } +}; + // The G1FullCollector holds data associated with the current Full GC. class G1FullCollector : StackObj { G1CollectedHeap* _heap; @@ -81,7 +95,8 @@ class G1FullCollector : StackObj { G1FullCollector(G1CollectedHeap* heap, bool explicit_gc, bool clear_soft_refs, - bool do_maximum_compaction); + bool do_maximum_compaction, + G1FullGCTracer* tracer); ~G1FullCollector(); void prepare_collection(); diff --git a/src/hotspot/share/gc/g1/g1FullGCScope.cpp b/src/hotspot/share/gc/g1/g1FullGCScope.cpp index 95d14930ce2..13c7b37a822 100644 --- a/src/hotspot/share/gc/g1/g1FullGCScope.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCScope.cpp @@ -25,30 +25,35 @@ #include "precompiled.hpp" #include "gc/g1/g1FullGCScope.hpp" +G1FullGCJFRTracerMark::G1FullGCJFRTracerMark(STWGCTimer* timer, GCTracer* tracer) + : G1JFRTracerMark(timer, tracer) { + + G1CollectedHeap::heap()->pre_full_gc_dump(_timer); +} + +G1FullGCJFRTracerMark::~G1FullGCJFRTracerMark() { + G1CollectedHeap::heap()->post_full_gc_dump(_timer); +} + G1FullGCScope::G1FullGCScope(G1MonitoringSupport* monitoring_support, bool explicit_gc, bool clear_soft, - bool do_maximum_compaction) : + bool do_maximum_compaction, + G1FullGCTracer* tracer) : _rm(), _explicit_gc(explicit_gc), _g1h(G1CollectedHeap::heap()), - _gc_id(), _svc_marker(SvcGCMarker::FULL), _timer(), - _tracer(), + _tracer(tracer), _active(), - _cpu_time(), + _tracer_mark(&_timer, _tracer), _soft_refs(clear_soft, _g1h->soft_ref_policy()), _monitoring_scope(monitoring_support, true /* full_gc */, true /* all_memory_pools_affected */), - _heap_transition(_g1h), + _heap_printer(_g1h), _region_compaction_threshold(do_maximum_compaction ? HeapRegion::GrainWords : - (1 - MarkSweepDeadRatio / 100.0) * HeapRegion::GrainWords) { - _timer.register_gc_start(); - _tracer.report_gc_start(_g1h->gc_cause(), _timer.gc_start()); - _g1h->pre_full_gc_dump(&_timer); - _g1h->trace_heap_before_gc(&_tracer); -} + (1 - MarkSweepDeadRatio / 100.0) * HeapRegion::GrainWords) { } G1FullGCScope::~G1FullGCScope() { // We must call G1MonitoringSupport::update_sizes() in the same scoping level @@ -56,10 +61,6 @@ G1FullGCScope::~G1FullGCScope() { // TraceMemoryManagerStats is called) so that the G1 memory pools are updated // before any GC notifications are raised. _g1h->g1mm()->update_sizes(); - _g1h->trace_heap_after_gc(&_tracer); - _g1h->post_full_gc_dump(&_timer); - _timer.register_gc_end(); - _tracer.report_gc_end(_timer.gc_end(), _timer.time_partitions()); } bool G1FullGCScope::is_explicit_gc() { @@ -75,11 +76,7 @@ STWGCTimer* G1FullGCScope::timer() { } G1FullGCTracer* G1FullGCScope::tracer() { - return &_tracer; -} - -G1HeapTransition* G1FullGCScope::heap_transition() { - return &_heap_transition; + return _tracer; } size_t G1FullGCScope::region_compaction_threshold() { diff --git a/src/hotspot/share/gc/g1/g1FullGCScope.hpp b/src/hotspot/share/gc/g1/g1FullGCScope.hpp index e12f72b950f..1d69b049b65 100644 --- a/src/hotspot/share/gc/g1/g1FullGCScope.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCScope.hpp @@ -28,8 +28,6 @@ #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1HeapTransition.hpp" #include "gc/g1/g1Trace.hpp" -#include "gc/shared/gcId.hpp" -#include "gc/shared/gcTraceTime.hpp" #include "gc/shared/gcTimer.hpp" #include "gc/shared/gcVMOperations.hpp" #include "gc/shared/isGCActiveMark.hpp" @@ -39,27 +37,34 @@ class GCMemoryManager; +class G1FullGCJFRTracerMark : public G1JFRTracerMark { +public: + + G1FullGCJFRTracerMark(STWGCTimer* timer, GCTracer* tracer); + ~G1FullGCJFRTracerMark(); +}; + // Class used to group scoped objects used in the Full GC together. class G1FullGCScope : public StackObj { ResourceMark _rm; bool _explicit_gc; G1CollectedHeap* _g1h; - GCIdMark _gc_id; SvcGCMarker _svc_marker; STWGCTimer _timer; - G1FullGCTracer _tracer; + G1FullGCTracer* _tracer; IsGCActiveMark _active; - GCTraceCPUTime _cpu_time; + G1FullGCJFRTracerMark _tracer_mark; ClearedAllSoftRefs _soft_refs; G1MonitoringScope _monitoring_scope; - G1HeapTransition _heap_transition; + G1HeapPrinterMark _heap_printer; size_t _region_compaction_threshold; public: G1FullGCScope(G1MonitoringSupport* monitoring_support, bool explicit_gc, bool clear_soft, - bool do_maximal_compaction); + bool do_maximal_compaction, + G1FullGCTracer* tracer); ~G1FullGCScope(); bool is_explicit_gc(); diff --git a/src/hotspot/share/gc/g1/g1VMOperations.cpp b/src/hotspot/share/gc/g1/g1VMOperations.cpp index 59004af9a90..ca50b427fdb 100644 --- a/src/hotspot/share/gc/g1/g1VMOperations.cpp +++ b/src/hotspot/share/gc/g1/g1VMOperations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, 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 "gc/g1/g1ConcurrentMarkThread.inline.hpp" #include "gc/g1/g1Policy.hpp" #include "gc/g1/g1VMOperations.hpp" +#include "gc/g1/g1Trace.hpp" #include "gc/shared/concurrentGCBreakpoints.hpp" #include "gc/shared/gcCause.hpp" #include "gc/shared/gcId.hpp" @@ -161,8 +162,8 @@ void VM_G1CollectForAllocation::doit() { void VM_G1PauseConcurrent::doit() { GCIdMark gc_id_mark(_gc_id); - GCTraceCPUTime tcpu; G1CollectedHeap* g1h = G1CollectedHeap::heap(); + GCTraceCPUTime tcpu(g1h->concurrent_mark()->gc_tracer_cm()); // GCTraceTime(...) only supports sub-phases, so a more verbose version // is needed when we report the top-level pause phase. diff --git a/src/hotspot/share/gc/g1/heapRegion.cpp b/src/hotspot/share/gc/g1/heapRegion.cpp index 26d40d7438c..4e8cba1f2f2 100644 --- a/src/hotspot/share/gc/g1/heapRegion.cpp +++ b/src/hotspot/share/gc/g1/heapRegion.cpp @@ -493,6 +493,7 @@ class G1VerificationClosure : public BasicOopIterateClosure { } void set_containing_obj(oop obj) { + assert(!_g1h->is_obj_dead_cond(obj, _vo), "Precondition"); _containing_obj = obj; } @@ -519,8 +520,6 @@ class VerifyLiveClosure : public G1VerificationClosure { template void do_oop_work(T* p) { assert(_containing_obj != NULL, "Precondition"); - assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo), - "Precondition"); verify_liveness(p); } @@ -577,8 +576,6 @@ class VerifyRemSetClosure : public G1VerificationClosure { template void do_oop_work(T* p) { assert(_containing_obj != NULL, "Precondition"); - assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo), - "Precondition"); verify_remembered_set(p); } diff --git a/src/hotspot/share/gc/parallel/objectStartArray.cpp b/src/hotspot/share/gc/parallel/objectStartArray.cpp index d2d98bc24a9..698a2219424 100644 --- a/src/hotspot/share/gc/parallel/objectStartArray.cpp +++ b/src/hotspot/share/gc/parallel/objectStartArray.cpp @@ -130,8 +130,15 @@ bool ObjectStartArray::object_starts_in_range(HeapWord* start_addr, "Range is wrong. start_addr (" PTR_FORMAT ") is after end_addr (" PTR_FORMAT ")", p2i(start_addr), p2i(end_addr)); + assert(is_aligned(start_addr, CardTable::card_size), "precondition"); + + if (start_addr == end_addr) { + // No objects in empty range. + return false; + } + jbyte* start_block = block_for_addr(start_addr); - jbyte* end_block = block_for_addr(end_addr); + jbyte* end_block = block_for_addr(end_addr - 1); for (jbyte* block = start_block; block <= end_block; block++) { if (*block != clean_block) { diff --git a/src/hotspot/share/gc/parallel/objectStartArray.hpp b/src/hotspot/share/gc/parallel/objectStartArray.hpp index 45b4a53b16c..016950dbf64 100644 --- a/src/hotspot/share/gc/parallel/objectStartArray.hpp +++ b/src/hotspot/share/gc/parallel/objectStartArray.hpp @@ -147,9 +147,11 @@ class ObjectStartArray : public CHeapObj { return *block != clean_block; } - // Return true if an object starts in the range of heap addresses. - // If an object starts at an address corresponding to - // "start", the method will return true. + // Return true iff an object starts in + // [start_addr, end_addr_aligned_up) + // where + // end_addr_aligned_up = align_up(end_addr, _card_size) + // Precondition: start_addr is card-size aligned bool object_starts_in_range(HeapWord* start_addr, HeapWord* end_addr) const; }; diff --git a/src/hotspot/share/gc/parallel/parallel_globals.hpp b/src/hotspot/share/gc/parallel/parallel_globals.hpp index 19953ca0b61..b9202ce7cda 100644 --- a/src/hotspot/share/gc/parallel/parallel_globals.hpp +++ b/src/hotspot/share/gc/parallel/parallel_globals.hpp @@ -55,9 +55,6 @@ "limiter (a number between 0-100)") \ range(0, 100) \ \ - develop(uintx, GCWorkerDelayMillis, 0, \ - "Delay in scheduling GC workers (in milliseconds)") \ - \ product(bool, PSChunkLargeArrays, true, \ "Process large arrays in chunks") diff --git a/src/hotspot/share/gc/parallel/psCardTable.cpp b/src/hotspot/share/gc/parallel/psCardTable.cpp index ec186aec83f..10ecaa0dd31 100644 --- a/src/hotspot/share/gc/parallel/psCardTable.cpp +++ b/src/hotspot/share/gc/parallel/psCardTable.cpp @@ -33,6 +33,7 @@ #include "oops/access.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/prefetch.inline.hpp" +#include "utilities/spinYield.hpp" #include "utilities/align.hpp" // Checks an individual oop for missing precise marks. Mark @@ -117,18 +118,202 @@ class CheckForPreciseMarks : public BasicOopIterateClosure { virtual void do_oop(narrowOop* p) { CheckForPreciseMarks::do_oop_work(p); } }; +static void prefetch_write(void *p) { + if (PrefetchScanIntervalInBytes >= 0) { + Prefetch::write(p, PrefetchScanIntervalInBytes); + } +} + +void PSCardTable::scan_obj_with_limit(PSPromotionManager* pm, + oop obj, + HeapWord* start, + HeapWord* end) { + if (!obj->is_typeArray()) { + prefetch_write(start); + pm->push_contents_bounded(obj, start, end); + } +} + +void PSCardTable::pre_scavenge(HeapWord* old_gen_bottom, uint active_workers) { + _preprocessing_active_workers = active_workers; +} + +// The "shadow" table is a copy of the card table entries of the current stripe. +// It is used to separate card reading, clearing and redirtying which reduces +// complexity significantly. +class PSStripeShadowCardTable { + typedef CardTable::CardValue CardValue; + + const uint _card_shift; + const uint _card_size; + CardValue _table[PSCardTable::num_cards_in_stripe]; + const CardValue* _table_base; + +public: + PSStripeShadowCardTable(PSCardTable* pst, HeapWord* const start, HeapWord* const end) : + _card_shift(CardTable::card_shift), + _card_size(CardTable::card_size), + _table_base(_table - (uintptr_t(start) >> _card_shift)) { + size_t stripe_byte_size = pointer_delta(end, start) * HeapWordSize; + size_t copy_length = align_up(stripe_byte_size, _card_size) >> _card_shift; + // The end of the last stripe may not be card aligned as it is equal to old + // gen top at scavenge start. We should not clear the card containing old gen + // top if not card aligned because there can be promoted objects on that + // same card. If it was marked dirty because of the promoted objects and we + // cleared it, we would loose a card mark. + size_t clear_length = align_down(stripe_byte_size, _card_size) >> _card_shift; + CardValue* stripe_start_card = pst->byte_for(start); + memcpy(_table, stripe_start_card, copy_length); + memset(stripe_start_card, CardTable::clean_card_val(), clear_length); + } + + HeapWord* addr_for(const CardValue* const card) { + assert(card >= _table && card <= &_table[PSCardTable::num_cards_in_stripe], "out of bounds"); + return (HeapWord*) ((card - _table_base) << _card_shift); + } + + const CardValue* card_for(HeapWord* addr) { + return &_table_base[uintptr_t(addr) >> _card_shift]; + } + + bool is_dirty(const CardValue* const card) { + return !is_clean(card); + } + + bool is_clean(const CardValue* const card) { + assert(card >= _table && card < &_table[PSCardTable::num_cards_in_stripe], "out of bounds"); + return *card == PSCardTable::clean_card_val(); + } + + const CardValue* find_first_dirty_card(const CardValue* const start, + const CardValue* const end) { + for (const CardValue* i = start; i < end; ++i) { + if (is_dirty(i)) { + return i; + } + } + return end; + } + + const CardValue* find_first_clean_card(const CardValue* const start, + const CardValue* const end) { + for (const CardValue* i = start; i < end; ++i) { + if (is_clean(i)) { + return i; + } + } + return end; + } +}; + +template +void PSCardTable::process_range(Func&& object_start, + PSPromotionManager* pm, + HeapWord* const start, + HeapWord* const end) { + assert(start < end, "precondition"); + assert(is_card_aligned(start), "precondition"); + + PSStripeShadowCardTable sct(this, start, end); + + // end might not be card-aligned. + const CardValue* end_card = sct.card_for(end - 1) + 1; + + for (HeapWord* i_addr = start; i_addr < end; /* empty */) { + const CardValue* dirty_l = sct.find_first_dirty_card(sct.card_for(i_addr), end_card); + const CardValue* dirty_r = sct.find_first_clean_card(dirty_l, end_card); + + assert(dirty_l <= dirty_r, "inv"); + + if (dirty_l == dirty_r) { + assert(dirty_r == end_card, "inv"); + break; + } + + // Located a non-empty dirty chunk [dirty_l, dirty_r). + HeapWord* addr_l = sct.addr_for(dirty_l); + HeapWord* addr_r = MIN2(sct.addr_for(dirty_r), end); + + // Scan objects overlapping [addr_l, addr_r) limited to [start, end). + HeapWord* obj_addr = object_start(addr_l); + + while (true) { + assert(obj_addr < addr_r, "inv"); + + oop obj = cast_to_oop(obj_addr); + const bool is_obj_array = obj->is_objArray(); + HeapWord* const obj_end_addr = obj_addr + obj->size(); + + if (is_obj_array) { + // Always scan obj arrays precisely (they are always marked precisely) + // to avoid unnecessary work. + scan_obj_with_limit(pm, obj, addr_l, addr_r); + } else { + if (obj_addr < i_addr && i_addr > start) { + // Already scanned this object. Has been one that spans multiple dirty chunks. + // The second condition makes sure objects reaching in the stripe are scanned once. + } else { + scan_obj_with_limit(pm, obj, addr_l, end); + } + } + + if (obj_end_addr >= addr_r) { + i_addr = is_obj_array ? addr_r : obj_end_addr; + break; + } + + // Move to next obj inside this dirty chunk. + obj_addr = obj_end_addr; + } + + // Finished a dirty chunk. + pm->drain_stacks_cond_depth(); + } +} + +template +void PSCardTable::preprocess_card_table_parallel(Func&& object_start, + HeapWord* old_gen_bottom, + HeapWord* old_gen_top, + uint stripe_index, + uint n_stripes) { + const size_t num_cards_in_slice = num_cards_in_stripe * n_stripes; + CardValue* cur_card = byte_for(old_gen_bottom) + stripe_index * num_cards_in_stripe; + CardValue* const end_card = byte_for(old_gen_top - 1) + 1; + + for (/* empty */; cur_card < end_card; cur_card += num_cards_in_slice) { + HeapWord* stripe_addr = addr_for(cur_card); + if (is_dirty(cur_card)) { + // The first card of this stripe is already dirty, no need to see if the + // reaching-in object is a potentially imprecisely marked non-array + // object. + continue; + } + HeapWord* first_obj_addr = object_start(stripe_addr); + if (first_obj_addr == stripe_addr) { + // No object reaching into this stripe. + continue; + } + oop first_obj = cast_to_oop(first_obj_addr); + if (!first_obj->is_array() && is_dirty(byte_for(first_obj_addr))) { + // Found a non-array object reaching into the stripe that has + // potentially been marked imprecisely. Mark first card of the stripe + // dirty so it will be processed later. + *cur_card = dirty_card_val(); + } + } +} + // We get passed the space_top value to prevent us from traversing into // the old_gen promotion labs, which cannot be safely parsed. // Do not call this method if the space is empty. // It is a waste to start tasks and get here only to -// do no work. If this method needs to be called -// when the space is empty, fix the calculation of -// end_card to allow sp_top == sp->bottom(). +// do no work. This method is just a no-op if space_top == sp->bottom(). // The generation (old gen) is divided into slices, which are further // subdivided into stripes, with one stripe per GC thread. The size of -// a stripe is a constant, ssize. +// a stripe is a constant, num_cards_in_stripe. // // +===============+ slice 0 // | stripe 0 | @@ -152,200 +337,66 @@ class CheckForPreciseMarks : public BasicOopIterateClosure { // In this case there are 4 threads, so 4 stripes. A GC thread first works on // its stripe within slice 0 and then moves to its stripe in the next slice // until it has exceeded the top of the generation. The distance to stripe in -// the next slice is calculated based on the number of stripes. The next -// stripe is at ssize * number_of_stripes (= slice_stride).. So after -// finishing stripe 0 in slice 0, the thread finds the stripe 0 in slice1 by -// adding slice_stride to the start of stripe 0 in slice 0 to get to the start -// of stride 0 in slice 1. +// the next slice is calculated based on the number of stripes. After finishing +// stripe 0 in slice 0, the thread finds the stripe 0 in slice 1 by adding +// slice_size_in_words to the start of stripe 0 in slice 0 to get to the start +// of stripe 0 in slice 1. + +// Scavenging and accesses to the card table are strictly limited to the stripe. +// In particular scavenging of an object crossing stripe boundaries is shared +// among the threads assigned to the stripes it resides on. This reduces +// complexity and enables shared scanning of large objects. +// It requires preprocessing of the card table though where imprecise card marks of +// objects crossing stripe boundaries are propagated to the first card of +// each stripe covered by the individual object. void PSCardTable::scavenge_contents_parallel(ObjectStartArray* start_array, - MutableSpace* sp, - HeapWord* space_top, + HeapWord* old_gen_bottom, + HeapWord* old_gen_top, PSPromotionManager* pm, - uint stripe_number, - uint stripe_total) { - int ssize = 128; // Naked constant! Work unit = 64k. - int dirty_card_count = 0; - - // It is a waste to get here if empty. - assert(sp->bottom() < sp->top(), "Should not be called if empty"); - oop* sp_top = (oop*)space_top; - CardValue* start_card = byte_for(sp->bottom()); - CardValue* end_card = byte_for(sp_top - 1) + 1; - oop* last_scanned = NULL; // Prevent scanning objects more than once - // The width of the stripe ssize*stripe_total must be - // consistent with the number of stripes so that the complete slice - // is covered. - size_t slice_width = ssize * stripe_total; - for (CardValue* slice = start_card; slice < end_card; slice += slice_width) { - CardValue* worker_start_card = slice + stripe_number * ssize; - if (worker_start_card >= end_card) - return; // We're done. - - CardValue* worker_end_card = worker_start_card + ssize; - if (worker_end_card > end_card) - worker_end_card = end_card; - - // We do not want to scan objects more than once. In order to accomplish - // this, we assert that any object with an object head inside our 'slice' - // belongs to us. We may need to extend the range of scanned cards if the - // last object continues into the next 'slice'. - // - // Note! ending cards are exclusive! - HeapWord* slice_start = addr_for(worker_start_card); - HeapWord* slice_end = MIN2((HeapWord*) sp_top, addr_for(worker_end_card)); - -#ifdef ASSERT - if (GCWorkerDelayMillis > 0) { - // Delay 1 worker so that it proceeds after all the work - // has been completed. - if (stripe_number < 2) { - os::naked_sleep(GCWorkerDelayMillis); - } + uint stripe_index, + uint n_stripes) { + // ObjectStartArray queries can be expensive for large objects. We cache known objects. + struct { + HeapWord* start_addr; + HeapWord* end_addr; + } cached_obj {nullptr, old_gen_bottom}; + + // Queries must be monotonic because we don't check addr >= cached_obj.start_addr. + auto object_start = [&] (HeapWord* addr) { + if (addr < cached_obj.end_addr) { + assert(cached_obj.start_addr != nullptr, "inv"); + return cached_obj.start_addr; } -#endif + HeapWord* result = start_array->object_start(addr); - // If there are not objects starting within the chunk, skip it. - if (!start_array->object_starts_in_range(slice_start, slice_end)) { - continue; - } - // Update our beginning addr - HeapWord* first_object = start_array->object_start(slice_start); - debug_only(oop* first_object_within_slice = (oop*) first_object;) - if (first_object < slice_start) { - last_scanned = (oop*)(first_object + cast_to_oop(first_object)->size()); - debug_only(first_object_within_slice = last_scanned;) - worker_start_card = byte_for(last_scanned); - } - - // Update the ending addr - if (slice_end < (HeapWord*)sp_top) { - // The subtraction is important! An object may start precisely at slice_end. - HeapWord* last_object = start_array->object_start(slice_end - 1); - slice_end = last_object + cast_to_oop(last_object)->size(); - // worker_end_card is exclusive, so bump it one past the end of last_object's - // covered span. - worker_end_card = byte_for(slice_end) + 1; - - if (worker_end_card > end_card) - worker_end_card = end_card; - } - - assert(slice_end <= (HeapWord*)sp_top, "Last object in slice crosses space boundary"); - assert(is_valid_card_address(worker_start_card), "Invalid worker start card"); - assert(is_valid_card_address(worker_end_card), "Invalid worker end card"); - // Note that worker_start_card >= worker_end_card is legal, and happens when - // an object spans an entire slice. - assert(worker_start_card <= end_card, "worker start card beyond end card"); - assert(worker_end_card <= end_card, "worker end card beyond end card"); - - CardValue* current_card = worker_start_card; - while (current_card < worker_end_card) { - // Find an unclean card. - while (current_card < worker_end_card && card_is_clean(*current_card)) { - current_card++; - } - CardValue* first_unclean_card = current_card; - - // Find the end of a run of contiguous unclean cards - while (current_card < worker_end_card && !card_is_clean(*current_card)) { - while (current_card < worker_end_card && !card_is_clean(*current_card)) { - current_card++; - } - - if (current_card < worker_end_card) { - // Some objects may be large enough to span several cards. If such - // an object has more than one dirty card, separated by a clean card, - // we will attempt to scan it twice. The test against "last_scanned" - // prevents the redundant object scan, but it does not prevent newly - // marked cards from being cleaned. - HeapWord* last_object_in_dirty_region = start_array->object_start(addr_for(current_card)-1); - size_t size_of_last_object = cast_to_oop(last_object_in_dirty_region)->size(); - HeapWord* end_of_last_object = last_object_in_dirty_region + size_of_last_object; - CardValue* ending_card_of_last_object = byte_for(end_of_last_object); - assert(ending_card_of_last_object <= worker_end_card, "ending_card_of_last_object is greater than worker_end_card"); - if (ending_card_of_last_object > current_card) { - // This means the object spans the next complete card. - // We need to bump the current_card to ending_card_of_last_object - current_card = ending_card_of_last_object; - } - } - } - CardValue* following_clean_card = current_card; - - if (first_unclean_card < worker_end_card) { - oop* p = (oop*) start_array->object_start(addr_for(first_unclean_card)); - assert((HeapWord*)p <= addr_for(first_unclean_card), "checking"); - // "p" should always be >= "last_scanned" because newly GC dirtied - // cards are no longer scanned again (see comment at end - // of loop on the increment of "current_card"). Test that - // hypothesis before removing this code. - // If this code is removed, deal with the first time through - // the loop when the last_scanned is the object starting in - // the previous slice. - assert((p >= last_scanned) || - (last_scanned == first_object_within_slice), - "Should no longer be possible"); - if (p < last_scanned) { - // Avoid scanning more than once; this can happen because - // newgen cards set by GC may a different set than the - // originally dirty set - p = last_scanned; - } - oop* to = (oop*)addr_for(following_clean_card); + cached_obj.start_addr = result; + cached_obj.end_addr = result + cast_to_oop(result)->size(); - // Test slice_end first! - if ((HeapWord*)to > slice_end) { - to = (oop*)slice_end; - } else if (to > sp_top) { - to = sp_top; - } + return result; + }; - // we know which cards to scan, now clear them - if (first_unclean_card <= worker_start_card+1) - first_unclean_card = worker_start_card+1; - if (following_clean_card >= worker_end_card-1) - following_clean_card = worker_end_card-1; + // Prepare scavenge. + preprocess_card_table_parallel(object_start, old_gen_bottom, old_gen_top, stripe_index, n_stripes); - while (first_unclean_card < following_clean_card) { - *first_unclean_card++ = clean_card; - } + // Sync with other workers. + Atomic::dec(&_preprocessing_active_workers); + SpinYield spin_yield; + while (Atomic::load_acquire(&_preprocessing_active_workers) > 0) { + spin_yield.wait(); + } - const int interval = PrefetchScanIntervalInBytes; - // scan all objects in the range - if (interval != 0) { - while (p < to) { - Prefetch::write(p, interval); - oop m = cast_to_oop(p); - assert(oopDesc::is_oop_or_null(m), "Expected an oop or NULL for header field at " PTR_FORMAT, p2i(m)); - pm->push_contents(m); - p += m->size(); - } - pm->drain_stacks_cond_depth(); - } else { - while (p < to) { - oop m = cast_to_oop(p); - assert(oopDesc::is_oop_or_null(m), "Expected an oop or NULL for header field at " PTR_FORMAT, p2i(m)); - pm->push_contents(m); - p += m->size(); - } - pm->drain_stacks_cond_depth(); - } - last_scanned = p; - } - // "current_card" is still the "following_clean_card" or - // the current_card is >= the worker_end_card so the - // loop will not execute again. - assert((current_card == following_clean_card) || - (current_card >= worker_end_card), - "current_card should only be incremented if it still equals " - "following_clean_card"); - // Increment current_card so that it is not processed again. - // It may now be dirty because a old-to-young pointer was - // found on it an updated. If it is now dirty, it cannot be - // be safely cleaned in the next iteration. - current_card++; - } + // Scavenge + cached_obj = {nullptr, old_gen_bottom}; + const size_t stripe_size_in_words = num_cards_in_stripe * card_size_in_words; + const size_t slice_size_in_words = stripe_size_in_words * n_stripes; + HeapWord* cur_addr = old_gen_bottom + stripe_index * stripe_size_in_words; + for (/* empty */; cur_addr < old_gen_top; cur_addr += slice_size_in_words) { + HeapWord* const stripe_l = cur_addr; + HeapWord* const stripe_r = MIN2(cur_addr + stripe_size_in_words, + old_gen_top); + + process_range(object_start, pm, stripe_l, stripe_r); } } diff --git a/src/hotspot/share/gc/parallel/psCardTable.hpp b/src/hotspot/share/gc/parallel/psCardTable.hpp index d912c656741..3c35ad23645 100644 --- a/src/hotspot/share/gc/parallel/psCardTable.hpp +++ b/src/hotspot/share/gc/parallel/psCardTable.hpp @@ -33,7 +33,36 @@ class ObjectStartArray; class PSPromotionManager; class PSCardTable: public CardTable { - private: + friend class PSStripeShadowCardTable; + static constexpr size_t num_cards_in_stripe = 128; + static_assert(num_cards_in_stripe >= 1, "progress"); + + volatile int _preprocessing_active_workers; + + bool is_dirty(CardValue* card) { + return !is_clean(card); + } + + bool is_clean(CardValue* card) { + return *card == clean_card_val(); + } + + // Iterate the stripes with the given index and copy imprecise card marks of + // objects reaching into a stripe to its first card. + template + void preprocess_card_table_parallel(Func&& object_start, + HeapWord* old_gen_bottom, + HeapWord* old_gen_top, + uint stripe_index, + uint n_stripes); + + // Scavenge contents on dirty cards of the given stripe [start, end). + template + void process_range(Func&& object_start, + PSPromotionManager* pm, + HeapWord* const start, + HeapWord* const end); + // Support methods for resizing the card table. // resize_commit_uncommit() returns true if the pages were committed or // uncommitted @@ -50,19 +79,27 @@ class PSCardTable: public CardTable { verify_card = CT_MR_BS_last_reserved + 5 }; + void scan_obj_with_limit(PSPromotionManager* pm, + oop obj, + HeapWord* start, + HeapWord* end); + public: - PSCardTable(MemRegion whole_heap) : CardTable(whole_heap) {} + PSCardTable(MemRegion whole_heap) : CardTable(whole_heap), + _preprocessing_active_workers(0) {} static CardValue youngergen_card_val() { return youngergen_card; } static CardValue verify_card_val() { return verify_card; } // Scavenge support + void pre_scavenge(HeapWord* old_gen_bottom, uint active_workers); + // Scavenge contents of stripes with the given index. void scavenge_contents_parallel(ObjectStartArray* start_array, - MutableSpace* sp, - HeapWord* space_top, + HeapWord* old_gen_bottom, + HeapWord* old_gen_top, PSPromotionManager* pm, - uint stripe_number, - uint stripe_total); + uint stripe_index, + uint n_stripes); bool addr_is_marked_imprecise(void *addr); bool addr_is_marked_precise(void *addr); diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index 69b7dc9881a..ce96640c2e5 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -1767,7 +1767,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { Threads::number_of_non_daemon_threads()); ParallelScavengeHeap::heap()->workers().update_active_workers(active_workers); - GCTraceCPUTime tcpu; + GCTraceCPUTime tcpu(&_gc_tracer); GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause, true); heap->pre_full_gc_dump(&_gc_timer); diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.hpp b/src/hotspot/share/gc/parallel/psPromotionManager.hpp index e94be81b621..862b43c916e 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.hpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.hpp @@ -174,6 +174,7 @@ class PSPromotionManager { TASKQUEUE_STATS_ONLY(inline void record_steal(ScannerTask task);) void push_contents(oop obj); + void push_contents_bounded(oop obj, HeapWord* left, HeapWord* right); }; #endif // SHARE_GC_PARALLEL_PSPROMOTIONMANAGER_HPP diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp index 5eb6a20b0b7..12f1f160403 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp @@ -128,6 +128,11 @@ inline void PSPromotionManager::push_contents(oop obj) { } } +inline void PSPromotionManager::push_contents_bounded(oop obj, HeapWord* left, HeapWord* right) { + PSPushContentsClosure pcc(this); + obj->oop_iterate(&pcc, MemRegion(left, right)); +} + template inline oop PSPromotionManager::copy_to_survivor_space(oop o) { assert(should_scavenge(&o), "Sanity"); @@ -218,13 +223,6 @@ inline oop PSPromotionManager::copy_unmarked_to_survivor_space(oop o, HeapWord* lab_base = old_gen()->allocate(OldPLABSize); if(lab_base != NULL) { -#ifdef ASSERT - // Delay the initialization of the promotion lab (plab). - // This exposes uninitialized plabs to card table processing. - if (GCWorkerDelayMillis > 0) { - os::naked_sleep(GCWorkerDelayMillis); - } -#endif _old_lab.initialize(MemRegion(lab_base, OldPLABSize)); // Try the old lab allocation again. new_obj = cast_to_oop(_old_lab.allocate(new_obj_size)); diff --git a/src/hotspot/share/gc/parallel/psScavenge.cpp b/src/hotspot/share/gc/parallel/psScavenge.cpp index 3f41b6f5064..c4011fff4e5 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.cpp +++ b/src/hotspot/share/gc/parallel/psScavenge.cpp @@ -88,7 +88,6 @@ static void scavenge_roots_work(ParallelRootType::Value root_type, uint worker_i assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(worker_id); - PSScavengeRootsClosure roots_closure(pm); PSPromoteRootsClosure roots_to_old_closure(pm); switch (root_type) { @@ -301,6 +300,10 @@ class ScavengeRootsTask : public AbstractGangTask { _active_workers(active_workers), _is_empty(is_empty), _terminator(active_workers, PSPromotionManager::vm_thread_promotion_manager()->stack_array_depth()) { + if (!_is_empty) { + PSCardTable* card_table = ParallelScavengeHeap::heap()->card_table(); + card_table->pre_scavenge(_old_gen->object_space()->bottom(), active_workers); + } } virtual void work(uint worker_id) { @@ -320,8 +323,9 @@ class ScavengeRootsTask : public AbstractGangTask { PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(worker_id); PSCardTable* card_table = ParallelScavengeHeap::heap()->card_table(); + // The top of the old gen changes during scavenge when objects are promoted. card_table->scavenge_contents_parallel(_old_gen->start_array(), - _old_gen->object_space(), + _old_gen->object_space()->bottom(), _gen_top, pm, worker_id, @@ -417,7 +421,7 @@ bool PSScavenge::invoke_no_policy() { { ResourceMark rm; - GCTraceCPUTime tcpu; + GCTraceCPUTime tcpu(&_gc_tracer); GCTraceTime(Info, gc) tm("Pause Young", NULL, gc_cause, true); TraceCollectorStats tcs(counters()); TraceMemoryManagerStats tms(heap->young_gc_manager(), gc_cause, "end of minor GC"); diff --git a/src/hotspot/share/gc/serial/defNewGeneration.cpp b/src/hotspot/share/gc/serial/defNewGeneration.cpp index 846444bcdc9..0b23c493558 100644 --- a/src/hotspot/share/gc/serial/defNewGeneration.cpp +++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp @@ -182,6 +182,8 @@ DefNewGeneration::DefNewGeneration(ReservedSpace rs, _pretenure_size_threshold_words = PretenureSizeThreshold >> LogHeapWordSize; _gc_timer = new (ResourceObj::C_HEAP, mtGC) STWGCTimer(); + + _gc_tracer = new (ResourceObj::C_HEAP, mtGC) DefNewTracer(); } void DefNewGeneration::compute_space_boundaries(uintx minimum_eden_size, @@ -531,8 +533,7 @@ void DefNewGeneration::collect(bool full, SerialHeap* heap = SerialHeap::heap(); _gc_timer->register_gc_start(); - DefNewTracer gc_tracer; - gc_tracer.report_gc_start(heap->gc_cause(), _gc_timer->gc_start()); + _gc_tracer->report_gc_start(heap->gc_cause(), _gc_timer->gc_start()); _old_gen = heap->old_gen(); @@ -550,7 +551,7 @@ void DefNewGeneration::collect(bool full, GCTraceTime(Trace, gc, phases) tm("DefNew", NULL, heap->gc_cause()); - heap->trace_heap_before_gc(&gc_tracer); + heap->trace_heap_before_gc(_gc_tracer); // These can be shared for all code paths IsAliveClosure is_alive(this); @@ -594,8 +595,8 @@ void DefNewGeneration::collect(bool full, ReferenceProcessorPhaseTimes pt(_gc_timer, rp->max_num_queues()); SerialGCRefProcProxyTask task(is_alive, keep_alive, evacuate_followers); const ReferenceProcessorStats& stats = rp->process_discovered_references(task, pt); - gc_tracer.report_gc_reference_stats(stats); - gc_tracer.report_tenuring_threshold(tenuring_threshold()); + _gc_tracer->report_gc_reference_stats(stats); + _gc_tracer->report_tenuring_threshold(tenuring_threshold()); pt.print_all_references(); assert(heap->no_allocs_since_save_marks(), "save marks have not been newly set."); @@ -647,7 +648,7 @@ void DefNewGeneration::collect(bool full, // Inform the next generation that a promotion failure occurred. _old_gen->promotion_failure_occurred(); - gc_tracer.report_promotion_failed(_promotion_failed_info); + _gc_tracer->report_promotion_failed(_promotion_failed_info); // Reset the PromotionFailureALot counters. NOT_PRODUCT(heap->reset_promotion_should_fail();) @@ -655,11 +656,11 @@ void DefNewGeneration::collect(bool full, // We should have processed and cleared all the preserved marks. _preserved_marks_set.reclaim(); - heap->trace_heap_after_gc(&gc_tracer); + heap->trace_heap_after_gc(_gc_tracer); _gc_timer->register_gc_end(); - gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions()); + _gc_tracer->report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions()); } void DefNewGeneration::init_assuming_no_promotion_failure() { diff --git a/src/hotspot/share/gc/serial/defNewGeneration.hpp b/src/hotspot/share/gc/serial/defNewGeneration.hpp index ac8d834782a..4d62a0dd9ed 100644 --- a/src/hotspot/share/gc/serial/defNewGeneration.hpp +++ b/src/hotspot/share/gc/serial/defNewGeneration.hpp @@ -39,6 +39,7 @@ class ContiguousSpace; class CSpaceCounters; class DefNewYoungerGenClosure; class DefNewScanClosure; +class DefNewTracer; class ScanWeakRefClosure; class SerialHeap; class STWGCTimer; @@ -139,6 +140,8 @@ class DefNewGeneration: public Generation { STWGCTimer* _gc_timer; + DefNewTracer* _gc_tracer; + enum SomeProtectedConstants { // Generations are GenGrain-aligned and have size that are multiples of // GenGrain. @@ -330,6 +333,8 @@ class DefNewGeneration: public Generation { return _promo_failure_scan_stack.is_empty(); } + DefNewTracer* gc_tracer() const { return _gc_tracer; } + protected: // If clear_space is true, clear the survivor spaces. Eden is // cleared if the minimum size of eden is 0. If mangle_space diff --git a/src/hotspot/share/gc/shared/gcTrace.cpp b/src/hotspot/share/gc/shared/gcTrace.cpp index 126cb464b8e..e609864963f 100644 --- a/src/hotspot/share/gc/shared/gcTrace.cpp +++ b/src/hotspot/share/gc/shared/gcTrace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, 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 @@ -37,6 +37,10 @@ #include "utilities/macros.hpp" #include "utilities/ticks.hpp" +bool GCTracer::should_report_cpu_time_event() const { + return should_send_cpu_time_event(); +} + void GCTracer::report_gc_start_impl(GCCause::Cause cause, const Ticks& timestamp) { _shared_gc_info.set_cause(cause); _shared_gc_info.set_start_timestamp(timestamp); @@ -59,6 +63,10 @@ void GCTracer::report_gc_end(const Ticks& timestamp, TimePartitions* time_partit report_gc_end_impl(timestamp, time_partitions); } +void GCTracer::report_cpu_time_event(double user_time, double system_time, double real_time) const { + send_cpu_time_event(user_time, system_time, real_time); +} + void GCTracer::report_gc_reference_stats(const ReferenceProcessorStats& rps) const { send_reference_stats_event(REF_SOFT, rps.soft_count()); send_reference_stats_event(REF_WEAK, rps.weak_count()); diff --git a/src/hotspot/share/gc/shared/gcTrace.hpp b/src/hotspot/share/gc/shared/gcTrace.hpp index 6a00b7c71be..483149b3868 100644 --- a/src/hotspot/share/gc/shared/gcTrace.hpp +++ b/src/hotspot/share/gc/shared/gcTrace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, 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 @@ -97,12 +97,14 @@ class GCTracer : public ResourceObj { SharedGCInfo _shared_gc_info; public: + bool should_report_cpu_time_event() const; void report_gc_start(GCCause::Cause cause, const Ticks& timestamp); void report_gc_end(const Ticks& timestamp, TimePartitions* time_partitions); void report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary) const; void report_metaspace_summary(GCWhen::Type when, const MetaspaceSummary& metaspace_summary) const; void report_gc_reference_stats(const ReferenceProcessorStats& rp) const; void report_object_count_after_gc(BoolObjectClosure* object_filter, WorkGang* workers) NOT_SERVICES_RETURN; + void report_cpu_time_event(double user_time, double system_time, double real_time) const; protected: GCTracer(GCName name) : _shared_gc_info(name) {} @@ -110,12 +112,14 @@ class GCTracer : public ResourceObj { virtual void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions); private: + bool should_send_cpu_time_event() const; void send_garbage_collection_event() const; void send_gc_heap_summary_event(GCWhen::Type when, const GCHeapSummary& heap_summary) const; void send_meta_space_summary_event(GCWhen::Type when, const MetaspaceSummary& meta_space_summary) const; void send_metaspace_chunk_free_list_summary(GCWhen::Type when, Metaspace::MetadataType mdtype, const MetaspaceChunkFreeListSummary& summary) const; void send_reference_stats_event(ReferenceType type, size_t count) const; void send_phase_events(TimePartitions* time_partitions) const; + void send_cpu_time_event(double user_time, double system_time, double real_time) const; }; class YoungGCTracer : public GCTracer { diff --git a/src/hotspot/share/gc/shared/gcTraceSend.cpp b/src/hotspot/share/gc/shared/gcTraceSend.cpp index d57af7ceaf1..5ee37592f28 100644 --- a/src/hotspot/share/gc/shared/gcTraceSend.cpp +++ b/src/hotspot/share/gc/shared/gcTraceSend.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, 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 @@ -36,6 +36,10 @@ typedef uintptr_t TraceAddress; +bool GCTracer::should_send_cpu_time_event() const { + return EventGCCPUTime::is_enabled(); +} + void GCTracer::send_garbage_collection_event() const { EventGarbageCollection event(UNTIMED); if (event.should_commit()) { @@ -50,6 +54,17 @@ void GCTracer::send_garbage_collection_event() const { } } +void GCTracer::send_cpu_time_event(double user_time, double system_time, double real_time) const { + EventGCCPUTime e; + if (e.should_commit()) { + e.set_gcId(GCId::current()); + e.set_userTime((size_t)(user_time * NANOUNITS)); + e.set_systemTime((size_t)(system_time * NANOUNITS)); + e.set_realTime((size_t)(real_time * NANOUNITS)); + e.commit(); + } +} + void GCTracer::send_reference_stats_event(ReferenceType type, size_t count) const { EventGCReferenceStatistics e; if (e.should_commit()) { diff --git a/src/hotspot/share/gc/shared/gcTraceTime.cpp b/src/hotspot/share/gc/shared/gcTraceTime.cpp index 3cb5b0f7164..2477b801c07 100644 --- a/src/hotspot/share/gc/shared/gcTraceTime.cpp +++ b/src/hotspot/share/gc/shared/gcTraceTime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, 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,6 +25,7 @@ #include "precompiled.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/gcTraceTime.inline.hpp" +#include "gc/shared/gcTrace.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/universe.hpp" @@ -70,16 +71,18 @@ void GCTraceTimeLoggerImpl::log_end(Ticks end) { out.print_cr(" %.3fms", duration_in_ms); } -GCTraceCPUTime::GCTraceCPUTime() : - _active(log_is_enabled(Info, gc, cpu)), +GCTraceCPUTime::GCTraceCPUTime(GCTracer* tracer) : + _active(log_is_enabled(Info, gc, cpu) || + (tracer != nullptr && tracer->should_report_cpu_time_event())), _starting_user_time(0.0), _starting_system_time(0.0), - _starting_real_time(0.0) + _starting_real_time(0.0), + _tracer(tracer) { if (_active) { bool valid = os::getTimesSecs(&_starting_real_time, - &_starting_user_time, - &_starting_system_time); + &_starting_user_time, + &_starting_system_time); if (!valid) { log_warning(gc, cpu)("TraceCPUTime: os::getTimesSecs() returned invalid result"); _active = false; @@ -92,10 +95,13 @@ GCTraceCPUTime::~GCTraceCPUTime() { double real_time, user_time, system_time; bool valid = os::getTimesSecs(&real_time, &user_time, &system_time); if (valid) { - log_info(gc, cpu)("User=%3.2fs Sys=%3.2fs Real=%3.2fs", - user_time - _starting_user_time, - system_time - _starting_system_time, - real_time - _starting_real_time); + user_time -= _starting_user_time; + system_time -= _starting_system_time; + real_time -= _starting_real_time; + log_info(gc, cpu)("User=%3.2fs Sys=%3.2fs Real=%3.2fs", user_time, system_time, real_time); + if (_tracer != nullptr) { + _tracer->report_cpu_time_event(user_time, system_time, real_time); + } } else { log_warning(gc, cpu)("TraceCPUTime: os::getTimesSecs() returned invalid result"); } diff --git a/src/hotspot/share/gc/shared/gcTraceTime.hpp b/src/hotspot/share/gc/shared/gcTraceTime.hpp index fbd46b5393d..955f267ddef 100644 --- a/src/hotspot/share/gc/shared/gcTraceTime.hpp +++ b/src/hotspot/share/gc/shared/gcTraceTime.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, 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 @@ -32,13 +32,16 @@ #include "memory/allocation.hpp" #include "utilities/ticks.hpp" +class GCTracer; + class GCTraceCPUTime : public StackObj { bool _active; // true if times will be measured and printed double _starting_user_time; // user time at start of measurement double _starting_system_time; // system time at start of measurement double _starting_real_time; // real time at start of measurement - public: - GCTraceCPUTime(); + GCTracer* _tracer; +public: + GCTraceCPUTime(GCTracer* tracer); ~GCTraceCPUTime(); }; diff --git a/src/hotspot/share/gc/shared/genCollectedHeap.cpp b/src/hotspot/share/gc/shared/genCollectedHeap.cpp index 411c1dc06ba..12a8355547f 100644 --- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp +++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp @@ -31,6 +31,7 @@ #include "code/icBuffer.hpp" #include "compiler/oopMap.hpp" #include "gc/serial/defNewGeneration.hpp" +#include "gc/serial/genMarkSweep.hpp" #include "gc/shared/adaptiveSizePolicy.hpp" #include "gc/shared/cardTableBarrierSet.hpp" #include "gc/shared/cardTableRS.hpp" @@ -554,7 +555,7 @@ void GenCollectedHeap::do_collection(bool full, if (do_young_collection) { GCIdMark gc_id_mark; - GCTraceCPUTime tcpu; + GCTraceCPUTime tcpu(((DefNewGeneration*)_young_gen)->gc_tracer()); GCTraceTime(Info, gc) t("Pause Young", NULL, gc_cause(), true); print_heap_before_gc(); @@ -605,7 +606,7 @@ void GenCollectedHeap::do_collection(bool full, if (do_full_collection) { GCIdMark gc_id_mark; - GCTraceCPUTime tcpu; + GCTraceCPUTime tcpu(GenMarkSweep::gc_tracer()); GCTraceTime(Info, gc) t("Pause Full", NULL, gc_cause(), true); print_heap_before_gc(); diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp index ac13cf28608..3222a0262eb 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp @@ -1730,11 +1730,26 @@ bool ShenandoahBarrierC2Support::identical_backtoback_ifs(Node* n, PhaseIdealLoo return true; } +bool ShenandoahBarrierC2Support::merge_point_safe(Node* region) { + for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { + Node* n = region->fast_out(i); + if (n->is_LoadStore()) { + // Splitting a LoadStore node through phi, causes it to lose its SCMemProj: the split if code doesn't have support + // for a LoadStore at the region the if is split through because that's not expected to happen (LoadStore nodes + // should be between barrier nodes). It does however happen with Shenandoah though because barriers can get + // expanded around a LoadStore node. + return false; + } + } + return true; +} + + void ShenandoahBarrierC2Support::merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase) { assert(is_heap_stable_test(n), "no other tests"); if (identical_backtoback_ifs(n, phase)) { Node* n_ctrl = n->in(0); - if (phase->can_split_if(n_ctrl)) { + if (phase->can_split_if(n_ctrl) && merge_point_safe(n_ctrl)) { IfNode* dom_if = phase->idom(n_ctrl)->as_If(); if (is_heap_stable_test(n)) { Node* gc_state_load = n->in(1)->in(1)->in(1)->in(1); diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp index c9404af5ff8..df5fa55e58f 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp @@ -65,6 +65,7 @@ class ShenandoahBarrierC2Support : public AllStatic { static void test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase); static void move_gc_state_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase); static void merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase); + static bool merge_point_safe(Node* region); static bool identical_backtoback_ifs(Node *n, PhaseIdealLoop* phase); static void fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase); static IfNode* find_unswitching_candidate(const IdealLoopTree *loop, PhaseIdealLoop* phase); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 42d33910c70..67ea25d31fa 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -1702,7 +1702,7 @@ void ShenandoahHeap::prepare_update_heap_references(bool concurrent) { _update_refs_iterator.reset(); } -void ShenandoahHeap::set_gc_state_all_threads() { +void ShenandoahHeap::propagate_gc_state_to_java_threads() { assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at Shenandoah safepoint"); if (_gc_state_changed) { _gc_state_changed = false; @@ -1713,7 +1713,7 @@ void ShenandoahHeap::set_gc_state_all_threads() { } } -void ShenandoahHeap::set_gc_state_mask(uint mask, bool value) { +void ShenandoahHeap::set_gc_state(uint mask, bool value) { assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at Shenandoah safepoint"); _gc_state.set_cond(mask, value); _gc_state_changed = true; @@ -1721,13 +1721,13 @@ void ShenandoahHeap::set_gc_state_mask(uint mask, bool value) { void ShenandoahHeap::set_concurrent_mark_in_progress(bool in_progress) { assert(!has_forwarded_objects(), "Not expected before/after mark phase"); - set_gc_state_mask(MARKING, in_progress); + set_gc_state(MARKING, in_progress); ShenandoahBarrierSet::satb_mark_queue_set().set_active_all_threads(in_progress, !in_progress); } void ShenandoahHeap::set_evacuation_in_progress(bool in_progress) { assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only call this at safepoint"); - set_gc_state_mask(EVACUATION, in_progress); + set_gc_state(EVACUATION, in_progress); } void ShenandoahHeap::set_concurrent_strong_root_in_progress(bool in_progress) { @@ -1739,7 +1739,7 @@ void ShenandoahHeap::set_concurrent_strong_root_in_progress(bool in_progress) { } void ShenandoahHeap::set_concurrent_weak_root_in_progress(bool cond) { - set_gc_state_mask(WEAK_ROOTS, cond); + set_gc_state(WEAK_ROOTS, cond); } GCTracer* ShenandoahHeap::tracer() { @@ -1857,7 +1857,7 @@ void ShenandoahHeap::parallel_cleaning(bool full_gc) { } void ShenandoahHeap::set_has_forwarded_objects(bool cond) { - set_gc_state_mask(HAS_FORWARDED, cond); + set_gc_state(HAS_FORWARDED, cond); } void ShenandoahHeap::set_unload_classes(bool uc) { @@ -1900,7 +1900,7 @@ void ShenandoahHeap::set_full_gc_move_in_progress(bool in_progress) { } void ShenandoahHeap::set_update_refs_in_progress(bool in_progress) { - set_gc_state_mask(UPDATEREFS, in_progress); + set_gc_state(UPDATEREFS, in_progress); } void ShenandoahHeap::register_nmethod(nmethod* nm) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index bf2125b0e20..c7ba21e6e9f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -289,12 +289,19 @@ class ShenandoahHeap : public CollectedHeap { ShenandoahSharedFlag _progress_last_gc; ShenandoahSharedFlag _concurrent_strong_root_in_progress; - void set_gc_state_mask(uint mask, bool value); + // This updates the singlular, global gc state. This must happen on a safepoint. + void set_gc_state(uint mask, bool value); public: char gc_state() const; - void set_gc_state_all_threads(); - bool has_gc_state_changed() { return _gc_state_changed; } + + // This copies the global gc state into a thread local variable for java threads. + // It is primarily intended to support quick access at barriers. + void propagate_gc_state_to_java_threads(); + + // This is public to support assertions that the state hasn't been changed off of + // a safepoint and that any changes were propagated to java threads after the safepoint. + bool has_gc_state_changed() const { return _gc_state_changed; } void set_concurrent_mark_in_progress(bool in_progress); void set_evacuation_in_progress(bool in_progress); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp index e34073f9b8e..e45476c4a5b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp @@ -100,6 +100,7 @@ class ShenandoahThreadLocalData { } static char gc_state(Thread* thread) { + assert(thread->is_Java_thread(), "GC state is only synchronized to java threads"); return data(thread)->_gc_state; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp index 970f99ad0f5..eeeb1dcad19 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp @@ -62,41 +62,41 @@ void VM_ShenandoahReferenceOperation::doit_epilogue() { void VM_ShenandoahInitMark::doit() { ShenandoahGCPauseMark mark(_gc_id, "Init Mark", SvcGCMarker::CONCURRENT); _gc->entry_init_mark(); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); } void VM_ShenandoahFinalMarkStartEvac::doit() { ShenandoahGCPauseMark mark(_gc_id, "Final Mark", SvcGCMarker::CONCURRENT); _gc->entry_final_mark(); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); } void VM_ShenandoahFullGC::doit() { ShenandoahGCPauseMark mark(_gc_id, "Full GC", SvcGCMarker::FULL); _full_gc->entry_full(_gc_cause); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); } void VM_ShenandoahDegeneratedGC::doit() { ShenandoahGCPauseMark mark(_gc_id, "Degenerated GC", SvcGCMarker::CONCURRENT); _gc->entry_degenerated(); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); } void VM_ShenandoahInitUpdateRefs::doit() { ShenandoahGCPauseMark mark(_gc_id, "Init Update Refs", SvcGCMarker::CONCURRENT); _gc->entry_init_updaterefs(); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); } void VM_ShenandoahFinalUpdateRefs::doit() { ShenandoahGCPauseMark mark(_gc_id, "Final Update Refs", SvcGCMarker::CONCURRENT); _gc->entry_final_updaterefs(); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); } void VM_ShenandoahFinalRoots::doit() { ShenandoahGCPauseMark mark(_gc_id, "Final Roots", SvcGCMarker::CONCURRENT); _gc->entry_final_roots(); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp index 99be9bd0af6..16fcf4c6f3e 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp @@ -619,7 +619,7 @@ void ShenandoahVerifier::verify_at_safepoint(const char *label, guarantee(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "only when nothing else happens"); guarantee(ShenandoahVerify, "only when enabled, and bitmap is initialized in ShenandoahHeap::initialize"); - ShenandoahHeap::heap()->set_gc_state_all_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); // Avoid side-effect of changing workers' active thread count, but bypass concurrent/parallel protocol check ShenandoahPushWorkerScope verify_worker_scope(_heap->workers(), _heap->max_workers(), false /*bypass check*/); diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml index 1c1fe5d0657..5ebb5502b0b 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xml +++ b/src/hotspot/share/jfr/metadata/metadata.xml @@ -431,6 +431,14 @@ + + + + + + + diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp index 1422287506b..a95cccf1a5c 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp @@ -34,6 +34,7 @@ #include "jfr/utilities/jfrTime.hpp" #include "jfrfiles/jfrEventClasses.hpp" #include "logging/log.hpp" +#include "runtime/atomic.hpp" #include "runtime/frame.inline.hpp" #include "runtime/os.hpp" #include "runtime/semaphore.hpp" @@ -350,8 +351,8 @@ class JfrThreadSampler : public NonJavaThread { void run(); static Monitor* transition_block() { return JfrThreadSampler_lock; } static void on_javathread_suspend(JavaThread* thread); - int64_t get_java_period() const { return _java_period_millis; }; - int64_t get_native_period() const { return _native_period_millis; }; + int64_t get_java_period() const { return Atomic::load(&_java_period_millis); }; + int64_t get_native_period() const { return Atomic::load(&_native_period_millis); }; }; static void clear_transition_block(JavaThread* jt) { @@ -412,12 +413,12 @@ JfrThreadSampler::~JfrThreadSampler() { void JfrThreadSampler::set_java_period(int64_t period_millis) { assert(period_millis >= 0, "invariant"); - _java_period_millis = period_millis; + Atomic::store(&_java_period_millis, period_millis); } void JfrThreadSampler::set_native_period(int64_t period_millis) { assert(period_millis >= 0, "invariant"); - _native_period_millis = period_millis; + Atomic::store(&_native_period_millis, period_millis); } static inline bool is_released(JavaThread* jt) { @@ -496,8 +497,17 @@ void JfrThreadSampler::run() { last_native_ms = last_java_ms; } _sample.signal(); - const int64_t java_period_millis = _java_period_millis == 0 ? max_jlong : MAX2(_java_period_millis, 1); - const int64_t native_period_millis = _native_period_millis == 0 ? max_jlong : MAX2(_native_period_millis, 1); + + int64_t java_period_millis = get_java_period(); + java_period_millis = java_period_millis == 0 ? max_jlong : MAX2(java_period_millis, 1); + int64_t native_period_millis = get_native_period(); + native_period_millis = native_period_millis == 0 ? max_jlong : MAX2(native_period_millis, 1); + + // If both periods are max_jlong, it implies the sampler is in the process of + // disenrolling. Loop back for graceful disenroll by means of the semaphore. + if (java_period_millis == max_jlong && native_period_millis == max_jlong) { + continue; + } const int64_t now_ms = get_monotonic_ms(); @@ -516,7 +526,7 @@ void JfrThreadSampler::run() { const int64_t sleep_to_next = MIN2(next_j, next_n); if (sleep_to_next > 0) { - os::naked_short_sleep(sleep_to_next); + os::naked_sleep(sleep_to_next); } if ((next_j - sleep_to_next) <= 0) { diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp index a97f2fe8d02..53e166c0c69 100644 --- a/src/hotspot/share/oops/constantPool.cpp +++ b/src/hotspot/share/oops/constantPool.cpp @@ -767,13 +767,16 @@ void ConstantPool::resolve_string_constants_impl(const constantPoolHandle& this_ } } -static Symbol* exception_message(const constantPoolHandle& this_cp, int which, constantTag tag, oop pending_exception) { +static const char* exception_message(const constantPoolHandle& this_cp, int which, constantTag tag, oop pending_exception) { + // Note: caller needs ResourceMark + // Dig out the detailed message to reuse if possible - Symbol* message = java_lang_Throwable::detail_message(pending_exception); - if (message != NULL) { - return message; + const char* msg = java_lang_Throwable::message_as_utf8(pending_exception); + if (msg != nullptr) { + return msg; } + Symbol* message = nullptr; // Return specific message for the tag switch (tag.value()) { case JVM_CONSTANT_UnresolvedClass: @@ -796,49 +799,48 @@ static Symbol* exception_message(const constantPoolHandle& this_cp, int which, c ShouldNotReachHere(); } - return message; + return message != nullptr ? message->as_C_string() : nullptr; } -static void add_resolution_error(const constantPoolHandle& this_cp, int which, +static void add_resolution_error(JavaThread* current, const constantPoolHandle& this_cp, int which, constantTag tag, oop pending_exception) { + ResourceMark rm(current); Symbol* error = pending_exception->klass()->name(); oop cause = java_lang_Throwable::cause(pending_exception); // Also dig out the exception cause, if present. Symbol* cause_sym = NULL; - Symbol* cause_msg = NULL; + const char* cause_msg = nullptr; if (cause != NULL && cause != pending_exception) { cause_sym = cause->klass()->name(); - cause_msg = java_lang_Throwable::detail_message(cause); + cause_msg = java_lang_Throwable::message_as_utf8(cause); } - Symbol* message = exception_message(this_cp, which, tag, pending_exception); + const char* message = exception_message(this_cp, which, tag, pending_exception); SystemDictionary::add_resolution_error(this_cp, which, error, message, cause_sym, cause_msg); } void ConstantPool::throw_resolution_error(const constantPoolHandle& this_cp, int which, TRAPS) { ResourceMark rm(THREAD); - Symbol* message = NULL; + const char* message = NULL; Symbol* cause = NULL; - Symbol* cause_msg = NULL; + const char* cause_msg = NULL; Symbol* error = SystemDictionary::find_resolution_error(this_cp, which, &message, &cause, &cause_msg); assert(error != NULL, "checking"); - const char* cause_str = cause_msg != NULL ? cause_msg->as_C_string() : NULL; CLEAR_PENDING_EXCEPTION; if (message != NULL) { - char* msg = message->as_C_string(); if (cause != NULL) { - Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_str); - THROW_MSG_CAUSE(error, msg, h_cause); + Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_msg); + THROW_MSG_CAUSE(error, message, h_cause); } else { - THROW_MSG(error, msg); + THROW_MSG(error, message); } } else { if (cause != NULL) { - Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_str); + Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_msg); THROW_CAUSE(error, h_cause); } else { THROW(error); @@ -860,7 +862,7 @@ void ConstantPool::save_and_throw_exception(const constantPoolHandle& this_cp, i // and OutOfMemoryError, etc, or if the thread was hit by stop() // Needs clarification to section 5.4.3 of the VM spec (see 6308271) } else if (this_cp->tag_at(which).value() != error_tag) { - add_resolution_error(this_cp, which, tag, PENDING_EXCEPTION); + add_resolution_error(THREAD, this_cp, which, tag, PENDING_EXCEPTION); // CAS in the tag. If a thread beat us to registering this error that's fine. // If another thread resolved the reference, this is a race condition. This // thread may have had a security manager or something temporary. diff --git a/src/hotspot/share/oops/cpCache.cpp b/src/hotspot/share/oops/cpCache.cpp index 40ca7d7efc6..9fdf69e057d 100644 --- a/src/hotspot/share/oops/cpCache.cpp +++ b/src/hotspot/share/oops/cpCache.cpp @@ -497,9 +497,9 @@ bool ConstantPoolCacheEntry::save_and_throw_indy_exc( CLEAR_PENDING_EXCEPTION; return false; } - + ResourceMark rm(THREAD); Symbol* error = PENDING_EXCEPTION->klass()->name(); - Symbol* message = java_lang_Throwable::detail_message(PENDING_EXCEPTION); + const char* message = java_lang_Throwable::message_as_utf8(PENDING_EXCEPTION); SystemDictionary::add_resolution_error(cpool, index, error, message); set_indy_resolution_failed(); diff --git a/src/hotspot/share/opto/castnode.cpp b/src/hotspot/share/opto/castnode.cpp index 5e79f32cc4c..242c7be8c15 100644 --- a/src/hotspot/share/opto/castnode.cpp +++ b/src/hotspot/share/opto/castnode.cpp @@ -195,66 +195,6 @@ void ConstraintCastNode::dump_spec(outputStream *st) const { const Type* CastIINode::Value(PhaseGVN* phase) const { const Type *res = ConstraintCastNode::Value(phase); - // Try to improve the type of the CastII if we recognize a CmpI/If - // pattern. - if (_dependency != RegularDependency) { - if (in(0) != nullptr && in(0)->in(0) != nullptr && in(0)->in(0)->is_If()) { - assert(in(0)->is_IfFalse() || in(0)->is_IfTrue(), "should be If proj"); - Node* proj = in(0); - if (proj->in(0)->in(1)->is_Bool()) { - Node* b = proj->in(0)->in(1); - if (b->in(1)->Opcode() == Op_CmpI) { - Node* cmp = b->in(1); - if (cmp->in(1) == in(1) && phase->type(cmp->in(2))->isa_int()) { - const TypeInt* in2_t = phase->type(cmp->in(2))->is_int(); - const Type* t = TypeInt::INT; - BoolTest test = b->as_Bool()->_test; - if (proj->is_IfFalse()) { - test = test.negate(); - } - BoolTest::mask m = test._test; - jlong lo_long = min_jint; - jlong hi_long = max_jint; - if (m == BoolTest::le || m == BoolTest::lt) { - hi_long = in2_t->_hi; - if (m == BoolTest::lt) { - hi_long -= 1; - } - } else if (m == BoolTest::ge || m == BoolTest::gt) { - lo_long = in2_t->_lo; - if (m == BoolTest::gt) { - lo_long += 1; - } - } else if (m == BoolTest::eq) { - lo_long = in2_t->_lo; - hi_long = in2_t->_hi; - } else if (m == BoolTest::ne) { - // can't do any better - } else { - stringStream ss; - test.dump_on(&ss); - fatal("unexpected comparison %s", ss.as_string()); - } - int lo_int = (int)lo_long; - int hi_int = (int)hi_long; - - if (lo_long != (jlong)lo_int) { - lo_int = min_jint; - } - if (hi_long != (jlong)hi_int) { - hi_int = max_jint; - } - - t = TypeInt::make(lo_int, hi_int, Type::WidenMax); - - res = res->filter_speculative(t); - - return res; - } - } - } - } - } return res; } diff --git a/src/hotspot/share/opto/chaitin.hpp b/src/hotspot/share/opto/chaitin.hpp index 650190571d9..612b62186b9 100644 --- a/src/hotspot/share/opto/chaitin.hpp +++ b/src/hotspot/share/opto/chaitin.hpp @@ -291,7 +291,7 @@ class PhaseIFG : public Phase { #endif //--------------- Live Range Accessors - LRG &lrgs(uint idx) const { assert(idx < _maxlrg, "oob"); return _lrgs[idx]; } + LRG &lrgs(uint idx) const { assert(idx < _maxlrg, "oob: index %u not smaller than %u", idx, _maxlrg); return _lrgs[idx]; } // Compute and set effective degree. Might be folded into SquareUp(). void Compute_Effective_Degree(); diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp index 2a1d1694c27..880dbff8307 100644 --- a/src/hotspot/share/opto/loopopts.cpp +++ b/src/hotspot/share/opto/loopopts.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, 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 @@ -497,8 +497,8 @@ Node *PhaseIdealLoop::remix_address_expressions( Node *n ) { } // Replace ((I1 +p V) +p I2) with ((I1 +p I2) +p V), - // but not if I2 is a constant. - if( n_op == Op_AddP ) { + // but not if I2 is a constant. Skip for irreducible loops. + if (n_op == Op_AddP && n_loop->_head->is_Loop()) { if( n2_loop == n_loop && n3_loop != n_loop ) { if( n->in(2)->Opcode() == Op_AddP && !n->in(3)->is_Con() ) { Node *n22_ctrl = get_ctrl(n->in(2)->in(2)); diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index f81e80fec0e..074b129b059 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -3353,6 +3353,7 @@ Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) { my_mem = load_node; } else { assert(my_mem->unique_out() == this, "sanity"); + assert(!trailing_load_store(), "load store node can't be eliminated"); del_req(Precedent); phase->is_IterGVN()->_worklist.push(my_mem); // remove dead node later my_mem = nullptr; diff --git a/src/hotspot/share/prims/forte.cpp b/src/hotspot/share/prims/forte.cpp index ac71146b5d4..31be7b23ae7 100644 --- a/src/hotspot/share/prims/forte.cpp +++ b/src/hotspot/share/prims/forte.cpp @@ -595,9 +595,6 @@ void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) { return; } - // !important! make sure all to call thread->set_in_asgct(false) before every return - thread->set_in_asgct(true); - // signify to other code in the VM that we're in ASGCT ThreadInAsgct tia(thread); @@ -658,7 +655,6 @@ void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) { trace->num_frames = ticks_unknown_state; // -7 break; } - thread->set_in_asgct(false); } diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp index c8357b1927a..46a90b678c3 100644 --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, 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 @@ -1476,6 +1476,10 @@ void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableAr reassign_object_array_elements(fr, reg_map, sv, (objArrayOop) obj()); } } + // These objects may escape when we return to Interpreter after deoptimization. + // We need barrier so that stores that initialize these objects can't be reordered + // with subsequent stores that make these objects accessible by other threads. + OrderAccess::storestore(); } diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index e8540f682da..10909a25356 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, 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 @@ -723,6 +723,10 @@ const intx ObjectAlignmentInBytes = 8; "at one time (minimum is 1024).") \ range(1024, max_jint) \ \ + product(intx, MonitorUnlinkBatch, 500, DIAGNOSTIC, \ + "The maximum number of monitors to unlink in one batch. ") \ + range(1, max_jint) \ + \ product(intx, MonitorUsedDeflationThreshold, 90, DIAGNOSTIC, \ "Percentage of used monitors before triggering deflation (0 is " \ "off). The check is performed on GuaranteedSafepointInterval, " \ @@ -2097,7 +2101,7 @@ const intx ObjectAlignmentInBytes = 8; develop(bool, TraceOptimizedUpcallStubs, false, \ "Trace optimized upcall stub generation") \ \ - product(uint, TrimNativeHeapInterval, 0, EXPERIMENTAL, \ + product(uint, TrimNativeHeapInterval, 0, \ "Interval, in ms, at which the JVM will trim the native heap if " \ "the platform supports that. Lower values will reclaim memory " \ "more eagerly at the cost of higher overhead. A value of 0 " \ diff --git a/src/hotspot/share/runtime/interfaceSupport.inline.hpp b/src/hotspot/share/runtime/interfaceSupport.inline.hpp index ba246a46d8f..3cae644d63a 100644 --- a/src/hotspot/share/runtime/interfaceSupport.inline.hpp +++ b/src/hotspot/share/runtime/interfaceSupport.inline.hpp @@ -464,6 +464,7 @@ extern "C" { \ #define JVM_ENTRY_FROM_LEAF(env, result_type, header) \ { { \ JavaThread* thread=JavaThread::thread_from_jni_environment(env); \ + MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ ThreadInVMfromNative __tiv(thread); \ debug_only(VMNativeEntryWrapper __vew;) \ VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread) diff --git a/src/hotspot/share/runtime/synchronizer.cpp b/src/hotspot/share/runtime/synchronizer.cpp index 5be659ebdcf..6f6dba9af51 100644 --- a/src/hotspot/share/runtime/synchronizer.cpp +++ b/src/hotspot/share/runtime/synchronizer.cpp @@ -80,44 +80,68 @@ size_t MonitorList::max() const { return Atomic::load(&_max); } -// Walk the in-use list and unlink (at most MonitorDeflationMax) deflated -// ObjectMonitors. Returns the number of unlinked ObjectMonitors. +// Walk the in-use list and unlink deflated ObjectMonitors. +// Returns the number of unlinked ObjectMonitors. size_t MonitorList::unlink_deflated(Thread* current, LogStream* ls, elapsedTimer* timer_p, + size_t deflated_count, GrowableArray* unlinked_list) { size_t unlinked_count = 0; - ObjectMonitor* prev = NULL; - ObjectMonitor* head = Atomic::load_acquire(&_head); - ObjectMonitor* m = head; - // The in-use list head can be NULL during the final audit. - while (m != NULL) { + ObjectMonitor* prev = nullptr; + ObjectMonitor* m = Atomic::load_acquire(&_head); + + // The in-use list head can be null during the final audit. + while (m != nullptr) { if (m->is_being_async_deflated()) { - // Find next live ObjectMonitor. + // Find next live ObjectMonitor. Batch up the unlinkable monitors, so we can + // modify the list once per batch. The batch starts at "m". + size_t unlinked_batch = 0; ObjectMonitor* next = m; + // Look for at most MonitorUnlinkBatch monitors, or the number of + // deflated and not unlinked monitors, whatever comes first. + assert(deflated_count >= unlinked_count, "Sanity: underflow"); + size_t unlinked_batch_limit = MIN2(deflated_count - unlinked_count, MonitorUnlinkBatch); do { ObjectMonitor* next_next = next->next_om(); - unlinked_count++; + unlinked_batch++; unlinked_list->append(next); next = next_next; - if (unlinked_count >= (size_t)MonitorDeflationMax) { - // Reached the max so bail out on the gathering loop. + if (unlinked_batch >= unlinked_batch_limit) { + // Reached the max batch, so bail out of the gathering loop. + break; + } + if (prev == nullptr && Atomic::load(&_head) != m) { + // Current batch used to be at head, but it is not at head anymore. + // Bail out and figure out where we currently are. This avoids long + // walks searching for new prev during unlink under heavy list inserts. break; } - } while (next != NULL && next->is_being_async_deflated()); - if (prev == NULL) { - ObjectMonitor* prev_head = Atomic::cmpxchg(&_head, head, next); - if (prev_head != head) { - // Find new prev ObjectMonitor that just got inserted. + } while (next != nullptr && next->is_being_async_deflated()); + + // Unlink the found batch. + if (prev == nullptr) { + // The current batch is the first batch, so there is a chance that it starts at head. + // Optimistically assume no inserts happened, and try to unlink the entire batch from the head. + ObjectMonitor* prev_head = Atomic::cmpxchg(&_head, m, next); + if (prev_head != m) { + // Something must have updated the head. Figure out the actual prev for this batch. for (ObjectMonitor* n = prev_head; n != m; n = n->next_om()) { prev = n; } + assert(prev != nullptr, "Should have found the prev for the current batch"); prev->set_next_om(next); } } else { + // The current batch is preceded by another batch. This guarantees the current batch + // does not start at head. Unlink the entire current batch without updating the head. + assert(Atomic::load(&_head) != m, "Sanity"); prev->set_next_om(next); } - if (unlinked_count >= (size_t)MonitorDeflationMax) { - // Reached the max so bail out on the searching loop. + + unlinked_count += unlinked_batch; + if (unlinked_count >= deflated_count) { + // Reached the max so bail out of the searching loop. + // There should be no more deflated monitors left. break; } m = next; @@ -133,6 +157,20 @@ size_t MonitorList::unlink_deflated(Thread* current, LogStream* ls, ls, timer_p); } } + +#ifdef ASSERT + // Invariant: the code above should unlink all deflated monitors. + // The code that runs after this unlinking does not expect deflated monitors. + // Notably, attempting to deflate the already deflated monitor would break. + { + ObjectMonitor* m = Atomic::load_acquire(&_head); + while (m != nullptr) { + assert(!m->is_being_async_deflated(), "All deflated monitors should be unlinked"); + m = m->next_om(); + } + } +#endif + Atomic::sub(&_count, unlinked_count); return unlinked_count; } @@ -1520,6 +1558,7 @@ size_t ObjectSynchronizer::deflate_idle_monitors() { ResourceMark rm; GrowableArray delete_list((int)deflated_count); size_t unlinked_count = _in_use_list.unlink_deflated(current, ls, &timer, + deflated_count, &delete_list); if (current->is_Java_thread()) { if (ls != NULL) { diff --git a/src/hotspot/share/runtime/synchronizer.hpp b/src/hotspot/share/runtime/synchronizer.hpp index 5a331e306ee..629a009e038 100644 --- a/src/hotspot/share/runtime/synchronizer.hpp +++ b/src/hotspot/share/runtime/synchronizer.hpp @@ -46,6 +46,7 @@ class MonitorList { public: void add(ObjectMonitor* monitor); size_t unlink_deflated(Thread* current, LogStream* ls, elapsedTimer* timer_p, + size_t deflated_count, GrowableArray* unlinked_list); size_t count() const; size_t max() const; diff --git a/src/hotspot/share/utilities/events.cpp b/src/hotspot/share/utilities/events.cpp index f4b7d74ee14..100acb3e90f 100644 --- a/src/hotspot/share/utilities/events.cpp +++ b/src/hotspot/share/utilities/events.cpp @@ -39,6 +39,7 @@ StringEventLog* Events::_vm_operations = NULL; ExceptionsEventLog* Events::_exceptions = NULL; StringEventLog* Events::_redefinitions = NULL; UnloadingEventLog* Events::_class_unloading = NULL; +StringEventLog* Events::_class_loading = NULL; StringEventLog* Events::_deopt_messages = NULL; StringEventLog* Events::_dll_messages = NULL; @@ -97,6 +98,7 @@ void Events::init() { _exceptions = new ExceptionsEventLog("Internal exceptions", "exc"); _redefinitions = new StringEventLog("Classes redefined", "redef"); _class_unloading = new UnloadingEventLog("Classes unloaded", "unload"); + _class_loading = new StringEventLog("Classes loaded", "load"); _deopt_messages = new StringEventLog("Deoptimization events", "deopt"); _dll_messages = new StringEventLog("Dll operation events", "dll"); } diff --git a/src/hotspot/share/utilities/events.hpp b/src/hotspot/share/utilities/events.hpp index 6f3dadde281..8ddf466f206 100644 --- a/src/hotspot/share/utilities/events.hpp +++ b/src/hotspot/share/utilities/events.hpp @@ -238,6 +238,9 @@ class Events : AllStatic { // Class unloading events static UnloadingEventLog* _class_unloading; + + // Class loading events + static StringEventLog* _class_loading; public: // Print all event logs; limit number of events per event log to be printed with max @@ -263,6 +266,8 @@ class Events : AllStatic { static void log_class_unloading(Thread* thread, InstanceKlass* ik); + static void log_class_loading(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + static void log_deopt_message(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); static void log_dll_message(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3); @@ -319,6 +324,15 @@ inline void Events::log_class_unloading(Thread* thread, InstanceKlass* ik) { } } +inline void Events::log_class_loading(Thread* thread, const char* format, ...) { + if (LogEvents && _class_loading != NULL) { + va_list ap; + va_start(ap, format); + _class_loading->logv(thread, format, ap); + va_end(ap); + } +} + inline void Events::log_deopt_message(Thread* thread, const char* format, ...) { if (LogEvents && _deopt_messages != NULL) { va_list ap; @@ -487,4 +501,7 @@ typedef EventMarkWithLogFunction EventMark; // These end up in the vm_operation log. typedef EventMarkWithLogFunction EventMarkVMOperation; +// These end up in the class loading log. +typedef EventMarkWithLogFunction EventMarkClassLoading; + #endif // SHARE_UTILITIES_EVENTS_HPP diff --git a/src/hotspot/share/utilities/exceptions.cpp b/src/hotspot/share/utilities/exceptions.cpp index bd95b8306be..d65f5bcfafd 100644 --- a/src/hotspot/share/utilities/exceptions.cpp +++ b/src/hotspot/share/utilities/exceptions.cpp @@ -563,11 +563,11 @@ void Exceptions::debug_check_abort_helper(Handle exception, const char* message) // for logging exceptions void Exceptions::log_exception(Handle exception, const char* message) { ResourceMark rm; - Symbol* detail_message = java_lang_Throwable::detail_message(exception()); - if (detail_message != NULL) { + const char* detail_message = java_lang_Throwable::message_as_utf8(exception()); + if (detail_message != nullptr) { log_info(exceptions)("Exception <%s: %s>\n thrown in %s", exception->print_value_string(), - detail_message->as_C_string(), + detail_message, message); } else { log_info(exceptions)("Exception <%s>\n thrown in %s", diff --git a/src/java.base/linux/classes/jdk/internal/platform/CgroupMetrics.java b/src/java.base/linux/classes/jdk/internal/platform/CgroupMetrics.java index 8f0ac0102b0..8797711bf4b 100644 --- a/src/java.base/linux/classes/jdk/internal/platform/CgroupMetrics.java +++ b/src/java.base/linux/classes/jdk/internal/platform/CgroupMetrics.java @@ -122,9 +122,11 @@ public long getMemoryFailCount() { @Override public long getMemoryLimit() { long subsMem = subsystem.getMemoryLimit(); + long systemTotal = getTotalMemorySize0(); + assert(systemTotal > 0); // Catch the cgroup memory limit exceeding host physical memory. // Treat this as unlimited. - if (subsMem >= getTotalMemorySize0()) { + if (subsMem >= systemTotal) { return CgroupSubsystem.LONG_RETVAL_UNLIMITED; } return subsMem; @@ -142,7 +144,15 @@ public long getTcpMemoryUsage() { @Override public long getMemoryAndSwapLimit() { - return subsystem.getMemoryAndSwapLimit(); + long totalSystemMemSwap = getTotalMemorySize0() + getTotalSwapSize0(); + assert(totalSystemMemSwap > 0); + // Catch the cgroup memory and swap limit exceeding host physical swap + // and memory. Treat this case as unlimited. + long subsSwapMem = subsystem.getMemoryAndSwapLimit(); + if (subsSwapMem >= totalSystemMemSwap) { + return CgroupSubsystem.LONG_RETVAL_UNLIMITED; + } + return subsSwapMem; } @Override @@ -185,5 +195,6 @@ public static Metrics getInstance() { private static native boolean isUseContainerSupport(); private static native long getTotalMemorySize0(); + private static native long getTotalSwapSize0(); } diff --git a/src/java.base/linux/native/libjava/CgroupMetrics.c b/src/java.base/linux/native/libjava/CgroupMetrics.c index d9bb7369f1d..a5e41167bc3 100644 --- a/src/java.base/linux/native/libjava/CgroupMetrics.c +++ b/src/java.base/linux/native/libjava/CgroupMetrics.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Red Hat, Inc. + * Copyright (c) 2020, 2024, Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ * questions. */ #include +#include #include "jni.h" #include "jvm.h" @@ -43,3 +44,15 @@ Java_jdk_internal_platform_CgroupMetrics_getTotalMemorySize0 jlong page_size = sysconf(_SC_PAGESIZE); return pages * page_size; } + +JNIEXPORT jlong JNICALL +Java_jdk_internal_platform_CgroupMetrics_getTotalSwapSize0 + (JNIEnv *env, jclass ignored) +{ + struct sysinfo si; + int retval = sysinfo(&si); + if (retval < 0) { + return 0; // syinfo failed, treat as no swap + } + return (jlong)(si.totalswap * si.mem_unit); +} diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index de62d82a331..538950055a0 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -563,9 +563,9 @@ public String(byte[] bytes, int offset, int length, Charset charset) { } } if (dp == 0 || dst == null) { - dst = new byte[length << 1]; + dst = StringUTF16.newBytesFor(length); } else { - byte[] buf = new byte[length << 1]; + byte[] buf = StringUTF16.newBytesFor(length); StringLatin1.inflate(dst, 0, buf, 0, dp); dst = buf; } @@ -589,7 +589,7 @@ public String(byte[] bytes, int offset, int length, Charset charset) { this.value = Arrays.copyOfRange(bytes, offset, offset + length); this.coder = LATIN1; } else { - byte[] dst = new byte[length << 1]; + byte[] dst = StringUTF16.newBytesFor(length); int dp = 0; while (dp < length) { int b = bytes[offset++]; @@ -723,9 +723,9 @@ static String newStringUTF8NoRepl(byte[] bytes, int offset, int length) { } } if (dp == 0 || dst == null) { - dst = new byte[length << 1]; + dst = StringUTF16.newBytesFor(length); } else { - byte[] buf = new byte[length << 1]; + byte[] buf = StringUTF16.newBytesFor(length); StringLatin1.inflate(dst, 0, buf, 0, dp); dst = buf; } @@ -1267,7 +1267,7 @@ private static byte[] encodeUTF8(byte coder, byte[] val, boolean doReplace) { return Arrays.copyOf(val, val.length); int dp = 0; - byte[] dst = new byte[val.length << 1]; + byte[] dst = StringUTF16.newBytesFor(val.length); for (byte c : val) { if (c < 0) { dst[dp++] = (byte) (0xc0 | ((c & 0xff) >> 6)); diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java index 4dd2b1fce7e..26ed3d83b4d 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java @@ -28,9 +28,11 @@ import java.lang.reflect.*; import java.security.AccessController; import java.security.PrivilegedAction; + +import jdk.internal.access.JavaLangReflectAccess; +import jdk.internal.access.SharedSecrets; import sun.invoke.WrapperInstance; import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; @@ -184,8 +186,6 @@ public static T asInterfaceInstance(final Class intfc, final MethodHandle checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class)); vaTargets[i] = checkTarget.asSpreader(Object[].class, smMT.parameterCount()); } - final ConcurrentHashMap defaultMethodMap = - hasDefaultMethods(intfc) ? new ConcurrentHashMap<>() : null; final InvocationHandler ih = new InvocationHandler() { private Object getArg(String name) { if ((Object)name == "getWrapperInstanceTarget") return target; @@ -202,7 +202,8 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl if (isObjectMethod(method)) return callObjectMethod(proxy, method, args); if (isDefaultMethod(method)) { - return callDefaultMethod(defaultMethodMap, proxy, intfc, method, args); + // no additional access check is performed + return JLRA.invokeDefault(proxy, method, args, null); } throw newInternalError("bad proxy method: "+method); } @@ -320,37 +321,5 @@ private static boolean isDefaultMethod(Method m) { return !Modifier.isAbstract(m.getModifiers()); } - private static boolean hasDefaultMethods(Class intfc) { - for (Method m : intfc.getMethods()) { - if (!isObjectMethod(m) && - !Modifier.isAbstract(m.getModifiers())) { - return true; - } - } - return false; - } - - private static Object callDefaultMethod(ConcurrentHashMap defaultMethodMap, - Object self, Class intfc, Method m, Object[] args) throws Throwable { - assert(isDefaultMethod(m) && !isObjectMethod(m)) : m; - - // Lazily compute the associated method handle from the method - MethodHandle dmh = defaultMethodMap.computeIfAbsent(m, mk -> { - try { - // Look up the default method for special invocation thereby - // avoiding recursive invocation back to the proxy - MethodHandle mh = MethodHandles.Lookup.IMPL_LOOKUP.findSpecial( - intfc, mk.getName(), - MethodType.methodType(mk.getReturnType(), mk.getParameterTypes()), - self.getClass()); - return mh.asSpreader(Object[].class, mk.getParameterCount()); - } catch (NoSuchMethodException | IllegalAccessException e) { - // The method is known to exist and should be accessible, this - // method would not be called unless the invokeinterface to the - // default (public) method passed access control checks - throw new InternalError(e); - } - }); - return dmh.invoke(self, args); - } + private static final JavaLangReflectAccess JLRA = SharedSecrets.getJavaLangReflectAccess(); } diff --git a/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java b/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java index 39f68ac953b..9353c515367 100644 --- a/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java +++ b/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java @@ -2553,7 +2553,7 @@ private static String toString(Set mods, String what) { private static int modsHashCode(Iterable> enums) { int h = 0; for (Enum e : enums) { - h = h * 43 + Objects.hashCode(e.name()); + h += e.name().hashCode(); } return h; } diff --git a/src/java.base/share/classes/java/lang/reflect/InvocationHandler.java b/src/java.base/share/classes/java/lang/reflect/InvocationHandler.java index 4ca59906367..d5d00f34c86 100644 --- a/src/java.base/share/classes/java/lang/reflect/InvocationHandler.java +++ b/src/java.base/share/classes/java/lang/reflect/InvocationHandler.java @@ -28,7 +28,6 @@ import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; -import java.lang.invoke.MethodHandle; import java.util.Objects; /** @@ -262,33 +261,6 @@ public static Object invokeDefault(Object proxy, Method method, Object... args) throws Throwable { Objects.requireNonNull(proxy); Objects.requireNonNull(method); - - // verify that the object is actually a proxy instance - if (!Proxy.isProxyClass(proxy.getClass())) { - throw new IllegalArgumentException("'proxy' is not a proxy instance"); - } - if (!method.isDefault()) { - throw new IllegalArgumentException("\"" + method + "\" is not a default method"); - } - @SuppressWarnings("unchecked") - Class proxyClass = (Class)proxy.getClass(); - - Class intf = method.getDeclaringClass(); - // access check on the default method - method.checkAccess(Reflection.getCallerClass(), intf, proxyClass, method.getModifiers()); - - MethodHandle mh = Proxy.defaultMethodHandle(proxyClass, method); - // invoke the super method - try { - // the args array can be null if the number of formal parameters required by - // the method is zero (consistent with Method::invoke) - Object[] params = args != null ? args : Proxy.EMPTY_ARGS; - return mh.invokeExact(proxy, params); - } catch (ClassCastException | NullPointerException e) { - throw new IllegalArgumentException(e.getMessage(), e); - } catch (Proxy.InvocationException e) { - // unwrap and throw the exception thrown by the default method - throw e.getCause(); - } + return Proxy.invokeDefault(proxy, method, args, Reflection.getCallerClass()); } } diff --git a/src/java.base/share/classes/java/lang/reflect/Proxy.java b/src/java.base/share/classes/java/lang/reflect/Proxy.java index a56f2ddef9d..47f325e8e04 100644 --- a/src/java.base/share/classes/java/lang/reflect/Proxy.java +++ b/src/java.base/share/classes/java/lang/reflect/Proxy.java @@ -1314,6 +1314,46 @@ public MethodHandles.Lookup run() { }); } + /* + * Invoke the default method of the given proxy with an explicit caller class. + * + * @throws IllegalAccessException if the proxy interface is inaccessible to the caller + * if caller is non-null + */ + static Object invokeDefault(Object proxy, Method method, Object[] args, Class caller) + throws Throwable { + // verify that the object is actually a proxy instance + if (!Proxy.isProxyClass(proxy.getClass())) { + throw new IllegalArgumentException("'proxy' is not a proxy instance"); + } + if (!method.isDefault()) { + throw new IllegalArgumentException("\"" + method + "\" is not a default method"); + } + @SuppressWarnings("unchecked") + Class proxyClass = (Class)proxy.getClass(); + + // skip access check if caller is null + if (caller != null) { + Class intf = method.getDeclaringClass(); + // access check on the default method + method.checkAccess(caller, intf, proxyClass, method.getModifiers()); + } + + MethodHandle mh = Proxy.defaultMethodHandle(proxyClass, method); + // invoke the super method + try { + // the args array can be null if the number of formal parameters required by + // the method is zero (consistent with Method::invoke) + Object[] params = args != null ? args : Proxy.EMPTY_ARGS; + return mh.invokeExact(proxy, params); + } catch (ClassCastException | NullPointerException e) { + throw new IllegalArgumentException(e.getMessage(), e); + } catch (Proxy.InvocationException e) { + // unwrap and throw the exception thrown by the default method + throw e.getCause(); + } + } + /** * Internal exception type to wrap the exception thrown by the default method * so that it can distinguish CCE and NPE thrown due to the arguments diff --git a/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java b/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java index 6ac890156b0..fa5a5d453ec 100644 --- a/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java +++ b/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java @@ -127,4 +127,9 @@ public T newInstance(Constructor ctor, Object[] args, Class caller) { return ctor.newInstanceWithCaller(args, true, caller); } + + public Object invokeDefault(Object proxy, Method method, Object[] args, Class caller) + throws Throwable { + return Proxy.invokeDefault(proxy, method, args, caller); + } } diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java index d10ad7f60a7..02946e885d6 100644 --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -33,7 +33,6 @@ import java.io.RandomAccessFile; import java.io.UncheckedIOException; import java.lang.ref.Cleaner.Cleanable; -import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.file.InvalidPathException; import java.nio.file.attribute.BasicFileAttributes; @@ -1419,14 +1418,19 @@ public boolean equals(Object obj) { } } private static final HashMap files = new HashMap<>(); - + /** + * Use the platform's default file system to avoid + * issues when the VM is configured to use a custom file system provider. + */ + private static final java.nio.file.FileSystem builtInFS = + DefaultFileSystemProvider.theFileSystem(); static Source get(File file, boolean toDelete, ZipCoder zc) throws IOException { final Key key; try { key = new Key(file, - Files.readAttributes(file.toPath(), BasicFileAttributes.class), - zc); + Files.readAttributes(builtInFS.getPath(file.getPath()), + BasicFileAttributes.class), zc); } catch (InvalidPathException ipe) { throw new IOException(ipe); } diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java index 4082fae336f..9e3ce846f02 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java @@ -102,4 +102,11 @@ public void setConstructorAccessor(Constructor c, /** Returns a new instance created by the given constructor with access check */ public T newInstance(Constructor ctor, Object[] args, Class caller) throws IllegalAccessException, InstantiationException, InvocationTargetException; + + /** Invokes the given default method if the method's declaring interface is + * accessible to the given caller. Otherwise, IllegalAccessException will + * be thrown. If the caller is null, no access check is performed. + */ + public Object invokeDefault(Object proxy, Method method, Object[] args, Class caller) + throws Throwable; } diff --git a/src/java.base/share/classes/jdk/internal/event/EventHelper.java b/src/java.base/share/classes/jdk/internal/event/EventHelper.java index 40f34f7787d..16bc9d37639 100644 --- a/src/java.base/share/classes/jdk/internal/event/EventHelper.java +++ b/src/java.base/share/classes/jdk/internal/event/EventHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, 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 @@ import jdk.internal.access.JavaUtilJarAccess; import jdk.internal.access.SharedSecrets; +import jdk.internal.misc.ThreadTracker; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; @@ -133,6 +134,18 @@ private static String getDurationString(Instant start) { } } + private static class ThreadTrackHolder { + static final ThreadTracker TRACKER = new ThreadTracker(); + } + + private static Object tryBeginLookup() { + return ThreadTrackHolder.TRACKER.tryBegin(); + } + + private static void endLookup(Object key) { + ThreadTrackHolder.TRACKER.end(key); + } + /** * Helper to determine if security events are being logged * at a preconfigured logging level. The configuration value @@ -141,14 +154,20 @@ private static String getDurationString(Instant start) { * @return boolean indicating whether an event should be logged */ public static boolean isLoggingSecurity() { - // Avoid a bootstrap issue where the commitEvent attempts to - // trigger early loading of System Logger but where - // the verification process still has JarFiles locked - if (securityLogger == null && !JUJA.isInitializing()) { - LOGGER_HANDLE.compareAndSet( null, System.getLogger(SECURITY_LOGGER_NAME)); - loggingSecurity = securityLogger.isLoggable(LOG_LEVEL); + Object key; + // Avoid bootstrap issues where + // * commitEvent triggers early loading of System Logger but where + // the verification process still has JarFiles locked + // * the loading of the logging libraries involves recursive + // calls to security libraries triggering recursion + if (securityLogger == null && !JUJA.isInitializing() && (key = tryBeginLookup()) != null) { + try { + LOGGER_HANDLE.compareAndSet(null, System.getLogger(SECURITY_LOGGER_NAME)); + loggingSecurity = securityLogger.isLoggable(LOG_LEVEL); + } finally { + endLookup(key); + } } return loggingSecurity; } - } diff --git a/src/java.base/share/classes/jdk/internal/misc/ThreadTracker.java b/src/java.base/share/classes/jdk/internal/misc/ThreadTracker.java new file mode 100644 index 00000000000..e8048e50818 --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/misc/ThreadTracker.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2021, 2022, 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 jdk.internal.misc; + +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Tracks threads to help detect reentrancy without using ThreadLocal variables. + * A thread invokes the {@code begin} or {@code tryBegin} methods at the start + * of a block, and the {@code end} method at the end of a block. + */ +public class ThreadTracker { + + /** + * A reference to a Thread that is suitable for use as a key in a collection. + * The hashCode/equals methods do not invoke the Thread hashCode/equals method + * as they may run arbitrary code and/or leak references to Thread objects. + */ + private record ThreadRef(Thread thread) { + @Override + public int hashCode() { + return Long.hashCode(thread.getId()); + } + @Override + public boolean equals(Object obj) { + return (obj instanceof ThreadRef other) + && this.thread == other.thread; + } + } + + private final Set threads = ConcurrentHashMap.newKeySet(); + + /** + * Adds the current thread to thread set if not already in the set. + * Returns a key to remove the thread or {@code null} if already in the set. + */ + public Object tryBegin() { + var threadRef = new ThreadRef(Thread.currentThread()); + return threads.add(threadRef) ? threadRef : null; + } + + /** + * Adds the current thread to thread set if not already in the set. + * Returns a key to remove the thread. + */ + public Object begin() { + var threadRef = new ThreadRef(Thread.currentThread()); + boolean added = threads.add(threadRef); + assert added; + return threadRef; + } + + /** + * Removes the thread identified by the key from the thread set. + */ + public void end(Object key) { + var threadRef = (ThreadRef) key; + assert threadRef.thread() == Thread.currentThread(); + boolean removed = threads.remove(threadRef); + assert removed; + } + + /** + * Returns true if the given thread is tracked. + */ + public boolean contains(Thread thread) { + var threadRef = new ThreadRef(thread); + return threads.contains(threadRef); + } +} diff --git a/src/java.base/share/classes/sun/launcher/LauncherHelper.java b/src/java.base/share/classes/sun/launcher/LauncherHelper.java index 4154f7a5d66..43a98a86869 100644 --- a/src/java.base/share/classes/sun/launcher/LauncherHelper.java +++ b/src/java.base/share/classes/sun/launcher/LauncherHelper.java @@ -169,6 +169,10 @@ static void showSettings(boolean printToStderr, String optionFlag, case "locale": printLocale(); break; + case "security": + var opt = opts.length > 2 ? opts[2].trim() : "all"; + SecuritySettings.printSecuritySettings(opt, ostream); + break; case "system": if (System.getProperty("os.name").contains("Linux")) { printSystemMetrics(); @@ -178,6 +182,7 @@ static void showSettings(boolean printToStderr, String optionFlag, printVmSettings(initialHeapSize, maxHeapSize, stackSize); printProperties(); printLocale(); + SecuritySettings.printSecuritySummarySettings(ostream); if (System.getProperty("os.name").contains("Linux")) { printSystemMetrics(); } @@ -315,9 +320,10 @@ private static void printLocales() { ostream.print(INDENT + INDENT); } } + ostream.println(); } - public static void printSystemMetrics() { + private static void printSystemMetrics() { Metrics c = Container.metrics(); ostream.println("Operating System Metrics:"); diff --git a/src/java.base/share/classes/sun/launcher/SecuritySettings.java b/src/java.base/share/classes/sun/launcher/SecuritySettings.java new file mode 100644 index 00000000000..c2bc67761c2 --- /dev/null +++ b/src/java.base/share/classes/sun/launcher/SecuritySettings.java @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2023, 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 sun.launcher; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import java.io.IOException; +import java.io.PrintStream; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Security; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.stream.Collectors; + +import jdk.internal.access.SharedSecrets; + +/** + * A utility class for security libs functionality + * in the -XshowSettings:security output + */ +public final class SecuritySettings { + + private static final String INDENT = " "; + private static final String TWOINDENT = INDENT + INDENT; + private static final String THREEINDENT = TWOINDENT + INDENT; + private static final String PROV_INFO_STRING = "Provider information: "; + private static PrintStream ostream = null; + + static void printSecuritySettings(String arg, PrintStream stream) { + ostream = stream; + switch (arg) { + case "properties" -> printSecurityProperties(); + case "providers" -> printSecurityProviderConfig(true); + case "tls" -> printSecurityTLSConfig(true); + case "all" -> printAllSecurityConfig(); + default -> ostream.println( + "\nUnrecognized security subcommand. Valid values are " + + "\"all\", \"properties\", \"providers\", \"tls\". See \"java -X\"\n"); + } + } + + // A non-verbose description of some core security configuration settings + static void printSecuritySummarySettings(PrintStream stream) { + ostream = stream; + ostream.println("Security settings summary: " + "\n" + + INDENT + "See \"java -X\" for verbose security settings options"); + printSecurityProviderConfig(false); + printSecurityTLSConfig(false); + } + + static void printAllSecurityConfig() { + ostream.println("Security settings:"); + printSecurityProperties(); + printSecurityProviderConfig(true); + printSecurityTLSConfig(true); + } + + private static void printSecurityProperties() { + ostream.println(INDENT + "Security properties:"); + Properties p = SharedSecrets.getJavaSecurityPropertiesAccess().getInitialProperties(); + for (String key : p.stringPropertyNames().stream().sorted().toList()) { + String val = p.getProperty(key); + if (val.length() > 60) { + splitLongPropertyLines(key, val); + } else { + ostream.println(TWOINDENT + key + "=" + val); + } + } + ostream.println(); + } + + private static void splitLongPropertyLines(String key, String val) { + // split long property values which use well known separator + if (val.contains(",") || val.contains(";")) { + String separator = (val.contains(",")) ? "," : ";"; + ostream.println(TWOINDENT + key + "="); + String[] values = val.split(separator); + String lastValue = values[values.length -1].trim(); + List.of(values).forEach( + s -> ostream.println(THREEINDENT + s.trim() + + (s.trim().equals(lastValue) ? "" : separator))); + } else { + ostream.println(TWOINDENT + key + "=" + val); + } + } + + private static void printSecurityTLSConfig(boolean verbose) { + SSLSocket ssls; + SSLContext sslContext; + try { + sslContext = SSLContext.getDefault(); + ssls = (SSLSocket)sslContext.getSocketFactory().createSocket(); + } catch (IOException | NoSuchAlgorithmException e) { + ostream.println(INDENT + "Failed to create SSL socket"); + ostream.println(INDENT + e + "\n"); + return; + } + + ostream.println(INDENT + "Security TLS configuration (" + + sslContext.getProvider().getName() + " provider):"); + ostream.println(TWOINDENT + "Enabled Protocols:"); + for (String s : ssls.getEnabledProtocols()) { + ostream.println(THREEINDENT + s); + } + + if (verbose) { + ostream.println("\n" + TWOINDENT + "Enabled Cipher Suites:"); + for (String s : ssls.getEnabledCipherSuites()) { + ostream.println(THREEINDENT + s); + } + } + ostream.println(); + } + + private static void printSecurityProviderConfig(boolean verbose) { + ostream.println(INDENT + "Security provider static configuration: (in order of preference)"); + for (Provider p : Security.getProviders()) { + if (verbose) { + // separate the views out + ostream.println(TWOINDENT + "-".repeat(40)); + } + ostream.println(TWOINDENT + "Provider name: " + p.getName()); + if (verbose) { + ostream.println(wrappedString(PROV_INFO_STRING + p.getInfo(), 80, + TWOINDENT, THREEINDENT)); + ostream.println(TWOINDENT + "Provider services: (type : algorithm)"); + Set services = p.getServices(); + Set keys = Collections.list(p.keys()) + .stream() + .map(String.class::cast) + .filter(s -> s.startsWith("Alg.Alias.")) + .collect(Collectors.toSet()); + if (!services.isEmpty()) { + services.stream() + .sorted(Comparator.comparing(Provider.Service::getType) + .thenComparing(Provider.Service::getAlgorithm)) + .forEach(ps -> { + ostream.println(THREEINDENT + + ps.getType() + "." + ps.getAlgorithm()); + List aliases = keys + .stream() + .filter(s -> s.startsWith("Alg.Alias." + ps.getType())) + .filter(s -> p.getProperty(s).equals(ps.getAlgorithm())) + .map(s -> s.substring(("Alg.Alias." + ps.getType() + ".").length())) + .toList(); + + if (!aliases.isEmpty()) { + ostream.println(wrappedString( + aliases.stream() + .collect(Collectors.joining(", ", INDENT + " aliases: [", "]")), + 80, " " + TWOINDENT, INDENT + THREEINDENT)); + } + }); + } else { + ostream.println(THREEINDENT + ""); + } + } + } + if (verbose) { + ostream.println(); + } + } + + // return a string split across multiple lines which aims to limit max length + private static String wrappedString(String orig, int limit, + String initIndent, String successiveIndent) { + if (orig == null || orig.isEmpty() || limit <= 0) { + // bad input + return orig; + } + StringBuilder sb = new StringBuilder(); + int widthCount = 0; + for (String s : orig.split(" ")) { + if (widthCount == 0) { + // first iteration only + sb.append(initIndent + s); + widthCount = s.length() + initIndent.length(); + } else { + if (widthCount + s.length() > limit) { + sb.append("\n" + successiveIndent + s); + widthCount = s.length() + successiveIndent.length(); + } else { + sb.append(" " + s); + widthCount += s.length() + 1; + } + } + } + return sb.toString(); + } +} diff --git a/src/java.base/share/classes/sun/launcher/resources/launcher.properties b/src/java.base/share/classes/sun/launcher/resources/launcher.properties index efcc4d69969..4eb9ab5eb79 100644 --- a/src/java.base/share/classes/sun/launcher/resources/launcher.properties +++ b/src/java.base/share/classes/sun/launcher/resources/launcher.properties @@ -168,6 +168,16 @@ java.launcher.X.usage=\n\ \ show all property settings and continue\n\ \ -XshowSettings:vm\n\ \ show all vm related settings and continue\n\ +\ -XshowSettings:security\n\ +\ show all security settings and continue\n\ +\ -XshowSettings:security:all\n\ +\ show all security settings and continue\n\ +\ -XshowSettings:security:properties\n\ +\ show security properties and continue\n\ +\ -XshowSettings:security:providers\n\ +\ show static security provider settings and continue\n\ +\ -XshowSettings:security:tls\n\ +\ show TLS related security settings and continue\n\ \ -XshowSettings:system\n\ \ (Linux Only) show host system or container\n\ \ configuration and continue\n\ diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index cbe42759701..7dc9f99eb18 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2022, 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 @@ -288,8 +288,7 @@ private static Set schemesListToSet(String list) { } static final String httpVersion = "HTTP/1.1"; - static final String acceptString = - "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"; + static final String acceptString = "*/*"; // the following http request headers should NOT have their values // returned for security reasons. diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java b/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java index 7af71c7d464..06a253cc1d7 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java @@ -153,7 +153,7 @@ private static HashMap getCache() { @Override protected boolean useAuthCache() { - return super.useAuthCache() && cacheSPNEGO; + return false; } /** diff --git a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java index 23c968ea6c2..b6b21f310bc 100644 --- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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 @@ -547,7 +547,7 @@ public SocketAddress receive(ByteBuffer dst) throws IOException { n = receive(dst, connected); } } - if (n >= 0) { + if (n > 0 || (n == 0 && isOpen())) { // sender address is in socket address buffer sender = sourceSocketAddress(); } @@ -668,7 +668,7 @@ private SocketAddress trustedBlockingReceive(ByteBuffer dst) park(Net.POLLIN); n = receive(dst, connected); } - if (n >= 0) { + if (n > 0 || (n == 0 && isOpen())) { // sender address is in socket address buffer sender = sourceSocketAddress(); } @@ -705,7 +705,7 @@ private SocketAddress trustedBlockingReceive(ByteBuffer dst, long nanos) park(Net.POLLIN, remainingNanos); n = receive(dst, connected); } - if (n >= 0) { + if (n > 0 || (n == 0 && isOpen())) { // sender address is in socket address buffer sender = sourceSocketAddress(); } diff --git a/src/java.base/share/classes/sun/security/action/GetPropertyAction.java b/src/java.base/share/classes/sun/security/action/GetPropertyAction.java index edaedc64ae8..f4c07f29a28 100644 --- a/src/java.base/share/classes/sun/security/action/GetPropertyAction.java +++ b/src/java.base/share/classes/sun/security/action/GetPropertyAction.java @@ -27,7 +27,9 @@ import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Locale; import java.util.Properties; +import sun.security.util.Debug; /** * A convenience class for retrieving the string value of a system @@ -159,4 +161,37 @@ public Properties run() { ); } } + + /** + * Convenience method for fetching System property values that are booleans. + * + * @param prop the name of the System property + * @param def a default value + * @param dbg a Debug object, if null no debug messages will be sent + * + * @return a boolean value corresponding to the value in the System property. + * If the property value is neither "true" or "false", the default value + * will be returned. + */ + public static boolean privilegedGetBooleanProp(String prop, boolean def, Debug dbg) { + String rawPropVal = privilegedGetProperty(prop, ""); + if ("".equals(rawPropVal)) { + return def; + } + + String lower = rawPropVal.toLowerCase(Locale.ROOT); + if ("true".equals(lower)) { + return true; + } else if ("false".equals(lower)) { + return false; + } else { + if (dbg != null) { + dbg.println("Warning: Unexpected value for " + prop + + ": " + rawPropVal + + ". Using default value: " + def); + } + return def; + } + } + } diff --git a/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java b/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java index 98575120ef9..03731b25cfb 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, 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 @@ -44,6 +44,7 @@ import java.util.Map; import sun.security.action.GetIntegerAction; +import sun.security.action.GetPropertyAction; import sun.security.util.Debug; import sun.security.util.Event; import sun.security.util.IOUtils; @@ -79,6 +80,28 @@ public final class OCSP { */ private static final int CONNECT_TIMEOUT = initializeTimeout(); + /** + * Boolean value indicating whether OCSP client can use GET for OCSP + * requests. There is an ambiguity in RFC recommendations. + * + * RFC 5019 says a stronger thing, "MUST": + * "When sending requests that are less than or equal to 255 bytes in + * total (after encoding) including the scheme and delimiters (http://), + * server name and base64-encoded OCSPRequest structure, clients MUST + * use the GET method (to enable OCSP response caching)." + * + * RFC 6960 says a weaker thing, "MAY": + * "HTTP-based OCSP requests can use either the GET or the POST method to + * submit their requests. To enable HTTP caching, small requests (that + * after encoding are less than 255 bytes) MAY be submitted using GET." + * + * For performance reasons, we default to stronger behavior. But this + * option also allows to fallback to weaker behavior in case of compatibility + * problems. + */ + private static final boolean USE_GET = initializeBoolean( + "com.sun.security.ocsp.useget", true); + /** * Initialize the timeout length by getting the OCSP timeout * system property. If the property has not been set, or if its @@ -96,6 +119,15 @@ private static int initializeTimeout() { return tmp * 1000; } + private static boolean initializeBoolean(String prop, boolean def) { + boolean value = + GetPropertyAction.privilegedGetBooleanProp(prop, def, debug); + if (debug != null) { + debug.println(prop + " set to " + value); + } + return value; + } + private OCSP() {} @@ -244,7 +276,7 @@ public static byte[] getOCSPBytes(List certIds, URI responderURI, encodedGetReq.append(URLEncoder.encode( Base64.getEncoder().encodeToString(bytes), "UTF-8")); - if (encodedGetReq.length() <= 255) { + if (USE_GET && encodedGetReq.length() <= 255) { url = new URL(encodedGetReq.toString()); con = (HttpURLConnection)url.openConnection(); con.setDoOutput(true); diff --git a/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java b/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java index 4c5af4b953c..dca389eadad 100644 --- a/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java +++ b/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java @@ -306,14 +306,6 @@ public AlgorithmParameterSpec getParams() { return keyParams; } - // return a string representation of this key for debugging - @Override - public String toString() { - return "SunRsaSign " + type.keyAlgo + " private CRT key, " - + n.bitLength() + " bits" + "\n params: " + keyParams - + "\n modulus: " + n + "\n private exponent: " + d; - } - // utility method for parsing DER encoding of RSA private keys in PKCS#1 // format as defined in RFC 8017 Appendix A.1.2, i.e. SEQ of version, n, // e, d, p, q, pe, qe, and coeff, and return the parsed components. diff --git a/src/java.base/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java b/src/java.base/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java index 5a645c7e887..a79b01445e9 100644 --- a/src/java.base/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java +++ b/src/java.base/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java @@ -143,14 +143,6 @@ public AlgorithmParameterSpec getParams() { return keyParams; } - // return a string representation of this key for debugging - @Override - public String toString() { - return "Sun " + type.keyAlgo + " private key, " + n.bitLength() - + " bits" + "\n params: " + keyParams + "\n modulus: " + n - + "\n private exponent: " + d; - } - /** * Restores the state of this object from the stream. *

diff --git a/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java index 52c23b33608..cd74949cbb5 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java @@ -1293,7 +1293,7 @@ List getClientDefaultCipherSuites() { } /* - * The SSLContext implementation for customized TLS protocols + * The SSLContext implementation for customized DTLS protocols * * @see SSLContext */ @@ -1351,13 +1351,11 @@ private static List customizedProtocols(boolean client, ProtocolVersion.DTLS12, ProtocolVersion.DTLS10 }; - if (!client) - return Arrays.asList(candidates); } else { // Use the customized TLS protocols. candidates = new ProtocolVersion[customized.size()]; - candidates = customized.toArray(candidates); + candidates = refactored.toArray(candidates); } return getAvailableProtocols(candidates); diff --git a/src/java.base/share/classes/sun/security/ssl/ServerHello.java b/src/java.base/share/classes/sun/security/ssl/ServerHello.java index 193a71cde86..2905cbf6192 100644 --- a/src/java.base/share/classes/sun/security/ssl/ServerHello.java +++ b/src/java.base/share/classes/sun/security/ssl/ServerHello.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, 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 @@ -799,6 +799,15 @@ public byte[] produce(ConnectionContext context, hhrm.write(shc.handshakeOutput); shc.handshakeOutput.flush(); + // In TLS1.3 middlebox compatibility mode the server sends a + // dummy change_cipher_spec record immediately after its + // first handshake message. This may either be after + // a ServerHello or a HelloRetryRequest. + // (RFC 8446, Appendix D.4) + shc.conContext.outputRecord.changeWriteCiphers( + SSLWriteCipher.nullTlsWriteCipher(), + (clientHello.sessionId.length() != 0)); + // Stateless, shall we clean up the handshake context as well? shc.handshakeHash.finish(); // forgot about the handshake hash shc.handshakeExtensions.clear(); diff --git a/src/java.base/share/classes/sun/security/ssl/SunJSSE.java b/src/java.base/share/classes/sun/security/ssl/SunJSSE.java index 894e26dfad8..dce2aad8400 100644 --- a/src/java.base/share/classes/sun/security/ssl/SunJSSE.java +++ b/src/java.base/share/classes/sun/security/ssl/SunJSSE.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, 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 @@ -31,25 +31,6 @@ /** * The JSSE provider. - * - * SunJSSE now supports an experimental FIPS compliant mode when used with an - * appropriate FIPS certified crypto provider. In FIPS mode, we: - * . allow only TLS 1.0 or later - * . allow only FIPS approved ciphersuites - * . perform all crypto in the FIPS crypto provider - * - * It is currently not possible to use both FIPS compliant SunJSSE and - * standard JSSE at the same time because of the various static data structures - * we use. - * - * However, we do want to allow FIPS mode to be enabled at runtime and without - * editing the java.security file. That means we need to allow - * Security.removeProvider("SunJSSE") to work, which creates an instance of - * this class in non-FIPS mode. That is why we delay the selection of the mode - * as long as possible. This is until we open an SSL/TLS connection and the - * data structures need to be initialized or until SunJSSE is initialized in - * FIPS mode. - * */ public class SunJSSE extends java.security.Provider { diff --git a/src/java.base/share/classes/sun/security/ssl/X509Authentication.java b/src/java.base/share/classes/sun/security/ssl/X509Authentication.java index ba1396f017b..366b27b4032 100644 --- a/src/java.base/share/classes/sun/security/ssl/X509Authentication.java +++ b/src/java.base/share/classes/sun/security/ssl/X509Authentication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, 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 @@ -203,6 +203,10 @@ public static SSLPossession createPossession( private static SSLPossession createClientPossession( ClientHandshakeContext chc, String[] keyTypes) { X509ExtendedKeyManager km = chc.sslContext.getX509KeyManager(); + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.finest("X509KeyManager class: " + + km.getClass().getName()); + } String clientAlias = null; if (chc.conContext.transport instanceof SSLSocketImpl socket) { clientAlias = km.chooseClientAlias( @@ -272,6 +276,10 @@ private static SSLPossession createClientPossession( private static SSLPossession createServerPossession( ServerHandshakeContext shc, String[] keyTypes) { X509ExtendedKeyManager km = shc.sslContext.getX509KeyManager(); + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.finest("X509KeyManager class: " + + km.getClass().getName()); + } String serverAlias = null; for (String keyType : keyTypes) { if (shc.conContext.transport instanceof SSLSocketImpl socket) { diff --git a/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties b/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties index 53bf1d837ff..c231cadc416 100644 --- a/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties +++ b/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2023, 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 @@ -266,6 +266,7 @@ XBB=XBB XBC=XBC XBD=XBD XCD=XCD +XCG=XCG XDR=XDR XFO=XFO XFU=XFU @@ -491,6 +492,7 @@ xbb=European Monetary Unit xbc=European Unit of Account (XBC) xbd=European Unit of Account (XBD) xcd=East Caribbean Dollar +xcg=Caribbean Guilder xdr=Special Drawing Rights xfo=French Gold Franc xfu=French UIC-Franc diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index 78faaf1a0c5..8f6e1e12a7e 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -736,8 +736,8 @@ jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048, \ # rsa_pkcs1_sha1, secp224r1 -jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \ - DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL +jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, DTLSv1.0, RC4, DES, \ + MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL # # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) diff --git a/src/java.base/share/legal/siphash.md b/src/java.base/share/legal/siphash.md new file mode 100644 index 00000000000..a1183acf2b0 --- /dev/null +++ b/src/java.base/share/legal/siphash.md @@ -0,0 +1,150 @@ +## SipHash v1.0-68c8a7c + +### Notice +SipHash reference C implementation + +``` + Copyright (c) 2016 Jean-Philippe Aumasson + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along + with + this software. If not, see + . +``` + +### Licenses +The code is dual-licensed CCO and MIT + +#### MIT License +``` +Copyright 2012-2024 JP Aumasson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` + +#### CC0 1.0 Universal +``` +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific +works ("Commons") that the public can reliably and without fear of later +claims of infringement build upon, modify, incorporate in other works, reuse +and redistribute as freely as possible in any form whatsoever and for any +purposes, including without limitation commercial purposes. These owners may +contribute to the Commons to promote the ideal of a free culture and the +further production of creative, cultural and scientific works, or to gain +reputation or greater distribution for their Work in part through the use and +efforts of others. + +For these and/or other purposes and motivations, and without any expectation +of additional consideration or compensation, the person associating CC0 with a +Work (the "Affirmer"), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work +and publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not limited +to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + + ii. moral rights retained by the original author(s) and/or performer(s); + + iii. publicity and privacy rights pertaining to a person's image or likeness + depicted in a Work; + + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + + v. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + + vii. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer's Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer's heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer's express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, +non transferable, non sublicensable, non exclusive, irrevocable and +unconditional license to exercise Affirmer's Copyright and Related Rights in +the Work (i) in all territories worldwide, (ii) for the maximum duration +provided by applicable law or treaty (including future time extensions), (iii) +in any current or future medium and for any number of copies, and (iv) for any +purpose whatsoever, including without limitation commercial, advertising or +promotional purposes (the "License"). The License shall be deemed effective as +of the date CC0 was applied by Affirmer to the Work. Should any part of the +License for any reason be judged legally invalid or ineffective under +applicable law, such partial invalidity or ineffectiveness shall not +invalidate the remainder of the License, and in such case Affirmer hereby +affirms that he or she will not (i) exercise any of his or her remaining +Copyright and Related Rights in the Work or (ii) assert any associated claims +and causes of action with respect to the Work, in either case contrary to +Affirmer's express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + + b. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or otherwise, + including without limitation warranties of title, merchantability, fitness + for a particular purpose, non infringement, or the absence of latent or + other defects, accuracy, or the present or absence of errors, whether or not + discoverable, all to the greatest extent permissible under applicable law. + + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without limitation + any person's Copyright and Related Rights in the Work. Further, Affirmer + disclaims responsibility for obtaining any necessary consents, permissions + or other rights required for any use of the Work. + + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see + + +``` diff --git a/src/java.base/share/legal/zlib.md b/src/java.base/share/legal/zlib.md index d856af6ccd4..fcc5457bf5b 100644 --- a/src/java.base/share/legal/zlib.md +++ b/src/java.base/share/legal/zlib.md @@ -1,9 +1,9 @@ -## zlib v1.2.13 +## zlib v1.3.1 ### zlib License

 
-Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
+Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler
 
 This software is provided 'as-is', without any express or implied
 warranty.  In no event will the authors be held liable for any damages
diff --git a/src/java.base/share/man/java.1 b/src/java.base/share/man/java.1
index 3039c2187e4..44251290e05 100644
--- a/src/java.base/share/man/java.1
+++ b/src/java.base/share/man/java.1
@@ -1,4 +1,4 @@
-.\" Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved.
+.\" Copyright (c) 1994, 2024, 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
@@ -1540,6 +1540,17 @@ and its committed regions.
 .RE
 .RE
 .TP
+.B \f[CB]-XX:TrimNativeHeapInterval=\f[R]\f[I]millis\f[R]
+Interval, in ms, at which the JVM will trim the native heap.
+Lower values will reclaim memory more eagerly at the cost of higher
+overhead.
+A value of 0 (default) disables native heap trimming.
+Native heap trimming is performed in a dedicated thread.
+.RS
+.PP
+This option is only supported on Linux with GNU C Library (glibc).
+.RE
+.TP
 .B \f[CB]\-XX:ObjectAlignmentInBytes=\f[R]\f[I]alignment\f[R]
 Sets the memory alignment of Java objects (in bytes).
 By default, the value is set to 8 bytes.
diff --git a/src/java.base/share/native/libzip/zlib/ChangeLog b/src/java.base/share/native/libzip/zlib/ChangeLog
index 30199a65a03..b801a1031ec 100644
--- a/src/java.base/share/native/libzip/zlib/ChangeLog
+++ b/src/java.base/share/native/libzip/zlib/ChangeLog
@@ -1,6 +1,109 @@
 
                 ChangeLog file for zlib
 
+Changes in 1.3.1 (22 Jan 2024)
+- Reject overflows of zip header fields in minizip
+- Fix bug in inflateSync() for data held in bit buffer
+- Add LIT_MEM define to use more memory for a small deflate speedup
+- Fix decision on the emission of Zip64 end records in minizip
+- Add bounds checking to ERR_MSG() macro, used by zError()
+- Neutralize zip file traversal attacks in miniunz
+- Fix a bug in ZLIB_DEBUG compiles in check_match()
+- Various portability and appearance improvements
+
+Changes in 1.3 (18 Aug 2023)
+- Remove K&R function definitions and zlib2ansi
+- Fix bug in deflateBound() for level 0 and memLevel 9
+- Fix bug when gzungetc() is used immediately after gzopen()
+- Fix bug when using gzflush() with a very small buffer
+- Fix crash when gzsetparams() attempted for transparent write
+- Fix test/example.c to work with FORCE_STORED
+- Rewrite of zran in examples (see zran.c version history)
+- Fix minizip to allow it to open an empty zip file
+- Fix reading disk number start on zip64 files in minizip
+- Fix logic error in minizip argument processing
+- Add minizip testing to Makefile
+- Read multiple bytes instead of byte-by-byte in minizip unzip.c
+- Add memory sanitizer to configure (--memory)
+- Various portability improvements
+- Various documentation improvements
+- Various spelling and typo corrections
+
+Changes in 1.2.13 (13 Oct 2022)
+- Fix configure issue that discarded provided CC definition
+- Correct incorrect inputs provided to the CRC functions
+- Repair prototypes and exporting of new CRC functions
+- Fix inflateBack to detect invalid input with distances too far
+- Have infback() deliver all of the available output up to any error
+- Fix a bug when getting a gzip header extra field with inflate()
+- Fix bug in block type selection when Z_FIXED used
+- Tighten deflateBound bounds
+- Remove deleted assembler code references
+- Various portability and appearance improvements
+
+Changes in 1.2.12 (27 Mar 2022)
+- Cygwin does not have _wopen(), so do not create gzopen_w() there
+- Permit a deflateParams() parameter change as soon as possible
+- Limit hash table inserts after switch from stored deflate
+- Fix bug when window full in deflate_stored()
+- Fix CLEAR_HASH macro to be usable as a single statement
+- Avoid a conversion error in gzseek when off_t type too small
+- Have Makefile return non-zero error code on test failure
+- Avoid some conversion warnings in gzread.c and gzwrite.c
+- Update use of errno for newer Windows CE versions
+- Small speedup to inflate [psumbera]
+- Return an error if the gzputs string length can't fit in an int
+- Add address checking in clang to -w option of configure
+- Don't compute check value for raw inflate if asked to validate
+- Handle case where inflateSync used when header never processed
+- Avoid the use of ptrdiff_t
+- Avoid an undefined behavior of memcpy() in gzappend()
+- Avoid undefined behaviors of memcpy() in gz*printf()
+- Avoid an undefined behavior of memcpy() in _tr_stored_block()
+- Make the names in functions declarations identical to definitions
+- Remove old assembler code in which bugs have manifested
+- Fix deflateEnd() to not report an error at start of raw deflate
+- Add legal disclaimer to README
+- Emphasize the need to continue decompressing gzip members
+- Correct the initialization requirements for deflateInit2()
+- Fix a bug that can crash deflate on some input when using Z_FIXED
+- Assure that the number of bits for deflatePrime() is valid
+- Use a structure to make globals in enough.c evident
+- Use a macro for the printf format of big_t in enough.c
+- Clean up code style in enough.c, update version
+- Use inline function instead of macro for index in enough.c
+- Clarify that prefix codes are counted in enough.c
+- Show all the codes for the maximum tables size in enough.c
+- Add gznorm.c example, which normalizes gzip files
+- Fix the zran.c example to work on a multiple-member gzip file
+- Add tables for crc32_combine(), to speed it up by a factor of 200
+- Add crc32_combine_gen() and crc32_combine_op() for fast combines
+- Speed up software CRC-32 computation by a factor of 1.5 to 3
+- Use atomic test and set, if available, for dynamic CRC tables
+- Don't bother computing check value after successful inflateSync()
+- Correct comment in crc32.c
+- Add use of the ARMv8 crc32 instructions when requested
+- Use ARM crc32 instructions if the ARM architecture has them
+- Explicitly note that the 32-bit check values are 32 bits
+- Avoid adding empty gzip member after gzflush with Z_FINISH
+- Fix memory leak on error in gzlog.c
+- Fix error in comment on the polynomial representation of a byte
+- Clarify gz* function interfaces, referring to parameter names
+- Change macro name in inflate.c to avoid collision in VxWorks
+- Correct typo in blast.c
+- Improve portability of contrib/minizip
+- Fix indentation in minizip's zip.c
+- Replace black/white with allow/block. (theresa-m)
+- minizip warning fix if MAXU32 already defined. (gvollant)
+- Fix unztell64() in minizip to work past 4GB. (Daniël Hörchner)
+- Clean up minizip to reduce warnings for testing
+- Add fallthrough comments for gcc
+- Eliminate use of ULL constants
+- Separate out address sanitizing from warnings in configure
+- Remove destructive aspects of make distclean
+- Check for cc masquerading as gcc or clang in configure
+- Fix crc32.c to compile local functions only if used
+
 Changes in 1.2.11 (15 Jan 2017)
 - Fix deflate stored bug when pulling last block from window
 - Permit immediate deflateParams changes before any deflate input
@@ -96,7 +199,7 @@ Changes in 1.2.7.1 (24 Mar 2013)
 - Fix types in contrib/minizip to match result of get_crc_table()
 - Simplify contrib/vstudio/vc10 with 'd' suffix
 - Add TOP support to win32/Makefile.msc
-- Suport i686 and amd64 assembler builds in CMakeLists.txt
+- Support i686 and amd64 assembler builds in CMakeLists.txt
 - Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h
 - Add vc11 and vc12 build files to contrib/vstudio
 - Add gzvprintf() as an undocumented function in zlib
@@ -296,14 +399,14 @@ Changes in 1.2.5.1 (10 Sep 2011)
 - Use u4 type for crc_table to avoid conversion warnings
 - Apply casts in zlib.h to avoid conversion warnings
 - Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller]
-- Improve inflateSync() documentation to note indeterminancy
+- Improve inflateSync() documentation to note indeterminacy
 - Add deflatePending() function to return the amount of pending output
 - Correct the spelling of "specification" in FAQ [Randers-Pehrson]
 - Add a check in configure for stdarg.h, use for gzprintf()
 - Check that pointers fit in ints when gzprint() compiled old style
 - Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler]
 - Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt]
-- Add debug records in assmebler code [Londer]
+- Add debug records in assembler code [Londer]
 - Update RFC references to use http://tools.ietf.org/html/... [Li]
 - Add --archs option, use of libtool to configure for Mac OS X [Borstel]
 
@@ -511,7 +614,7 @@ Changes in 1.2.3.5 (8 Jan 2010)
 - Don't use _vsnprintf on later versions of MSVC [Lowman]
 - Add CMake build script and input file [Lowman]
 - Update contrib/minizip to 1.1 [Svensson, Vollant]
-- Moved nintendods directory from contrib to .
+- Moved nintendods directory from contrib to root
 - Replace gzio.c with a new set of routines with the same functionality
 - Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above
 - Update contrib/minizip to 1.1b
@@ -685,7 +788,7 @@ Changes in 1.2.2.4 (11 July 2005)
 - Be more strict on incomplete code sets in inflate_table() and increase
   ENOUGH and MAXD -- this repairs a possible security vulnerability for
   invalid inflate input.  Thanks to Tavis Ormandy and Markus Oberhumer for
-  discovering the vulnerability and providing test cases.
+  discovering the vulnerability and providing test cases
 - Add ia64 support to configure for HP-UX [Smith]
 - Add error return to gzread() for format or i/o error [Levin]
 - Use malloc.h for OS/2 [Necasek]
@@ -721,7 +824,7 @@ Changes in 1.2.2.2 (30 December 2004)
 - Add Z_FIXED strategy option to deflateInit2() to force fixed trees
 - Add updated make_vms.com [Coghlan], update README
 - Create a new "examples" directory, move gzappend.c there, add zpipe.c,
-  fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
+  fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html
 - Add FAQ entry and comments in deflate.c on uninitialized memory access
 - Add Solaris 9 make options in configure [Gilbert]
 - Allow strerror() usage in gzio.c for STDC
@@ -792,7 +895,7 @@ Changes in 1.2.1.1 (9 January 2004)
 - Fix a big fat bug in inftrees.c that prevented decoding valid
   dynamic blocks with only literals and no distance codes --
   Thanks to "Hot Emu" for the bug report and sample file
-- Add a note to puff.c on no distance codes case.
+- Add a note to puff.c on no distance codes case
 
 Changes in 1.2.1 (17 November 2003)
 - Remove a tab in contrib/gzappend/gzappend.c
@@ -970,7 +1073,7 @@ Changes in 1.2.0.1 (17 March 2003)
     - Include additional header file on VMS for off_t typedef
 - Try to use _vsnprintf where it supplants vsprintf [Vollant]
 - Add some casts in inffast.c
-- Enchance comments in zlib.h on what happens if gzprintf() tries to
+- Enhance comments in zlib.h on what happens if gzprintf() tries to
   write more than 4095 bytes before compression
 - Remove unused state from inflateBackEnd()
 - Remove exit(0) from minigzip.c, example.c
@@ -1036,14 +1139,14 @@ Changes in 1.2.0 (9 March 2003)
 - Add contrib/puff/ simple inflate for deflate format description
 
 Changes in 1.1.4 (11 March 2002)
-- ZFREE was repeated on same allocation on some error conditions.
+- ZFREE was repeated on same allocation on some error conditions
   This creates a security problem described in
   http://www.zlib.org/advisory-2002-03-11.txt
 - Returned incorrect error (Z_MEM_ERROR) on some invalid data
 - Avoid accesses before window for invalid distances with inflate window
-  less than 32K.
+  less than 32K
 - force windowBits > 8 to avoid a bug in the encoder for a window size
-  of 256 bytes. (A complete fix will be available in 1.1.5).
+  of 256 bytes. (A complete fix will be available in 1.1.5)
 
 Changes in 1.1.3 (9 July 1998)
 - fix "an inflate input buffer bug that shows up on rare but persistent
@@ -1117,7 +1220,7 @@ Changes in 1.1.1 (27 Feb 98)
 - remove block truncation heuristic which had very marginal effect for zlib
   (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
   compression ratio on some files. This also allows inlining _tr_tally for
-  matches in deflate_slow.
+  matches in deflate_slow
 - added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
 
 Changes in 1.1.0 (24 Feb 98)
@@ -1148,7 +1251,7 @@ Changes in 1.0.9 (17 Feb 1998)
 - Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
 - in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
 - in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
-  the declaration of FAR (Gilles VOllant)
+  the declaration of FAR (Gilles Vollant)
 - install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
 - read_buf buf parameter of type Bytef* instead of charf*
 - zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
@@ -1162,7 +1265,7 @@ Changes in 1.0.8 (27 Jan 1998)
 - include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
 - use constant arrays for the static trees in trees.c instead of computing
   them at run time (thanks to Ken Raeburn for this suggestion). To create
-  trees.h, compile with GEN_TREES_H and run "make test".
+  trees.h, compile with GEN_TREES_H and run "make test"
 - check return code of example in "make test" and display result
 - pass minigzip command line options to file_compress
 - simplifying code of inflateSync to avoid gcc 2.8 bug
@@ -1201,12 +1304,12 @@ Changes in 1.0.6 (19 Jan 1998)
 - add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
   gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
 - Fix a deflate bug occurring only with compression level 0 (thanks to
-  Andy Buckler for finding this one).
-- In minigzip, pass transparently also the first byte for .Z files.
+  Andy Buckler for finding this one)
+- In minigzip, pass transparently also the first byte for .Z files
 - return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
 - check Z_FINISH in inflate (thanks to Marc Schluper)
 - Implement deflateCopy (thanks to Adam Costello)
-- make static libraries by default in configure, add --shared option.
+- make static libraries by default in configure, add --shared option
 - move MSDOS or Windows specific files to directory msdos
 - suppress the notion of partial flush to simplify the interface
   (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
@@ -1218,7 +1321,7 @@ Changes in 1.0.6 (19 Jan 1998)
 - added Makefile.nt (thanks to Stephen Williams)
 - added the unsupported "contrib" directory:
    contrib/asm386/ by Gilles Vollant 
-        386 asm code replacing longest_match().
+        386 asm code replacing longest_match()
    contrib/iostream/ by Kevin Ruland 
         A C++ I/O streams interface to the zlib gz* functions
    contrib/iostream2/  by Tyge Løvset 
@@ -1226,7 +1329,7 @@ Changes in 1.0.6 (19 Jan 1998)
    contrib/untgz/  by "Pedro A. Aranda Guti\irrez" 
         A very simple tar.gz file extractor using zlib
    contrib/visual-basic.txt by Carlos Rios 
-        How to use compress(), uncompress() and the gz* functions from VB.
+        How to use compress(), uncompress() and the gz* functions from VB
 - pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
   level) in minigzip (thanks to Tom Lane)
 
@@ -1235,8 +1338,8 @@ Changes in 1.0.6 (19 Jan 1998)
 - add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
 - add undocumented function zError to convert error code to string
   (for Tim Smithers)
-- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
-- Use default memcpy for Symantec MSDOS compiler.
+- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code
+- Use default memcpy for Symantec MSDOS compiler
 - Add EXPORT keyword for check_func (needed for Windows DLL)
 - add current directory to LD_LIBRARY_PATH for "make test"
 - create also a link for libz.so.1
@@ -1249,7 +1352,7 @@ Changes in 1.0.6 (19 Jan 1998)
 - allow compilation with ANSI keywords only enabled for TurboC in large model
 - avoid "versionString"[0] (Borland bug)
 - add NEED_DUMMY_RETURN for Borland
-- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
+- use variable z_verbose for tracing in debug mode (L. Peter Deutsch)
 - allow compilation with CC
 - defined STDC for OS/2 (David Charlap)
 - limit external names to 8 chars for MVS (Thomas Lund)
@@ -1259,7 +1362,7 @@ Changes in 1.0.6 (19 Jan 1998)
 - use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
 - added makelcc.bat for lcc-win32 (Tom St Denis)
 - in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
-- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion
 - check for unistd.h in configure (for off_t)
 - remove useless check parameter in inflate_blocks_free
 - avoid useless assignment of s->check to itself in inflate_blocks_new
@@ -1280,7 +1383,7 @@ Changes in 1.0.5 (3 Jan 98)
 Changes in 1.0.4 (24 Jul 96)
 - In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
   bit, so the decompressor could decompress all the correct data but went
-  on to attempt decompressing extra garbage data. This affected minigzip too.
+  on to attempt decompressing extra garbage data. This affected minigzip too
 - zlibVersion and gzerror return const char* (needed for DLL)
 - port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
 - use z_error only for DEBUG (avoid problem with DLLs)
@@ -1310,7 +1413,7 @@ Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
 - fix array overlay in deflate.c which sometimes caused bad compressed data
 - fix inflate bug with empty stored block
 - fix MSDOS medium model which was broken in 0.99
-- fix deflateParams() which could generate bad compressed data.
+- fix deflateParams() which could generate bad compressed data
 - Bytef is define'd instead of typedef'ed (work around Borland bug)
 - added an INDEX file
 - new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
@@ -1331,7 +1434,7 @@ Changes in 0.99 (27 Jan 96)
 - allow preset dictionary shared between compressor and decompressor
 - allow compression level 0 (no compression)
 - add deflateParams in zlib.h: allow dynamic change of compression level
-  and compression strategy.
+  and compression strategy
 - test large buffers and deflateParams in example.c
 - add optional "configure" to build zlib as a shared library
 - suppress Makefile.qnx, use configure instead
@@ -1370,33 +1473,33 @@ Changes in 0.99 (27 Jan 96)
 - fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
 - in fcalloc, normalize pointer if size > 65520 bytes
 - don't use special fcalloc for 32 bit Borland C++
-- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc.
 - use Z_BINARY instead of BINARY
 - document that gzclose after gzdopen will close the file
-- allow "a" as mode in gzopen.
+- allow "a" as mode in gzopen
 - fix error checking in gzread
 - allow skipping .gz extra-field on pipes
 - added reference to Perl interface in README
 - put the crc table in FAR data (I dislike more and more the medium model :)
 - added get_crc_table
-- added a dimension to all arrays (Borland C can't count).
+- added a dimension to all arrays (Borland C can't count)
 - workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
 - guard against multiple inclusion of *.h (for precompiled header on Mac)
-- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode
 - don't use unsized arrays to avoid silly warnings by Visual C++:
      warning C4746: 'inflate_mask' : unsized array treated as  '__far'
-     (what's wrong with far data in far model?).
+     (what's wrong with far data in far model?)
 - define enum out of inflate_blocks_state to allow compilation with C++
 
 Changes in 0.95 (16 Aug 95)
 - fix MSDOS small and medium model (now easier to adapt to any compiler)
 - inlined send_bits
 - fix the final (:-) bug for deflate with flush (output was correct but
-  not completely flushed in rare occasions).
+  not completely flushed in rare occasions)
 - default window size is same for compression and decompression
-  (it's now sufficient to set MAX_WBITS in zconf.h).
+  (it's now sufficient to set MAX_WBITS in zconf.h)
 - voidp -> voidpf and voidnp -> voidp (for consistency with other
-  typedefs and because voidnp was not near in large model).
+  typedefs and because voidnp was not near in large model)
 
 Changes in 0.94 (13 Aug 95)
 - support MSDOS medium model
@@ -1405,12 +1508,12 @@ Changes in 0.94 (13 Aug 95)
 - added support for VMS
 - allow a compression level in gzopen()
 - gzflush now calls fflush
-- For deflate with flush, flush even if no more input is provided.
+- For deflate with flush, flush even if no more input is provided
 - rename libgz.a as libz.a
 - avoid complex expression in infcodes.c triggering Turbo C bug
 - work around a problem with gcc on Alpha (in INSERT_STRING)
 - don't use inline functions (problem with some gcc versions)
-- allow renaming of Byte, uInt, etc... with #define.
+- allow renaming of Byte, uInt, etc... with #define
 - avoid warning about (unused) pointer before start of array in deflate.c
 - avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
 - avoid reserved word 'new' in trees.c
@@ -1429,7 +1532,7 @@ Changes in 0.92 (3 May 95)
 - no memcpy on Pyramid
 - suppressed inftest.c
 - optimized fill_window, put longest_match inline for gcc
-- optimized inflate on stored blocks.
+- optimized inflate on stored blocks
 - untabify all sources to simplify patches
 
 Changes in 0.91 (2 May 95)
@@ -1447,7 +1550,7 @@ Changes in 0.9 (1 May 95)
 - let again gzread copy uncompressed data unchanged (was working in 0.71)
 - deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
 - added a test of inflateSync in example.c
-- moved MAX_WBITS to zconf.h because users might want to change that.
+- moved MAX_WBITS to zconf.h because users might want to change that
 - document explicitly that zalloc(64K) on MSDOS must return a normalized
   pointer (zero offset)
 - added Makefiles for Microsoft C, Turbo C, Borland C++
@@ -1456,7 +1559,7 @@ Changes in 0.9 (1 May 95)
 Changes in 0.8 (29 April 95)
 - added fast inflate (inffast.c)
 - deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
-  is incompatible with previous versions of zlib which returned Z_OK.
+  is incompatible with previous versions of zlib which returned Z_OK
 - work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
   (actually that was not a compiler bug, see 0.81 above)
 - gzread no longer reads one extra byte in certain cases
@@ -1466,50 +1569,50 @@ Changes in 0.8 (29 April 95)
 
 Changes in 0.71 (14 April 95)
 - Fixed more MSDOS compilation problems :( There is still a bug with
-  TurboC large model.
+  TurboC large model
 
 Changes in 0.7 (14 April 95)
-- Added full inflate support.
+- Added full inflate support
 - Simplified the crc32() interface. The pre- and post-conditioning
   (one's complement) is now done inside crc32(). WARNING: this is
-  incompatible with previous versions; see zlib.h for the new usage.
+  incompatible with previous versions; see zlib.h for the new usage
 
 Changes in 0.61 (12 April 95)
-- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS
 
 Changes in 0.6 (11 April 95)
 - added minigzip.c
 - added gzdopen to reopen a file descriptor as gzFile
-- added transparent reading of non-gziped files in gzread.
+- added transparent reading of non-gziped files in gzread
 - fixed bug in gzread (don't read crc as data)
-- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose)
 - don't allocate big arrays in the stack (for MSDOS)
 - fix some MSDOS compilation problems
 
 Changes in 0.5:
 - do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
-  not yet Z_FULL_FLUSH.
+  not yet Z_FULL_FLUSH
 - support decompression but only in a single step (forced Z_FINISH)
-- added opaque object for zalloc and zfree.
+- added opaque object for zalloc and zfree
 - added deflateReset and inflateReset
-- added a variable zlib_version for consistency checking.
-- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
-  Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
+- added a variable zlib_version for consistency checking
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'
+  Added Z_FILTERED and Z_HUFFMAN_ONLY constants
 
 Changes in 0.4:
-- avoid "zip" everywhere, use zlib instead of ziplib.
+- avoid "zip" everywhere, use zlib instead of ziplib
 - suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
-  if compression method == 8.
+  if compression method == 8
 - added adler32 and crc32
 - renamed deflateOptions as deflateInit2, call one or the other but not both
-- added the method parameter for deflateInit2.
+- added the method parameter for deflateInit2
 - added inflateInit2
-- simplied considerably deflateInit and inflateInit by not supporting
+- simplified considerably deflateInit and inflateInit by not supporting
   user-provided history buffer. This is supported only in deflateInit2
-  and inflateInit2.
+  and inflateInit2
 
 Changes in 0.3:
 - prefix all macro names with Z_
-- use Z_FINISH instead of deflateEnd to finish compression.
+- use Z_FINISH instead of deflateEnd to finish compression
 - added Z_HUFFMAN_ONLY
 - added gzerror()
diff --git a/src/java.base/share/native/libzip/zlib/README b/src/java.base/share/native/libzip/zlib/README
index ba34d1894a9..c5f917540b6 100644
--- a/src/java.base/share/native/libzip/zlib/README
+++ b/src/java.base/share/native/libzip/zlib/README
@@ -1,6 +1,6 @@
 ZLIB DATA COMPRESSION LIBRARY
 
-zlib 1.2.13 is a general purpose data compression library.  All the code is
+zlib 1.3.1 is a general purpose data compression library.  All the code is
 thread safe.  The data format used by the zlib library is described by RFCs
 (Request for Comments) 1950 to 1952 in the files
 http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
@@ -29,18 +29,17 @@ PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
 
 Mark Nelson  wrote an article about zlib for the Jan.  1997
 issue of Dr.  Dobb's Journal; a copy of the article is available at
-http://marknelson.us/1997/01/01/zlib-engine/ .
+https://marknelson.us/posts/1997/01/01/zlib-engine.html .
 
-The changes made in version 1.2.13 are documented in the file ChangeLog.
+The changes made in version 1.3.1 are documented in the file ChangeLog.
 
 Unsupported third party contributions are provided in directory contrib/ .
 
-zlib is available in Java using the java.util.zip package, documented at
-http://java.sun.com/developer/technicalArticles/Programming/compression/ .
+zlib is available in Java using the java.util.zip package. Follow the API
+Documentation link at: https://docs.oracle.com/search/?q=java.util.zip .
 
-A Perl interface to zlib written by Paul Marquess  is available
-at CPAN (Comprehensive Perl Archive Network) sites, including
-http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
+A Perl interface to zlib and bzip2 written by Paul Marquess 
+can be found at https://github.com/pmqs/IO-Compress .
 
 A Python interface to zlib written by A.M. Kuchling  is
 available in Python 1.5 and later versions, see
@@ -64,7 +63,7 @@ Notes for some targets:
 - zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
   when compiled with cc.
 
-- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+- On Digital Unix 4.0D (formerly OSF/1) on AlphaServer, the cc option -std1 is
   necessary to get gzprintf working correctly. This is done by configure.
 
 - zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
@@ -84,7 +83,7 @@ Acknowledgments:
 
 Copyright notice:
 
- (C) 1995-2022 Jean-loup Gailly and Mark Adler
+ (C) 1995-2024 Jean-loup Gailly and Mark Adler
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/src/java.base/share/native/libzip/zlib/compress.c b/src/java.base/share/native/libzip/zlib/compress.c
index bc090096785..d7421379673 100644
--- a/src/java.base/share/native/libzip/zlib/compress.c
+++ b/src/java.base/share/native/libzip/zlib/compress.c
@@ -43,13 +43,8 @@
    memory, Z_BUF_ERROR if there was not enough room in the output buffer,
    Z_STREAM_ERROR if the level parameter is invalid.
 */
-int ZEXPORT compress2(dest, destLen, source, sourceLen, level)
-    Bytef *dest;
-    uLongf *destLen;
-    const Bytef *source;
-    uLong sourceLen;
-    int level;
-{
+int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source,
+                      uLong sourceLen, int level) {
     z_stream stream;
     int err;
     const uInt max = (uInt)-1;
@@ -89,12 +84,8 @@ int ZEXPORT compress2(dest, destLen, source, sourceLen, level)
 
 /* ===========================================================================
  */
-int ZEXPORT compress(dest, destLen, source, sourceLen)
-    Bytef *dest;
-    uLongf *destLen;
-    const Bytef *source;
-    uLong sourceLen;
-{
+int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source,
+                     uLong sourceLen) {
     return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
 }
 
@@ -102,9 +93,7 @@ int ZEXPORT compress(dest, destLen, source, sourceLen)
      If the default memLevel or windowBits for deflateInit() is changed, then
    this function needs to be updated.
  */
-uLong ZEXPORT compressBound(sourceLen)
-    uLong sourceLen;
-{
+uLong ZEXPORT compressBound(uLong sourceLen) {
     return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
            (sourceLen >> 25) + 13;
 }
diff --git a/src/java.base/share/native/libzip/zlib/deflate.c b/src/java.base/share/native/libzip/zlib/deflate.c
index 46d512d4200..57fc6802bb8 100644
--- a/src/java.base/share/native/libzip/zlib/deflate.c
+++ b/src/java.base/share/native/libzip/zlib/deflate.c
@@ -23,7 +23,7 @@
  */
 
 /* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
+ * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -76,7 +76,7 @@
 #include "deflate.h"
 
 const char deflate_copyright[] =
-   " deflate 1.2.13 Copyright 1995-2022 Jean-loup Gailly and Mark Adler ";
+   " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler ";
 /*
   If you use the zlib library in a product, an acknowledgment is welcome
   in the documentation of your product. If for some reason you cannot
@@ -84,9 +84,6 @@ const char deflate_copyright[] =
   copyright string in the executable of your product.
  */
 
-/* ===========================================================================
- *  Function prototypes.
- */
 typedef enum {
     need_more,      /* block not completed, need more input or more output */
     block_done,     /* block flush performed */
@@ -94,29 +91,16 @@ typedef enum {
     finish_done     /* finish done, accept no more input or output */
 } block_state;
 
-typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+typedef block_state (*compress_func)(deflate_state *s, int flush);
 /* Compression function. Returns the block state after the call. */
 
-local int deflateStateCheck      OF((z_streamp strm));
-local void slide_hash     OF((deflate_state *s));
-local void fill_window    OF((deflate_state *s));
-local block_state deflate_stored OF((deflate_state *s, int flush));
-local block_state deflate_fast   OF((deflate_state *s, int flush));
+local block_state deflate_stored(deflate_state *s, int flush);
+local block_state deflate_fast(deflate_state *s, int flush);
 #ifndef FASTEST
-local block_state deflate_slow   OF((deflate_state *s, int flush));
-#endif
-local block_state deflate_rle    OF((deflate_state *s, int flush));
-local block_state deflate_huff   OF((deflate_state *s, int flush));
-local void lm_init        OF((deflate_state *s));
-local void putShortMSB    OF((deflate_state *s, uInt b));
-local void flush_pending  OF((z_streamp strm));
-local unsigned read_buf   OF((z_streamp strm, Bytef *buf, unsigned size));
-local uInt longest_match  OF((deflate_state *s, IPos cur_match));
-
-#ifdef ZLIB_DEBUG
-local  void check_match OF((deflate_state *s, IPos start, IPos match,
-                            int length));
+local block_state deflate_slow(deflate_state *s, int flush);
 #endif
+local block_state deflate_rle(deflate_state *s, int flush);
+local block_state deflate_huff(deflate_state *s, int flush);
 
 /* ===========================================================================
  * Local data
@@ -219,9 +203,12 @@ local const config configuration_table[10] = {
  * bit values at the expense of memory usage). We slide even when level == 0 to
  * keep the hash table consistent if we switch back to level > 0 later.
  */
-local void slide_hash(s)
-    deflate_state *s;
-{
+#if defined(__has_feature)
+#  if __has_feature(memory_sanitizer)
+     __attribute__((no_sanitize("memory")))
+#  endif
+#endif
+local void slide_hash(deflate_state *s) {
     unsigned n, m;
     Posf *p;
     uInt wsize = s->w_size;
@@ -245,30 +232,177 @@ local void slide_hash(s)
 #endif
 }
 
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.  All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local unsigned read_buf(z_streamp strm, Bytef *buf, unsigned size) {
+    unsigned len = strm->avail_in;
+
+    if (len > size) len = size;
+    if (len == 0) return 0;
+
+    strm->avail_in  -= len;
+
+    zmemcpy(buf, strm->next_in, len);
+    if (strm->state->wrap == 1) {
+        strm->adler = adler32(strm->adler, buf, len);
+    }
+#ifdef GZIP
+    else if (strm->state->wrap == 2) {
+        strm->adler = crc32(strm->adler, buf, len);
+    }
+#endif
+    strm->next_in  += len;
+    strm->total_in += len;
+
+    return len;
+}
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+local void fill_window(deflate_state *s) {
+    unsigned n;
+    unsigned more;    /* Amount of free space at the end of the window. */
+    uInt wsize = s->w_size;
+
+    Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
+
+    do {
+        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+        /* Deal with !@#$% 64K limit: */
+        if (sizeof(int) <= 2) {
+            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+                more = wsize;
+
+            } else if (more == (unsigned)(-1)) {
+                /* Very unlikely, but possible on 16 bit machine if
+                 * strstart == 0 && lookahead == 1 (input done a byte at time)
+                 */
+                more--;
+            }
+        }
+
+        /* If the window is almost full and there is insufficient lookahead,
+         * move the upper half to the lower one to make room in the upper half.
+         */
+        if (s->strstart >= wsize + MAX_DIST(s)) {
+
+            zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more);
+            s->match_start -= wsize;
+            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
+            s->block_start -= (long) wsize;
+            if (s->insert > s->strstart)
+                s->insert = s->strstart;
+            slide_hash(s);
+            more += wsize;
+        }
+        if (s->strm->avail_in == 0) break;
+
+        /* If there was no sliding:
+         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+         *    more == window_size - lookahead - strstart
+         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+         * => more >= window_size - 2*WSIZE + 2
+         * In the BIG_MEM or MMAP case (not yet supported),
+         *   window_size == input_size + MIN_LOOKAHEAD  &&
+         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+         * Otherwise, window_size == 2*WSIZE so more >= 2.
+         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+         */
+        Assert(more >= 2, "more < 2");
+
+        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+        s->lookahead += n;
+
+        /* Initialize the hash value now that we have some input: */
+        if (s->lookahead + s->insert >= MIN_MATCH) {
+            uInt str = s->strstart - s->insert;
+            s->ins_h = s->window[str];
+            UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
+#if MIN_MATCH != 3
+            Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+            while (s->insert) {
+                UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+                s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+                s->head[s->ins_h] = (Pos)str;
+                str++;
+                s->insert--;
+                if (s->lookahead + s->insert < MIN_MATCH)
+                    break;
+            }
+        }
+        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+         * but this is not important since only literal bytes will be emitted.
+         */
+
+    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+
+    /* If the WIN_INIT bytes after the end of the current data have never been
+     * written, then zero those bytes in order to avoid memory check reports of
+     * the use of uninitialized (or uninitialised as Julian writes) bytes by
+     * the longest match routines.  Update the high water mark for the next
+     * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
+     * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
+     */
+    if (s->high_water < s->window_size) {
+        ulg curr = s->strstart + (ulg)(s->lookahead);
+        ulg init;
+
+        if (s->high_water < curr) {
+            /* Previous high water mark below current data -- zero WIN_INIT
+             * bytes or up to end of window, whichever is less.
+             */
+            init = s->window_size - curr;
+            if (init > WIN_INIT)
+                init = WIN_INIT;
+            zmemzero(s->window + curr, (unsigned)init);
+            s->high_water = curr + init;
+        }
+        else if (s->high_water < (ulg)curr + WIN_INIT) {
+            /* High water mark at or above current data, but below current data
+             * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
+             * to end of window, whichever is less.
+             */
+            init = (ulg)curr + WIN_INIT - s->high_water;
+            if (init > s->window_size - s->high_water)
+                init = s->window_size - s->high_water;
+            zmemzero(s->window + s->high_water, (unsigned)init);
+            s->high_water += init;
+        }
+    }
+
+    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
+           "not enough room for search");
+}
+
 /* ========================================================================= */
-int ZEXPORT deflateInit_(strm, level, version, stream_size)
-    z_streamp strm;
-    int level;
-    const char *version;
-    int stream_size;
-{
+int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version,
+                         int stream_size) {
     return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
                          Z_DEFAULT_STRATEGY, version, stream_size);
     /* To do: ignore strm->next_in if we use it as window */
 }
 
 /* ========================================================================= */
-int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
-                  version, stream_size)
-    z_streamp strm;
-    int  level;
-    int  method;
-    int  windowBits;
-    int  memLevel;
-    int  strategy;
-    const char *version;
-    int stream_size;
-{
+int ZEXPORT deflateInit2_(z_streamp strm, int level, int method,
+                          int windowBits, int memLevel, int strategy,
+                          const char *version, int stream_size) {
     deflate_state *s;
     int wrap = 1;
     static const char my_version[] = ZLIB_VERSION;
@@ -383,7 +517,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
      * symbols from which it is being constructed.
      */
 
-    s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4);
+    s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS);
     s->pending_buf_size = (ulg)s->lit_bufsize * 4;
 
     if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
@@ -393,8 +527,14 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
         deflateEnd (strm);
         return Z_MEM_ERROR;
     }
+#ifdef LIT_MEM
+    s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1));
+    s->l_buf = s->pending_buf + (s->lit_bufsize << 2);
+    s->sym_end = s->lit_bufsize - 1;
+#else
     s->sym_buf = s->pending_buf + s->lit_bufsize;
     s->sym_end = (s->lit_bufsize - 1) * 3;
+#endif
     /* We avoid equality with lit_bufsize*3 because of wraparound at 64K
      * on 16 bit machines and because stored blocks are restricted to
      * 64K-1 bytes.
@@ -410,9 +550,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
 /* =========================================================================
  * Check for a valid deflate stream state. Return 0 if ok, 1 if not.
  */
-local int deflateStateCheck(strm)
-    z_streamp strm;
-{
+local int deflateStateCheck(z_streamp strm) {
     deflate_state *s;
     if (strm == Z_NULL ||
         strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
@@ -433,11 +571,8 @@ local int deflateStateCheck(strm)
 }
 
 /* ========================================================================= */
-int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength)
-    z_streamp strm;
-    const Bytef *dictionary;
-    uInt  dictLength;
-{
+int ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary,
+                                 uInt  dictLength) {
     deflate_state *s;
     uInt str, n;
     int wrap;
@@ -502,11 +637,8 @@ int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength)
 }
 
 /* ========================================================================= */
-int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength)
-    z_streamp strm;
-    Bytef *dictionary;
-    uInt  *dictLength;
-{
+int ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary,
+                                 uInt *dictLength) {
     deflate_state *s;
     uInt len;
 
@@ -524,9 +656,7 @@ int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength)
 }
 
 /* ========================================================================= */
-int ZEXPORT deflateResetKeep(strm)
-    z_streamp strm;
-{
+int ZEXPORT deflateResetKeep(z_streamp strm) {
     deflate_state *s;
 
     if (deflateStateCheck(strm)) {
@@ -561,10 +691,32 @@ int ZEXPORT deflateResetKeep(strm)
     return Z_OK;
 }
 
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init(deflate_state *s) {
+    s->window_size = (ulg)2L*s->w_size;
+
+    CLEAR_HASH(s);
+
+    /* Set the default configuration parameters:
+     */
+    s->max_lazy_match   = configuration_table[s->level].max_lazy;
+    s->good_match       = configuration_table[s->level].good_length;
+    s->nice_match       = configuration_table[s->level].nice_length;
+    s->max_chain_length = configuration_table[s->level].max_chain;
+
+    s->strstart = 0;
+    s->block_start = 0L;
+    s->lookahead = 0;
+    s->insert = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    s->ins_h = 0;
+}
+
 /* ========================================================================= */
-int ZEXPORT deflateReset(strm)
-    z_streamp strm;
-{
+int ZEXPORT deflateReset(z_streamp strm) {
     int ret;
 
     ret = deflateResetKeep(strm);
@@ -574,10 +726,7 @@ int ZEXPORT deflateReset(strm)
 }
 
 /* ========================================================================= */
-int ZEXPORT deflateSetHeader(strm, head)
-    z_streamp strm;
-    gz_headerp head;
-{
+int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) {
     if (deflateStateCheck(strm) || strm->state->wrap != 2)
         return Z_STREAM_ERROR;
     strm->state->gzhead = head;
@@ -585,11 +734,7 @@ int ZEXPORT deflateSetHeader(strm, head)
 }
 
 /* ========================================================================= */
-int ZEXPORT deflatePending(strm, pending, bits)
-    unsigned *pending;
-    int *bits;
-    z_streamp strm;
-{
+int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) {
     if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
     if (pending != Z_NULL)
         *pending = strm->state->pending;
@@ -599,19 +744,21 @@ int ZEXPORT deflatePending(strm, pending, bits)
 }
 
 /* ========================================================================= */
-int ZEXPORT deflatePrime(strm, bits, value)
-    z_streamp strm;
-    int bits;
-    int value;
-{
+int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) {
     deflate_state *s;
     int put;
 
     if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
     s = strm->state;
+#ifdef LIT_MEM
+    if (bits < 0 || bits > 16 ||
+        (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3))
+        return Z_BUF_ERROR;
+#else
     if (bits < 0 || bits > 16 ||
         s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3))
         return Z_BUF_ERROR;
+#endif
     do {
         put = Buf_size - s->bi_valid;
         if (put > bits)
@@ -626,11 +773,7 @@ int ZEXPORT deflatePrime(strm, bits, value)
 }
 
 /* ========================================================================= */
-int ZEXPORT deflateParams(strm, level, strategy)
-    z_streamp strm;
-    int level;
-    int strategy;
-{
+int ZEXPORT deflateParams(z_streamp strm, int level, int strategy) {
     deflate_state *s;
     compress_func func;
 
@@ -675,13 +818,8 @@ int ZEXPORT deflateParams(strm, level, strategy)
 }
 
 /* ========================================================================= */
-int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
-    z_streamp strm;
-    int good_length;
-    int max_lazy;
-    int nice_length;
-    int max_chain;
-{
+int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy,
+                        int nice_length, int max_chain) {
     deflate_state *s;
 
     if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -717,10 +855,7 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
  *
  * Shifts are used to approximate divisions, for speed.
  */
-uLong ZEXPORT deflateBound(strm, sourceLen)
-    z_streamp strm;
-    uLong sourceLen;
-{
+uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) {
     deflate_state *s;
     uLong fixedlen, storelen, wraplen;
 
@@ -776,7 +911,8 @@ uLong ZEXPORT deflateBound(strm, sourceLen)
 
     /* if not default parameters, return one of the conservative bounds */
     if (s->w_bits != 15 || s->hash_bits != 8 + 7)
-        return (s->w_bits <= s->hash_bits ? fixedlen : storelen) + wraplen;
+        return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) +
+               wraplen;
 
     /* default settings: return tight bound for that case -- ~0.03% overhead
        plus a small constant */
@@ -789,10 +925,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen)
  * IN assertion: the stream state is correct and there is enough room in
  * pending_buf.
  */
-local void putShortMSB(s, b)
-    deflate_state *s;
-    uInt b;
-{
+local void putShortMSB(deflate_state *s, uInt b) {
     put_byte(s, (Byte)(b >> 8));
     put_byte(s, (Byte)(b & 0xff));
 }
@@ -803,9 +936,7 @@ local void putShortMSB(s, b)
  * applications may wish to modify it to avoid allocating a large
  * strm->next_out buffer and copying into it. (See also read_buf()).
  */
-local void flush_pending(strm)
-    z_streamp strm;
-{
+local void flush_pending(z_streamp strm) {
     unsigned len;
     deflate_state *s = strm->state;
 
@@ -836,10 +967,7 @@ local void flush_pending(strm)
     } while (0)
 
 /* ========================================================================= */
-int ZEXPORT deflate(strm, flush)
-    z_streamp strm;
-    int flush;
-{
+int ZEXPORT deflate(z_streamp strm, int flush) {
     int old_flush; /* value of flush param for previous deflate call */
     deflate_state *s;
 
@@ -1151,9 +1279,7 @@ int ZEXPORT deflate(strm, flush)
 }
 
 /* ========================================================================= */
-int ZEXPORT deflateEnd(strm)
-    z_streamp strm;
-{
+int ZEXPORT deflateEnd(z_streamp strm) {
     int status;
 
     if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -1177,11 +1303,10 @@ int ZEXPORT deflateEnd(strm)
  * To simplify the source, this is not supported for 16-bit MSDOS (which
  * doesn't have enough memory anyway to duplicate compression states).
  */
-int ZEXPORT deflateCopy(dest, source)
-    z_streamp dest;
-    z_streamp source;
-{
+int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) {
 #ifdef MAXSEG_64K
+    (void)dest;
+    (void)source;
     return Z_STREAM_ERROR;
 #else
     deflate_state *ds;
@@ -1205,7 +1330,7 @@ int ZEXPORT deflateCopy(dest, source)
     ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
     ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
     ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
-    ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4);
+    ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS);
 
     if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
         ds->pending_buf == Z_NULL) {
@@ -1216,10 +1341,15 @@ int ZEXPORT deflateCopy(dest, source)
     zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
     zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
     zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
-    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+    zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS);
 
     ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+#ifdef LIT_MEM
+    ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1));
+    ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2);
+#else
     ds->sym_buf = ds->pending_buf + ds->lit_bufsize;
+#endif
 
     ds->l_desc.dyn_tree = ds->dyn_ltree;
     ds->d_desc.dyn_tree = ds->dyn_dtree;
@@ -1229,66 +1359,6 @@ int ZEXPORT deflateCopy(dest, source)
 #endif /* MAXSEG_64K */
 }
 
-/* ===========================================================================
- * Read a new buffer from the current input stream, update the adler32
- * and total number of bytes read.  All deflate() input goes through
- * this function so some applications may wish to modify it to avoid
- * allocating a large strm->next_in buffer and copying from it.
- * (See also flush_pending()).
- */
-local unsigned read_buf(strm, buf, size)
-    z_streamp strm;
-    Bytef *buf;
-    unsigned size;
-{
-    unsigned len = strm->avail_in;
-
-    if (len > size) len = size;
-    if (len == 0) return 0;
-
-    strm->avail_in  -= len;
-
-    zmemcpy(buf, strm->next_in, len);
-    if (strm->state->wrap == 1) {
-        strm->adler = adler32(strm->adler, buf, len);
-    }
-#ifdef GZIP
-    else if (strm->state->wrap == 2) {
-        strm->adler = crc32(strm->adler, buf, len);
-    }
-#endif
-    strm->next_in  += len;
-    strm->total_in += len;
-
-    return len;
-}
-
-/* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
-local void lm_init(s)
-    deflate_state *s;
-{
-    s->window_size = (ulg)2L*s->w_size;
-
-    CLEAR_HASH(s);
-
-    /* Set the default configuration parameters:
-     */
-    s->max_lazy_match   = configuration_table[s->level].max_lazy;
-    s->good_match       = configuration_table[s->level].good_length;
-    s->nice_match       = configuration_table[s->level].nice_length;
-    s->max_chain_length = configuration_table[s->level].max_chain;
-
-    s->strstart = 0;
-    s->block_start = 0L;
-    s->lookahead = 0;
-    s->insert = 0;
-    s->match_length = s->prev_length = MIN_MATCH-1;
-    s->match_available = 0;
-    s->ins_h = 0;
-}
-
 #ifndef FASTEST
 /* ===========================================================================
  * Set match_start to the longest match starting at the given string and
@@ -1299,10 +1369,7 @@ local void lm_init(s)
  *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
  * OUT assertion: the match length is not greater than s->lookahead.
  */
-local uInt longest_match(s, cur_match)
-    deflate_state *s;
-    IPos cur_match;                             /* current match */
-{
+local uInt longest_match(deflate_state *s, IPos cur_match) {
     unsigned chain_length = s->max_chain_length;/* max hash chain length */
     register Bytef *scan = s->window + s->strstart; /* current string */
     register Bytef *match;                      /* matched string */
@@ -1450,10 +1517,7 @@ local uInt longest_match(s, cur_match)
 /* ---------------------------------------------------------------------------
  * Optimized version for FASTEST only
  */
-local uInt longest_match(s, cur_match)
-    deflate_state *s;
-    IPos cur_match;                             /* current match */
-{
+local uInt longest_match(deflate_state *s, IPos cur_match) {
     register Bytef *scan = s->window + s->strstart; /* current string */
     register Bytef *match;                       /* matched string */
     register int len;                           /* length of current match */
@@ -1514,19 +1578,23 @@ local uInt longest_match(s, cur_match)
 /* ===========================================================================
  * Check that the match at match_start is indeed a match.
  */
-local void check_match(s, start, match, length)
-    deflate_state *s;
-    IPos start, match;
-    int length;
-{
+local void check_match(deflate_state *s, IPos start, IPos match, int length) {
     /* check that the match is indeed a match */
-    if (zmemcmp(s->window + match,
-                s->window + start, length) != EQUAL) {
-        fprintf(stderr, " start %u, match %u, length %d\n",
-                start, match, length);
+    Bytef *back = s->window + (int)match, *here = s->window + start;
+    IPos len = length;
+    if (match == (IPos)-1) {
+        /* match starts one byte before the current window -- just compare the
+           subsequent length-1 bytes */
+        back++;
+        here++;
+        len--;
+    }
+    if (zmemcmp(back, here, len) != EQUAL) {
+        fprintf(stderr, " start %u, match %d, length %d\n",
+                start, (int)match, length);
         do {
-            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
-        } while (--length != 0);
+            fprintf(stderr, "(%02x %02x)", *back++, *here++);
+        } while (--len != 0);
         z_error("invalid match");
     }
     if (z_verbose > 1) {
@@ -1538,137 +1606,6 @@ local void check_match(s, start, match, length)
 #  define check_match(s, start, match, length)
 #endif /* ZLIB_DEBUG */
 
-/* ===========================================================================
- * Fill the window when the lookahead becomes insufficient.
- * Updates strstart and lookahead.
- *
- * IN assertion: lookahead < MIN_LOOKAHEAD
- * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- *    At least one byte has been read, or avail_in == 0; reads are
- *    performed for at least two bytes (required for the zip translate_eol
- *    option -- not supported here).
- */
-local void fill_window(s)
-    deflate_state *s;
-{
-    unsigned n;
-    unsigned more;    /* Amount of free space at the end of the window. */
-    uInt wsize = s->w_size;
-
-    Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
-
-    do {
-        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-
-        /* Deal with !@#$% 64K limit: */
-        if (sizeof(int) <= 2) {
-            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
-                more = wsize;
-
-            } else if (more == (unsigned)(-1)) {
-                /* Very unlikely, but possible on 16 bit machine if
-                 * strstart == 0 && lookahead == 1 (input done a byte at time)
-                 */
-                more--;
-            }
-        }
-
-        /* If the window is almost full and there is insufficient lookahead,
-         * move the upper half to the lower one to make room in the upper half.
-         */
-        if (s->strstart >= wsize + MAX_DIST(s)) {
-
-            zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more);
-            s->match_start -= wsize;
-            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
-            s->block_start -= (long) wsize;
-            if (s->insert > s->strstart)
-                s->insert = s->strstart;
-            slide_hash(s);
-            more += wsize;
-        }
-        if (s->strm->avail_in == 0) break;
-
-        /* If there was no sliding:
-         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
-         *    more == window_size - lookahead - strstart
-         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
-         * => more >= window_size - 2*WSIZE + 2
-         * In the BIG_MEM or MMAP case (not yet supported),
-         *   window_size == input_size + MIN_LOOKAHEAD  &&
-         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
-         * Otherwise, window_size == 2*WSIZE so more >= 2.
-         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
-         */
-        Assert(more >= 2, "more < 2");
-
-        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
-        s->lookahead += n;
-
-        /* Initialize the hash value now that we have some input: */
-        if (s->lookahead + s->insert >= MIN_MATCH) {
-            uInt str = s->strstart - s->insert;
-            s->ins_h = s->window[str];
-            UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
-#if MIN_MATCH != 3
-            Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
-            while (s->insert) {
-                UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
-#ifndef FASTEST
-                s->prev[str & s->w_mask] = s->head[s->ins_h];
-#endif
-                s->head[s->ins_h] = (Pos)str;
-                str++;
-                s->insert--;
-                if (s->lookahead + s->insert < MIN_MATCH)
-                    break;
-            }
-        }
-        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
-         * but this is not important since only literal bytes will be emitted.
-         */
-
-    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-
-    /* If the WIN_INIT bytes after the end of the current data have never been
-     * written, then zero those bytes in order to avoid memory check reports of
-     * the use of uninitialized (or uninitialised as Julian writes) bytes by
-     * the longest match routines.  Update the high water mark for the next
-     * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
-     * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
-     */
-    if (s->high_water < s->window_size) {
-        ulg curr = s->strstart + (ulg)(s->lookahead);
-        ulg init;
-
-        if (s->high_water < curr) {
-            /* Previous high water mark below current data -- zero WIN_INIT
-             * bytes or up to end of window, whichever is less.
-             */
-            init = s->window_size - curr;
-            if (init > WIN_INIT)
-                init = WIN_INIT;
-            zmemzero(s->window + curr, (unsigned)init);
-            s->high_water = curr + init;
-        }
-        else if (s->high_water < (ulg)curr + WIN_INIT) {
-            /* High water mark at or above current data, but below current data
-             * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
-             * to end of window, whichever is less.
-             */
-            init = (ulg)curr + WIN_INIT - s->high_water;
-            if (init > s->window_size - s->high_water)
-                init = s->window_size - s->high_water;
-            zmemzero(s->window + s->high_water, (unsigned)init);
-            s->high_water += init;
-        }
-    }
-
-    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
-           "not enough room for search");
-}
-
 /* ===========================================================================
  * Flush the current block, with given end-of-file flag.
  * IN assertion: strstart is set to the end of the current match.
@@ -1711,10 +1648,7 @@ local void fill_window(s)
  * copied. It is most efficient with large input and output buffers, which
  * maximizes the opportunities to have a single copy from next_in to next_out.
  */
-local block_state deflate_stored(s, flush)
-    deflate_state *s;
-    int flush;
-{
+local block_state deflate_stored(deflate_state *s, int flush) {
     /* Smallest worthy block size when not flushing or finishing. By default
      * this is 32K. This can be as small as 507 bytes for memLevel == 1. For
      * large input and output buffers, the stored block size will be larger.
@@ -1898,10 +1832,7 @@ local block_state deflate_stored(s, flush)
  * new strings in the dictionary only for unmatched strings or for short
  * matches. It is used only for the fast compression options.
  */
-local block_state deflate_fast(s, flush)
-    deflate_state *s;
-    int flush;
-{
+local block_state deflate_fast(deflate_state *s, int flush) {
     IPos hash_head;       /* head of the hash chain */
     int bflush;           /* set if current block must be flushed */
 
@@ -2000,10 +1931,7 @@ local block_state deflate_fast(s, flush)
  * evaluation for matches: a match is finally adopted only if there is
  * no better match at the next window position.
  */
-local block_state deflate_slow(s, flush)
-    deflate_state *s;
-    int flush;
-{
+local block_state deflate_slow(deflate_state *s, int flush) {
     IPos hash_head;          /* head of hash chain */
     int bflush;              /* set if current block must be flushed */
 
@@ -2131,10 +2059,7 @@ local block_state deflate_slow(s, flush)
  * one.  Do not maintain a hash table.  (It will be regenerated if this run of
  * deflate switches away from Z_RLE.)
  */
-local block_state deflate_rle(s, flush)
-    deflate_state *s;
-    int flush;
-{
+local block_state deflate_rle(deflate_state *s, int flush) {
     int bflush;             /* set if current block must be flushed */
     uInt prev;              /* byte at distance one to match */
     Bytef *scan, *strend;   /* scan goes up to strend for length of run */
@@ -2205,10 +2130,7 @@ local block_state deflate_rle(s, flush)
  * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
  * (It will be regenerated if this run of deflate switches away from Huffman.)
  */
-local block_state deflate_huff(s, flush)
-    deflate_state *s;
-    int flush;
-{
+local block_state deflate_huff(deflate_state *s, int flush) {
     int bflush;             /* set if current block must be flushed */
 
     for (;;) {
diff --git a/src/java.base/share/native/libzip/zlib/deflate.h b/src/java.base/share/native/libzip/zlib/deflate.h
index b73f5a04e14..830d46b8894 100644
--- a/src/java.base/share/native/libzip/zlib/deflate.h
+++ b/src/java.base/share/native/libzip/zlib/deflate.h
@@ -23,7 +23,7 @@
  */
 
 /* deflate.h -- internal compression state
- * Copyright (C) 1995-2018 Jean-loup Gailly
+ * Copyright (C) 1995-2024 Jean-loup Gailly
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -47,6 +47,10 @@
 #  define GZIP
 #endif
 
+/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at
+   the cost of a larger memory footprint */
+/* #define LIT_MEM */
+
 /* ===========================================================================
  * Internal compression state.
  */
@@ -241,7 +245,14 @@ typedef struct internal_state {
     /* Depth of each subtree used as tie breaker for trees of equal frequency
      */
 
+#ifdef LIT_MEM
+#   define LIT_BUFS 5
+    ushf *d_buf;          /* buffer for distances */
+    uchf *l_buf;          /* buffer for literals/lengths */
+#else
+#   define LIT_BUFS 4
     uchf *sym_buf;        /* buffer for distances and literals/lengths */
+#endif
 
     uInt  lit_bufsize;
     /* Size of match buffer for literals/lengths.  There are 4 reasons for
@@ -263,7 +274,7 @@ typedef struct internal_state {
      *   - I can't count above 4
      */
 
-    uInt sym_next;      /* running index in sym_buf */
+    uInt sym_next;      /* running index in symbol buffer */
     uInt sym_end;       /* symbol table full when sym_next reaches this */
 
     ulg opt_len;        /* bit length of current block with optimal trees */
@@ -315,14 +326,14 @@ typedef struct internal_state {
    memory checker errors from longest match routines */
 
         /* in trees.c */
-void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
-int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
-                        ulg stored_len, int last));
-void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
-void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
-void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
-                        ulg stored_len, int last));
+void ZLIB_INTERNAL _tr_init(deflate_state *s);
+int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc);
+void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf,
+                                   ulg stored_len, int last);
+void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s);
+void ZLIB_INTERNAL _tr_align(deflate_state *s);
+void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf,
+                                    ulg stored_len, int last);
 
 #define d_code(dist) \
    ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
@@ -342,6 +353,25 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
   extern const uch ZLIB_INTERNAL _dist_code[];
 #endif
 
+#ifdef LIT_MEM
+# define _tr_tally_lit(s, c, flush) \
+  { uch cc = (c); \
+    s->d_buf[s->sym_next] = 0; \
+    s->l_buf[s->sym_next++] = cc; \
+    s->dyn_ltree[cc].Freq++; \
+    flush = (s->sym_next == s->sym_end); \
+   }
+# define _tr_tally_dist(s, distance, length, flush) \
+  { uch len = (uch)(length); \
+    ush dist = (ush)(distance); \
+    s->d_buf[s->sym_next] = dist; \
+    s->l_buf[s->sym_next++] = len; \
+    dist--; \
+    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+    s->dyn_dtree[d_code(dist)].Freq++; \
+    flush = (s->sym_next == s->sym_end); \
+  }
+#else
 # define _tr_tally_lit(s, c, flush) \
   { uch cc = (c); \
     s->sym_buf[s->sym_next++] = 0; \
@@ -361,6 +391,7 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
     s->dyn_dtree[d_code(dist)].Freq++; \
     flush = (s->sym_next == s->sym_end); \
   }
+#endif
 #else
 # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
 # define _tr_tally_dist(s, distance, length, flush) \
diff --git a/src/java.base/share/native/libzip/zlib/gzclose.c b/src/java.base/share/native/libzip/zlib/gzclose.c
index 5cce4b03d2f..eff53ace042 100644
--- a/src/java.base/share/native/libzip/zlib/gzclose.c
+++ b/src/java.base/share/native/libzip/zlib/gzclose.c
@@ -32,9 +32,7 @@
 /* gzclose() is in a separate file so that it is linked in only if it is used.
    That way the other gzclose functions can be used instead to avoid linking in
    unneeded compression or decompression routines. */
-int ZEXPORT gzclose(file)
-    gzFile file;
-{
+int ZEXPORT gzclose(gzFile file) {
 #ifndef NO_GZCOMPRESS
     gz_statep state;
 
diff --git a/src/java.base/share/native/libzip/zlib/gzguts.h b/src/java.base/share/native/libzip/zlib/gzguts.h
index 81bedce5445..8cce2c69d24 100644
--- a/src/java.base/share/native/libzip/zlib/gzguts.h
+++ b/src/java.base/share/native/libzip/zlib/gzguts.h
@@ -23,7 +23,7 @@
  */
 
 /* gzguts.h -- zlib internal header definitions for gz* operations
- * Copyright (C) 2004-2019 Mark Adler
+ * Copyright (C) 2004-2024 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -31,9 +31,8 @@
 #  ifndef _LARGEFILE_SOURCE
 #    define _LARGEFILE_SOURCE 1
 #  endif
-#  ifdef _FILE_OFFSET_BITS
-#    undef _FILE_OFFSET_BITS
-#  endif
+#  undef _FILE_OFFSET_BITS
+#  undef _TIME_BITS
 #endif
 
 #ifdef HAVE_HIDDEN
@@ -143,8 +142,8 @@
 
 /* gz* functions always use library allocation functions */
 #ifndef STDC
-  extern voidp  malloc OF((uInt size));
-  extern void   free   OF((voidpf ptr));
+  extern voidp  malloc(uInt size);
+  extern void   free(voidpf ptr);
 #endif
 
 /* get errno and strerror definition */
@@ -162,10 +161,10 @@
 
 /* provide prototypes for these when building zlib without LFS */
 #if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
-    ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
-    ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
-    ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
-    ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+    ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *);
+    ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int);
+    ZEXTERN z_off64_t ZEXPORT gztell64(gzFile);
+    ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile);
 #endif
 
 /* default memLevel */
@@ -227,17 +226,13 @@ typedef struct {
 typedef gz_state FAR *gz_statep;
 
 /* shared functions */
-void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
+void ZLIB_INTERNAL gz_error(gz_statep, int, const char *);
 #if defined UNDER_CE
-char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
+char ZLIB_INTERNAL *gz_strwinerror(DWORD error);
 #endif
 
 /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
    value -- needed when comparing unsigned to z_off64_t, which is signed
    (possible z_off64_t types off_t, off64_t, and long are all signed) */
-#ifdef INT_MAX
-#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
-#else
-unsigned ZLIB_INTERNAL gz_intmax OF((void));
-#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
-#endif
+unsigned ZLIB_INTERNAL gz_intmax(void);
+#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
diff --git a/src/java.base/share/native/libzip/zlib/gzlib.c b/src/java.base/share/native/libzip/zlib/gzlib.c
index 1cbc6d25b16..0f4dfae64a0 100644
--- a/src/java.base/share/native/libzip/zlib/gzlib.c
+++ b/src/java.base/share/native/libzip/zlib/gzlib.c
@@ -23,7 +23,7 @@
  */
 
 /* gzlib.c -- zlib functions common to reading and writing gzip files
- * Copyright (C) 2004-2019 Mark Adler
+ * Copyright (C) 2004-2024 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -39,10 +39,6 @@
 #endif
 #endif
 
-/* Local functions */
-local void gz_reset OF((gz_statep));
-local gzFile gz_open OF((const void *, int, const char *));
-
 #if defined UNDER_CE
 
 /* Map the Windows error number in ERROR to a locale-dependent error message
@@ -54,9 +50,7 @@ local gzFile gz_open OF((const void *, int, const char *));
 
    The gz_strwinerror function does not change the current setting of
    GetLastError. */
-char ZLIB_INTERNAL *gz_strwinerror(error)
-     DWORD error;
-{
+char ZLIB_INTERNAL *gz_strwinerror(DWORD error) {
     static char buf[1024];
 
     wchar_t *msgbuf;
@@ -96,9 +90,7 @@ char ZLIB_INTERNAL *gz_strwinerror(error)
 #endif /* UNDER_CE */
 
 /* Reset gzip file state */
-local void gz_reset(state)
-    gz_statep state;
-{
+local void gz_reset(gz_statep state) {
     state->x.have = 0;              /* no output data available */
     if (state->mode == GZ_READ) {   /* for reading ... */
         state->eof = 0;             /* not at end of file */
@@ -114,11 +106,7 @@ local void gz_reset(state)
 }
 
 /* Open a gzip file either by name or file descriptor. */
-local gzFile gz_open(path, fd, mode)
-    const void *path;
-    int fd;
-    const char *mode;
-{
+local gzFile gz_open(const void *path, int fd, const char *mode) {
     gz_statep state;
     z_size_t len;
     int oflag;
@@ -293,26 +281,17 @@ local gzFile gz_open(path, fd, mode)
 }
 
 /* -- see zlib.h -- */
-gzFile ZEXPORT gzopen(path, mode)
-    const char *path;
-    const char *mode;
-{
+gzFile ZEXPORT gzopen(const char *path, const char *mode) {
     return gz_open(path, -1, mode);
 }
 
 /* -- see zlib.h -- */
-gzFile ZEXPORT gzopen64(path, mode)
-    const char *path;
-    const char *mode;
-{
+gzFile ZEXPORT gzopen64(const char *path, const char *mode) {
     return gz_open(path, -1, mode);
 }
 
 /* -- see zlib.h -- */
-gzFile ZEXPORT gzdopen(fd, mode)
-    int fd;
-    const char *mode;
-{
+gzFile ZEXPORT gzdopen(int fd, const char *mode) {
     char *path;         /* identifier for error messages */
     gzFile gz;
 
@@ -330,19 +309,13 @@ gzFile ZEXPORT gzdopen(fd, mode)
 
 /* -- see zlib.h -- */
 #ifdef WIDECHAR
-gzFile ZEXPORT gzopen_w(path, mode)
-    const wchar_t *path;
-    const char *mode;
-{
+gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) {
     return gz_open(path, -2, mode);
 }
 #endif
 
 /* -- see zlib.h -- */
-int ZEXPORT gzbuffer(file, size)
-    gzFile file;
-    unsigned size;
-{
+int ZEXPORT gzbuffer(gzFile file, unsigned size) {
     gz_statep state;
 
     /* get internal structure and check integrity */
@@ -359,16 +332,14 @@ int ZEXPORT gzbuffer(file, size)
     /* check and set requested size */
     if ((size << 1) < size)
         return -1;              /* need to be able to double it */
-    if (size < 2)
-        size = 2;               /* need two bytes to check magic header */
+    if (size < 8)
+        size = 8;               /* needed to behave well with flushing */
     state->want = size;
     return 0;
 }
 
 /* -- see zlib.h -- */
-int ZEXPORT gzrewind(file)
-    gzFile file;
-{
+int ZEXPORT gzrewind(gzFile file) {
     gz_statep state;
 
     /* get internal structure */
@@ -389,11 +360,7 @@ int ZEXPORT gzrewind(file)
 }
 
 /* -- see zlib.h -- */
-z_off64_t ZEXPORT gzseek64(file, offset, whence)
-    gzFile file;
-    z_off64_t offset;
-    int whence;
-{
+z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) {
     unsigned n;
     z_off64_t ret;
     gz_statep state;
@@ -466,11 +433,7 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence)
 }
 
 /* -- see zlib.h -- */
-z_off_t ZEXPORT gzseek(file, offset, whence)
-    gzFile file;
-    z_off_t offset;
-    int whence;
-{
+z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) {
     z_off64_t ret;
 
     ret = gzseek64(file, (z_off64_t)offset, whence);
@@ -478,9 +441,7 @@ z_off_t ZEXPORT gzseek(file, offset, whence)
 }
 
 /* -- see zlib.h -- */
-z_off64_t ZEXPORT gztell64(file)
-    gzFile file;
-{
+z_off64_t ZEXPORT gztell64(gzFile file) {
     gz_statep state;
 
     /* get internal structure and check integrity */
@@ -495,9 +456,7 @@ z_off64_t ZEXPORT gztell64(file)
 }
 
 /* -- see zlib.h -- */
-z_off_t ZEXPORT gztell(file)
-    gzFile file;
-{
+z_off_t ZEXPORT gztell(gzFile file) {
     z_off64_t ret;
 
     ret = gztell64(file);
@@ -505,9 +464,7 @@ z_off_t ZEXPORT gztell(file)
 }
 
 /* -- see zlib.h -- */
-z_off64_t ZEXPORT gzoffset64(file)
-    gzFile file;
-{
+z_off64_t ZEXPORT gzoffset64(gzFile file) {
     z_off64_t offset;
     gz_statep state;
 
@@ -528,9 +485,7 @@ z_off64_t ZEXPORT gzoffset64(file)
 }
 
 /* -- see zlib.h -- */
-z_off_t ZEXPORT gzoffset(file)
-    gzFile file;
-{
+z_off_t ZEXPORT gzoffset(gzFile file) {
     z_off64_t ret;
 
     ret = gzoffset64(file);
@@ -538,9 +493,7 @@ z_off_t ZEXPORT gzoffset(file)
 }
 
 /* -- see zlib.h -- */
-int ZEXPORT gzeof(file)
-    gzFile file;
-{
+int ZEXPORT gzeof(gzFile file) {
     gz_statep state;
 
     /* get internal structure and check integrity */
@@ -555,10 +508,7 @@ int ZEXPORT gzeof(file)
 }
 
 /* -- see zlib.h -- */
-const char * ZEXPORT gzerror(file, errnum)
-    gzFile file;
-    int *errnum;
-{
+const char * ZEXPORT gzerror(gzFile file, int *errnum) {
     gz_statep state;
 
     /* get internal structure and check integrity */
@@ -576,9 +526,7 @@ const char * ZEXPORT gzerror(file, errnum)
 }
 
 /* -- see zlib.h -- */
-void ZEXPORT gzclearerr(file)
-    gzFile file;
-{
+void ZEXPORT gzclearerr(gzFile file) {
     gz_statep state;
 
     /* get internal structure and check integrity */
@@ -602,11 +550,7 @@ void ZEXPORT gzclearerr(file)
    memory).  Simply save the error message as a static string.  If there is an
    allocation failure constructing the error message, then convert the error to
    out of memory. */
-void ZLIB_INTERNAL gz_error(state, err, msg)
-    gz_statep state;
-    int err;
-    const char *msg;
-{
+void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) {
     /* free previously allocated message and clear */
     if (state->msg != NULL) {
         if (state->err != Z_MEM_ERROR)
@@ -643,21 +587,20 @@ void ZLIB_INTERNAL gz_error(state, err, msg)
 #endif
 }
 
-#ifndef INT_MAX
 /* portably return maximum value for an int (when limits.h presumed not
    available) -- we need to do this to cover cases where 2's complement not
    used, since C standard permits 1's complement and sign-bit representations,
    otherwise we could just use ((unsigned)-1) >> 1 */
-unsigned ZLIB_INTERNAL gz_intmax()
-{
-    unsigned p, q;
-
-    p = 1;
+unsigned ZLIB_INTERNAL gz_intmax(void) {
+#ifdef INT_MAX
+    return INT_MAX;
+#else
+    unsigned p = 1, q;
     do {
         q = p;
         p <<= 1;
         p++;
     } while (p > q);
     return q >> 1;
-}
 #endif
+}
diff --git a/src/java.base/share/native/libzip/zlib/gzread.c b/src/java.base/share/native/libzip/zlib/gzread.c
index fbe4281b4e0..7b9c9df5fa1 100644
--- a/src/java.base/share/native/libzip/zlib/gzread.c
+++ b/src/java.base/share/native/libzip/zlib/gzread.c
@@ -29,25 +29,12 @@
 
 #include "gzguts.h"
 
-/* Local functions */
-local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
-local int gz_avail OF((gz_statep));
-local int gz_look OF((gz_statep));
-local int gz_decomp OF((gz_statep));
-local int gz_fetch OF((gz_statep));
-local int gz_skip OF((gz_statep, z_off64_t));
-local z_size_t gz_read OF((gz_statep, voidp, z_size_t));
-
 /* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from
    state->fd, and update state->eof, state->err, and state->msg as appropriate.
    This function needs to loop on read(), since read() is not guaranteed to
    read the number of bytes requested, depending on the type of descriptor. */
-local int gz_load(state, buf, len, have)
-    gz_statep state;
-    unsigned char *buf;
-    unsigned len;
-    unsigned *have;
-{
+local int gz_load(gz_statep state, unsigned char *buf, unsigned len,
+                  unsigned *have) {
     int ret;
     unsigned get, max = ((unsigned)-1 >> 2) + 1;
 
@@ -77,9 +64,7 @@ local int gz_load(state, buf, len, have)
    If strm->avail_in != 0, then the current data is moved to the beginning of
    the input buffer, and then the remainder of the buffer is loaded with the
    available data from the input file. */
-local int gz_avail(state)
-    gz_statep state;
-{
+local int gz_avail(gz_statep state) {
     unsigned got;
     z_streamp strm = &(state->strm);
 
@@ -112,9 +97,7 @@ local int gz_avail(state)
    case, all further file reads will be directly to either the output buffer or
    a user buffer.  If decompressing, the inflate state will be initialized.
    gz_look() will return 0 on success or -1 on failure. */
-local int gz_look(state)
-    gz_statep state;
-{
+local int gz_look(gz_statep state) {
     z_streamp strm = &(state->strm);
 
     /* allocate read buffers and inflate memory */
@@ -194,9 +177,7 @@ local int gz_look(state)
    data.  If the gzip stream completes, state->how is reset to LOOK to look for
    the next gzip stream or raw data, once state->x.have is depleted.  Returns 0
    on success, -1 on failure. */
-local int gz_decomp(state)
-    gz_statep state;
-{
+local int gz_decomp(gz_statep state) {
     int ret = Z_OK;
     unsigned had;
     z_streamp strm = &(state->strm);
@@ -248,9 +229,7 @@ local int gz_decomp(state)
    looked for to determine whether to copy or decompress.  Returns -1 on error,
    otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the
    end of the input file has been reached and all data has been processed.  */
-local int gz_fetch(state)
-    gz_statep state;
-{
+local int gz_fetch(gz_statep state) {
     z_streamp strm = &(state->strm);
 
     do {
@@ -278,10 +257,7 @@ local int gz_fetch(state)
 }
 
 /* Skip len uncompressed bytes of output.  Return -1 on error, 0 on success. */
-local int gz_skip(state, len)
-    gz_statep state;
-    z_off64_t len;
-{
+local int gz_skip(gz_statep state, z_off64_t len) {
     unsigned n;
 
     /* skip over len bytes or reach end-of-file, whichever comes first */
@@ -313,11 +289,7 @@ local int gz_skip(state, len)
    input.  Return the number of bytes read.  If zero is returned, either the
    end of file was reached, or there was an error.  state->err must be
    consulted in that case to determine which. */
-local z_size_t gz_read(state, buf, len)
-    gz_statep state;
-    voidp buf;
-    z_size_t len;
-{
+local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) {
     z_size_t got;
     unsigned n;
 
@@ -394,11 +366,7 @@ local z_size_t gz_read(state, buf, len)
 }
 
 /* -- see zlib.h -- */
-int ZEXPORT gzread(file, buf, len)
-    gzFile file;
-    voidp buf;
-    unsigned len;
-{
+int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) {
     gz_statep state;
 
     /* get internal structure */
@@ -430,12 +398,7 @@ int ZEXPORT gzread(file, buf, len)
 }
 
 /* -- see zlib.h -- */
-z_size_t ZEXPORT gzfread(buf, size, nitems, file)
-    voidp buf;
-    z_size_t size;
-    z_size_t nitems;
-    gzFile file;
-{
+z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file) {
     z_size_t len;
     gz_statep state;
 
@@ -466,9 +429,7 @@ z_size_t ZEXPORT gzfread(buf, size, nitems, file)
 #else
 #  undef gzgetc
 #endif
-int ZEXPORT gzgetc(file)
-    gzFile file;
-{
+int ZEXPORT gzgetc(gzFile file) {
     unsigned char buf[1];
     gz_statep state;
 
@@ -493,17 +454,12 @@ int ZEXPORT gzgetc(file)
     return gz_read(state, buf, 1) < 1 ? -1 : buf[0];
 }
 
-int ZEXPORT gzgetc_(file)
-gzFile file;
-{
+int ZEXPORT gzgetc_(gzFile file) {
     return gzgetc(file);
 }
 
 /* -- see zlib.h -- */
-int ZEXPORT gzungetc(c, file)
-    int c;
-    gzFile file;
-{
+int ZEXPORT gzungetc(int c, gzFile file) {
     gz_statep state;
 
     /* get internal structure */
@@ -511,6 +467,10 @@ int ZEXPORT gzungetc(c, file)
         return -1;
     state = (gz_statep)file;
 
+    /* in case this was just opened, set up the input buffer */
+    if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
+        (void)gz_look(state);
+
     /* check that we're reading and that there's no (serious) error */
     if (state->mode != GZ_READ ||
         (state->err != Z_OK && state->err != Z_BUF_ERROR))
@@ -560,11 +520,7 @@ int ZEXPORT gzungetc(c, file)
 }
 
 /* -- see zlib.h -- */
-char * ZEXPORT gzgets(file, buf, len)
-    gzFile file;
-    char *buf;
-    int len;
-{
+char * ZEXPORT gzgets(gzFile file, char *buf, int len) {
     unsigned left, n;
     char *str;
     unsigned char *eol;
@@ -624,9 +580,7 @@ char * ZEXPORT gzgets(file, buf, len)
 }
 
 /* -- see zlib.h -- */
-int ZEXPORT gzdirect(file)
-    gzFile file;
-{
+int ZEXPORT gzdirect(gzFile file) {
     gz_statep state;
 
     /* get internal structure */
@@ -644,9 +598,7 @@ int ZEXPORT gzdirect(file)
 }
 
 /* -- see zlib.h -- */
-int ZEXPORT gzclose_r(file)
-    gzFile file;
-{
+int ZEXPORT gzclose_r(gzFile file) {
     int ret, err;
     gz_statep state;
 
diff --git a/src/java.base/share/native/libzip/zlib/gzwrite.c b/src/java.base/share/native/libzip/zlib/gzwrite.c
index 3aff44cc940..008b03e7021 100644
--- a/src/java.base/share/native/libzip/zlib/gzwrite.c
+++ b/src/java.base/share/native/libzip/zlib/gzwrite.c
@@ -29,18 +29,10 @@
 
 #include "gzguts.h"
 
-/* Local functions */
-local int gz_init OF((gz_statep));
-local int gz_comp OF((gz_statep, int));
-local int gz_zero OF((gz_statep, z_off64_t));
-local z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
-
 /* Initialize state for writing a gzip file.  Mark initialization by setting
    state->size to non-zero.  Return -1 on a memory allocation failure, or 0 on
    success. */
-local int gz_init(state)
-    gz_statep state;
-{
+local int gz_init(gz_statep state) {
     int ret;
     z_streamp strm = &(state->strm);
 
@@ -94,10 +86,7 @@ local int gz_init(state)
    deflate() flush value.  If flush is Z_FINISH, then the deflate() state is
    reset to start a new gzip stream.  If gz->direct is true, then simply write
    to the output file without compressing, and ignore flush. */
-local int gz_comp(state, flush)
-    gz_statep state;
-    int flush;
-{
+local int gz_comp(gz_statep state, int flush) {
     int ret, writ;
     unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
     z_streamp strm = &(state->strm);
@@ -175,10 +164,7 @@ local int gz_comp(state, flush)
 
 /* Compress len zeros to output.  Return -1 on a write error or memory
    allocation failure by gz_comp(), or 0 on success. */
-local int gz_zero(state, len)
-    gz_statep state;
-    z_off64_t len;
-{
+local int gz_zero(gz_statep state, z_off64_t len) {
     int first;
     unsigned n;
     z_streamp strm = &(state->strm);
@@ -208,11 +194,7 @@ local int gz_zero(state, len)
 
 /* Write len bytes from buf to file.  Return the number of bytes written.  If
    the returned value is less than len, then there was an error. */
-local z_size_t gz_write(state, buf, len)
-    gz_statep state;
-    voidpc buf;
-    z_size_t len;
-{
+local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {
     z_size_t put = len;
 
     /* if len is zero, avoid unnecessary operations */
@@ -276,11 +258,7 @@ local z_size_t gz_write(state, buf, len)
 }
 
 /* -- see zlib.h -- */
-int ZEXPORT gzwrite(file, buf, len)
-    gzFile file;
-    voidpc buf;
-    unsigned len;
-{
+int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) {
     gz_statep state;
 
     /* get internal structure */
@@ -304,12 +282,8 @@ int ZEXPORT gzwrite(file, buf, len)
 }
 
 /* -- see zlib.h -- */
-z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
-    voidpc buf;
-    z_size_t size;
-    z_size_t nitems;
-    gzFile file;
-{
+z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems,
+                          gzFile file) {
     z_size_t len;
     gz_statep state;
 
@@ -334,10 +308,7 @@ z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
 }
 
 /* -- see zlib.h -- */
-int ZEXPORT gzputc(file, c)
-    gzFile file;
-    int c;
-{
+int ZEXPORT gzputc(gzFile file, int c) {
     unsigned have;
     unsigned char buf[1];
     gz_statep state;
@@ -382,10 +353,7 @@ int ZEXPORT gzputc(file, c)
 }
 
 /* -- see zlib.h -- */
-int ZEXPORT gzputs(file, s)
-    gzFile file;
-    const char *s;
-{
+int ZEXPORT gzputs(gzFile file, const char *s) {
     z_size_t len, put;
     gz_statep state;
 
@@ -412,8 +380,7 @@ int ZEXPORT gzputs(file, s)
 #include 
 
 /* -- see zlib.h -- */
-int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
-{
+int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
     int len;
     unsigned left;
     char *next;
@@ -484,8 +451,7 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
     return len;
 }
 
-int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
-{
+int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) {
     va_list va;
     int ret;
 
@@ -498,13 +464,10 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
 #else /* !STDC && !Z_HAVE_STDARG_H */
 
 /* -- see zlib.h -- */
-int ZEXPORTVA gzprintf(file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
-                       a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
-    gzFile file;
-    const char *format;
-    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
-        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
-{
+int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3,
+                       int a4, int a5, int a6, int a7, int a8, int a9, int a10,
+                       int a11, int a12, int a13, int a14, int a15, int a16,
+                       int a17, int a18, int a19, int a20) {
     unsigned len, left;
     char *next;
     gz_statep state;
@@ -586,10 +549,7 @@ int ZEXPORTVA gzprintf(file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
 #endif
 
 /* -- see zlib.h -- */
-int ZEXPORT gzflush(file, flush)
-    gzFile file;
-    int flush;
-{
+int ZEXPORT gzflush(gzFile file, int flush) {
     gz_statep state;
 
     /* get internal structure */
@@ -618,11 +578,7 @@ int ZEXPORT gzflush(file, flush)
 }
 
 /* -- see zlib.h -- */
-int ZEXPORT gzsetparams(file, level, strategy)
-    gzFile file;
-    int level;
-    int strategy;
-{
+int ZEXPORT gzsetparams(gzFile file, int level, int strategy) {
     gz_statep state;
     z_streamp strm;
 
@@ -633,7 +589,7 @@ int ZEXPORT gzsetparams(file, level, strategy)
     strm = &(state->strm);
 
     /* check that we're writing and that there's no error */
-    if (state->mode != GZ_WRITE || state->err != Z_OK)
+    if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct)
         return Z_STREAM_ERROR;
 
     /* if no change is requested, then do nothing */
@@ -660,9 +616,7 @@ int ZEXPORT gzsetparams(file, level, strategy)
 }
 
 /* -- see zlib.h -- */
-int ZEXPORT gzclose_w(file)
-    gzFile file;
-{
+int ZEXPORT gzclose_w(gzFile file) {
     int ret = Z_OK;
     gz_statep state;
 
diff --git a/src/java.base/share/native/libzip/zlib/infback.c b/src/java.base/share/native/libzip/zlib/infback.c
index ea7ea83d8d2..f680e2cdbdc 100644
--- a/src/java.base/share/native/libzip/zlib/infback.c
+++ b/src/java.base/share/native/libzip/zlib/infback.c
@@ -39,9 +39,6 @@
 #include "inflate.h"
 #include "inffast.h"
 
-/* function prototypes */
-local void fixedtables OF((struct inflate_state FAR *state));
-
 /*
    strm provides memory allocation functions in zalloc and zfree, or
    Z_NULL to use the library memory allocation functions.
@@ -49,13 +46,9 @@ local void fixedtables OF((struct inflate_state FAR *state));
    windowBits is in the range 8..15, and window is a user-supplied
    window and output buffer that is 2**windowBits bytes.
  */
-int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
-z_streamp strm;
-int windowBits;
-unsigned char FAR *window;
-const char *version;
-int stream_size;
-{
+int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits,
+                             unsigned char FAR *window, const char *version,
+                             int stream_size) {
     struct inflate_state FAR *state;
 
     if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
@@ -104,9 +97,7 @@ int stream_size;
    used for threaded applications, since the rewriting of the tables and virgin
    may not be thread-safe.
  */
-local void fixedtables(state)
-struct inflate_state FAR *state;
-{
+local void fixedtables(struct inflate_state FAR *state) {
 #ifdef BUILDFIXED
     static int virgin = 1;
     static code *lenfix, *distfix;
@@ -272,13 +263,8 @@ struct inflate_state FAR *state;
    inflateBack() can also return Z_STREAM_ERROR if the input parameters
    are not correct, i.e. strm is Z_NULL or the state was not initialized.
  */
-int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
-z_streamp strm;
-in_func in;
-void FAR *in_desc;
-out_func out;
-void FAR *out_desc;
-{
+int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
+                        out_func out, void FAR *out_desc) {
     struct inflate_state FAR *state;
     z_const unsigned char FAR *next;    /* next input */
     unsigned char FAR *put;     /* next output */
@@ -656,9 +642,7 @@ void FAR *out_desc;
     return ret;
 }
 
-int ZEXPORT inflateBackEnd(strm)
-z_streamp strm;
-{
+int ZEXPORT inflateBackEnd(z_streamp strm) {
     if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
         return Z_STREAM_ERROR;
     ZFREE(strm, strm->state);
diff --git a/src/java.base/share/native/libzip/zlib/inffast.c b/src/java.base/share/native/libzip/zlib/inffast.c
index 45aa17d201f..e86dd78d801 100644
--- a/src/java.base/share/native/libzip/zlib/inffast.c
+++ b/src/java.base/share/native/libzip/zlib/inffast.c
@@ -71,10 +71,7 @@
       requires strm->avail_out >= 258 for each loop to avoid checking for
       output space.
  */
-void ZLIB_INTERNAL inflate_fast(strm, start)
-z_streamp strm;
-unsigned start;         /* inflate()'s starting value for strm->avail_out */
-{
+void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
     struct inflate_state FAR *state;
     z_const unsigned char FAR *in;      /* local strm->next_in */
     z_const unsigned char FAR *last;    /* have enough input while in < last */
diff --git a/src/java.base/share/native/libzip/zlib/inffast.h b/src/java.base/share/native/libzip/zlib/inffast.h
index b8da8bb757a..bc4fb6b0df8 100644
--- a/src/java.base/share/native/libzip/zlib/inffast.h
+++ b/src/java.base/share/native/libzip/zlib/inffast.h
@@ -32,4 +32,4 @@
    subject to change. Applications should only use zlib.h.
  */
 
-void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
+void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start);
diff --git a/src/java.base/share/native/libzip/zlib/inflate.c b/src/java.base/share/native/libzip/zlib/inflate.c
index b236dcafd80..3370cfe9565 100644
--- a/src/java.base/share/native/libzip/zlib/inflate.c
+++ b/src/java.base/share/native/libzip/zlib/inflate.c
@@ -115,20 +115,7 @@
 #  endif
 #endif
 
-/* function prototypes */
-local int inflateStateCheck OF((z_streamp strm));
-local void fixedtables OF((struct inflate_state FAR *state));
-local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
-                           unsigned copy));
-#ifdef BUILDFIXED
-   void makefixed OF((void));
-#endif
-local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
-                              unsigned len));
-
-local int inflateStateCheck(strm)
-z_streamp strm;
-{
+local int inflateStateCheck(z_streamp strm) {
     struct inflate_state FAR *state;
     if (strm == Z_NULL ||
         strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
@@ -140,9 +127,7 @@ z_streamp strm;
     return 0;
 }
 
-int ZEXPORT inflateResetKeep(strm)
-z_streamp strm;
-{
+int ZEXPORT inflateResetKeep(z_streamp strm) {
     struct inflate_state FAR *state;
 
     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -166,9 +151,7 @@ z_streamp strm;
     return Z_OK;
 }
 
-int ZEXPORT inflateReset(strm)
-z_streamp strm;
-{
+int ZEXPORT inflateReset(z_streamp strm) {
     struct inflate_state FAR *state;
 
     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -179,10 +162,7 @@ z_streamp strm;
     return inflateResetKeep(strm);
 }
 
-int ZEXPORT inflateReset2(strm, windowBits)
-z_streamp strm;
-int windowBits;
-{
+int ZEXPORT inflateReset2(z_streamp strm, int windowBits) {
     int wrap;
     struct inflate_state FAR *state;
 
@@ -219,12 +199,8 @@ int windowBits;
     return inflateReset(strm);
 }
 
-int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
-z_streamp strm;
-int windowBits;
-const char *version;
-int stream_size;
-{
+int ZEXPORT inflateInit2_(z_streamp strm, int windowBits,
+                          const char *version, int stream_size) {
     int ret;
     struct inflate_state FAR *state;
 
@@ -263,22 +239,17 @@ int stream_size;
     return ret;
 }
 
-int ZEXPORT inflateInit_(strm, version, stream_size)
-z_streamp strm;
-const char *version;
-int stream_size;
-{
+int ZEXPORT inflateInit_(z_streamp strm, const char *version,
+                         int stream_size) {
     return inflateInit2_(strm, DEF_WBITS, version, stream_size);
 }
 
-int ZEXPORT inflatePrime(strm, bits, value)
-z_streamp strm;
-int bits;
-int value;
-{
+int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) {
     struct inflate_state FAR *state;
 
     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    if (bits == 0)
+        return Z_OK;
     state = (struct inflate_state FAR *)strm->state;
     if (bits < 0) {
         state->hold = 0;
@@ -302,9 +273,7 @@ int value;
    used for threaded applications, since the rewriting of the tables and virgin
    may not be thread-safe.
  */
-local void fixedtables(state)
-struct inflate_state FAR *state;
-{
+local void fixedtables(struct inflate_state FAR *state) {
 #ifdef BUILDFIXED
     static int virgin = 1;
     static code *lenfix, *distfix;
@@ -366,7 +335,7 @@ struct inflate_state FAR *state;
 
     a.out > inffixed.h
  */
-void makefixed()
+void makefixed(void)
 {
     unsigned low, size;
     struct inflate_state state;
@@ -420,11 +389,7 @@ void makefixed()
    output will fall in the output data, making match copies simpler and faster.
    The advantage may be dependent on the size of the processor's data caches.
  */
-local int updatewindow(strm, end, copy)
-z_streamp strm;
-const Bytef *end;
-unsigned copy;
-{
+local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) {
     struct inflate_state FAR *state;
     unsigned dist;
 
@@ -646,10 +611,7 @@ unsigned copy;
    will return Z_BUF_ERROR if it has not reached the end of the stream.
  */
 
-int ZEXPORT inflate(strm, flush)
-z_streamp strm;
-int flush;
-{
+int ZEXPORT inflate(z_streamp strm, int flush) {
     struct inflate_state FAR *state;
     z_const unsigned char FAR *next;    /* next input */
     unsigned char FAR *put;     /* next output */
@@ -1325,9 +1287,7 @@ int flush;
     return ret;
 }
 
-int ZEXPORT inflateEnd(strm)
-z_streamp strm;
-{
+int ZEXPORT inflateEnd(z_streamp strm) {
     struct inflate_state FAR *state;
     if (inflateStateCheck(strm))
         return Z_STREAM_ERROR;
@@ -1339,11 +1299,8 @@ z_streamp strm;
     return Z_OK;
 }
 
-int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
-z_streamp strm;
-Bytef *dictionary;
-uInt *dictLength;
-{
+int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary,
+                                 uInt *dictLength) {
     struct inflate_state FAR *state;
 
     /* check state */
@@ -1362,11 +1319,8 @@ uInt *dictLength;
     return Z_OK;
 }
 
-int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
-z_streamp strm;
-const Bytef *dictionary;
-uInt dictLength;
-{
+int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary,
+                                 uInt dictLength) {
     struct inflate_state FAR *state;
     unsigned long dictid;
     int ret;
@@ -1397,10 +1351,7 @@ uInt dictLength;
     return Z_OK;
 }
 
-int ZEXPORT inflateGetHeader(strm, head)
-z_streamp strm;
-gz_headerp head;
-{
+int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) {
     struct inflate_state FAR *state;
 
     /* check state */
@@ -1425,11 +1376,8 @@ gz_headerp head;
    called again with more data and the *have state.  *have is initialized to
    zero for the first call.
  */
-local unsigned syncsearch(have, buf, len)
-unsigned FAR *have;
-const unsigned char FAR *buf;
-unsigned len;
-{
+local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf,
+                          unsigned len) {
     unsigned got;
     unsigned next;
 
@@ -1448,9 +1396,7 @@ unsigned len;
     return next;
 }
 
-int ZEXPORT inflateSync(strm)
-z_streamp strm;
-{
+int ZEXPORT inflateSync(z_streamp strm) {
     unsigned len;               /* number of bytes to look at or looked at */
     int flags;                  /* temporary to save header status */
     unsigned long in, out;      /* temporary to save total_in and total_out */
@@ -1465,7 +1411,7 @@ z_streamp strm;
     /* if first time, start search in bit buffer */
     if (state->mode != SYNC) {
         state->mode = SYNC;
-        state->hold <<= state->bits & 7;
+        state->hold >>= state->bits & 7;
         state->bits -= state->bits & 7;
         len = 0;
         while (state->bits >= 8) {
@@ -1506,9 +1452,7 @@ z_streamp strm;
    block. When decompressing, PPP checks that at the end of input packet,
    inflate is waiting for these length bytes.
  */
-int ZEXPORT inflateSyncPoint(strm)
-z_streamp strm;
-{
+int ZEXPORT inflateSyncPoint(z_streamp strm) {
     struct inflate_state FAR *state;
 
     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -1516,10 +1460,7 @@ z_streamp strm;
     return state->mode == STORED && state->bits == 0;
 }
 
-int ZEXPORT inflateCopy(dest, source)
-z_streamp dest;
-z_streamp source;
-{
+int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) {
     struct inflate_state FAR *state;
     struct inflate_state FAR *copy;
     unsigned char FAR *window;
@@ -1563,10 +1504,7 @@ z_streamp source;
     return Z_OK;
 }
 
-int ZEXPORT inflateUndermine(strm, subvert)
-z_streamp strm;
-int subvert;
-{
+int ZEXPORT inflateUndermine(z_streamp strm, int subvert) {
     struct inflate_state FAR *state;
 
     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -1581,10 +1519,7 @@ int subvert;
 #endif
 }
 
-int ZEXPORT inflateValidate(strm, check)
-z_streamp strm;
-int check;
-{
+int ZEXPORT inflateValidate(z_streamp strm, int check) {
     struct inflate_state FAR *state;
 
     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -1596,9 +1531,7 @@ int check;
     return Z_OK;
 }
 
-long ZEXPORT inflateMark(strm)
-z_streamp strm;
-{
+long ZEXPORT inflateMark(z_streamp strm) {
     struct inflate_state FAR *state;
 
     if (inflateStateCheck(strm))
@@ -1609,9 +1542,7 @@ z_streamp strm;
             (state->mode == MATCH ? state->was - state->length : 0));
 }
 
-unsigned long ZEXPORT inflateCodesUsed(strm)
-z_streamp strm;
-{
+unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) {
     struct inflate_state FAR *state;
     if (inflateStateCheck(strm)) return (unsigned long)-1;
     state = (struct inflate_state FAR *)strm->state;
diff --git a/src/java.base/share/native/libzip/zlib/inftrees.c b/src/java.base/share/native/libzip/zlib/inftrees.c
index a60b1bfb393..c4913bc4359 100644
--- a/src/java.base/share/native/libzip/zlib/inftrees.c
+++ b/src/java.base/share/native/libzip/zlib/inftrees.c
@@ -23,7 +23,7 @@
  */
 
 /* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2022 Mark Adler
+ * Copyright (C) 1995-2024 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -33,7 +33,7 @@
 #define MAXBITS 15
 
 const char inflate_copyright[] =
-   " inflate 1.2.13 Copyright 1995-2022 Mark Adler ";
+   " inflate 1.3.1 Copyright 1995-2024 Mark Adler ";
 /*
   If you use the zlib library in a product, an acknowledgment is welcome
   in the documentation of your product. If for some reason you cannot
@@ -53,14 +53,9 @@ const char inflate_copyright[] =
    table index bits.  It will differ if the request is greater than the
    longest code or if it is less than the shortest code.
  */
-int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
-codetype type;
-unsigned short FAR *lens;
-unsigned codes;
-code FAR * FAR *table;
-unsigned FAR *bits;
-unsigned short FAR *work;
-{
+int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens,
+                                unsigned codes, code FAR * FAR *table,
+                                unsigned FAR *bits, unsigned short FAR *work) {
     unsigned len;               /* a code's length in bits */
     unsigned sym;               /* index of code symbols */
     unsigned min, max;          /* minimum and maximum code lengths */
@@ -86,7 +81,7 @@ unsigned short FAR *work;
         35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
     static const unsigned short lext[31] = { /* Length codes 257..285 extra */
         16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
-        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 194, 65};
+        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77};
     static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
         1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
         257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
diff --git a/src/java.base/share/native/libzip/zlib/inftrees.h b/src/java.base/share/native/libzip/zlib/inftrees.h
index a05314fefbd..3e2e889301d 100644
--- a/src/java.base/share/native/libzip/zlib/inftrees.h
+++ b/src/java.base/share/native/libzip/zlib/inftrees.h
@@ -65,8 +65,8 @@ typedef struct {
    examples/enough.c found in the zlib distribution.  The arguments to that
    program are the number of symbols, the initial root table size, and the
    maximum bit length of a code.  "enough 286 9 15" for literal/length codes
-   returns returns 852, and "enough 30 6 15" for distance codes returns 592.
-   The initial root table size (9 or 6) is found in the fifth argument of the
+   returns 852, and "enough 30 6 15" for distance codes returns 592. The
+   initial root table size (9 or 6) is found in the fifth argument of the
    inflate_table() calls in inflate.c and infback.c.  If the root table size is
    changed, then these maximum sizes would be need to be recalculated and
    updated. */
@@ -81,6 +81,6 @@ typedef enum {
     DISTS
 } codetype;
 
-int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
-                             unsigned codes, code FAR * FAR *table,
-                             unsigned FAR *bits, unsigned short FAR *work));
+int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens,
+                                unsigned codes, code FAR * FAR *table,
+                                unsigned FAR *bits, unsigned short FAR *work);
diff --git a/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java b/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java
index ff48fdaea06..3296c5f2fad 100644
--- a/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java
+++ b/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java
@@ -1,4 +1,4 @@
-Changes from zlib 1.2.13
+Changes from zlib 1.3.1
 
 (1) renamed adler32.c -> zadler32.c, crc32c -> zcrc32.c
 
diff --git a/src/java.base/share/native/libzip/zlib/trees.c b/src/java.base/share/native/libzip/zlib/trees.c
index 7214373826f..bbfa9deee5b 100644
--- a/src/java.base/share/native/libzip/zlib/trees.c
+++ b/src/java.base/share/native/libzip/zlib/trees.c
@@ -23,7 +23,7 @@
  */
 
 /* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2021 Jean-loup Gailly
+ * Copyright (C) 1995-2024 Jean-loup Gailly
  * detect_data_type() function provided freely by Cosmin Truta, 2006
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
@@ -146,39 +146,116 @@ struct static_tree_desc_s {
     int     max_length;          /* max bit length for the codes */
 };
 
-local const static_tree_desc  static_l_desc =
+#ifdef NO_INIT_GLOBAL_POINTERS
+#  define TCONST
+#else
+#  define TCONST const
+#endif
+
+local TCONST static_tree_desc static_l_desc =
 {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
 
-local const static_tree_desc  static_d_desc =
+local TCONST static_tree_desc static_d_desc =
 {static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
 
-local const static_tree_desc  static_bl_desc =
+local TCONST static_tree_desc static_bl_desc =
 {(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
 
 /* ===========================================================================
- * Local (static) routines in this file.
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+    put_byte(s, (uch)((w) & 0xff)); \
+    put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
  */
+local unsigned bi_reverse(unsigned code, int len) {
+    register unsigned res = 0;
+    do {
+        res |= code & 1;
+        code >>= 1, res <<= 1;
+    } while (--len > 0);
+    return res >> 1;
+}
 
-local void tr_static_init OF((void));
-local void init_block     OF((deflate_state *s));
-local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
-local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
-local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
-local void build_tree     OF((deflate_state *s, tree_desc *desc));
-local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
-local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
-local int  build_bl_tree  OF((deflate_state *s));
-local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
-                              int blcodes));
-local void compress_block OF((deflate_state *s, const ct_data *ltree,
-                              const ct_data *dtree));
-local int  detect_data_type OF((deflate_state *s));
-local unsigned bi_reverse OF((unsigned code, int len));
-local void bi_windup      OF((deflate_state *s));
-local void bi_flush       OF((deflate_state *s));
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(deflate_state *s) {
+    if (s->bi_valid == 16) {
+        put_short(s, s->bi_buf);
+        s->bi_buf = 0;
+        s->bi_valid = 0;
+    } else if (s->bi_valid >= 8) {
+        put_byte(s, (Byte)s->bi_buf);
+        s->bi_buf >>= 8;
+        s->bi_valid -= 8;
+    }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(deflate_state *s) {
+    if (s->bi_valid > 8) {
+        put_short(s, s->bi_buf);
+    } else if (s->bi_valid > 0) {
+        put_byte(s, (Byte)s->bi_buf);
+    }
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef ZLIB_DEBUG
+    s->bits_sent = (s->bits_sent + 7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+local void gen_codes(ct_data *tree, int max_code, ushf *bl_count) {
+    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+    unsigned code = 0;         /* running code value */
+    int bits;                  /* bit index */
+    int n;                     /* code index */
+
+    /* The distribution counts are first used to generate the code values
+     * without bit reversal.
+     */
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+        code = (code + bl_count[bits - 1]) << 1;
+        next_code[bits] = (ush)code;
+    }
+    /* Check that the bit counts in bl_count are consistent. The last code
+     * must be all ones.
+     */
+    Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,
+            "inconsistent bit counts");
+    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+    for (n = 0;  n <= max_code; n++) {
+        int len = tree[n].Len;
+        if (len == 0) continue;
+        /* Now reverse the bits */
+        tree[n].Code = (ush)bi_reverse(next_code[len]++, len);
+
+        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+            n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1));
+    }
+}
 
 #ifdef GEN_TREES_H
-local void gen_trees_header OF((void));
+local void gen_trees_header(void);
 #endif
 
 #ifndef ZLIB_DEBUG
@@ -191,27 +268,12 @@ local void gen_trees_header OF((void));
        send_bits(s, tree[c].Code, tree[c].Len); }
 #endif
 
-/* ===========================================================================
- * Output a short LSB first on the stream.
- * IN assertion: there is enough room in pendingBuf.
- */
-#define put_short(s, w) { \
-    put_byte(s, (uch)((w) & 0xff)); \
-    put_byte(s, (uch)((ush)(w) >> 8)); \
-}
-
 /* ===========================================================================
  * Send a value on a given number of bits.
  * IN assertion: length <= 16 and value fits in length bits.
  */
 #ifdef ZLIB_DEBUG
-local void send_bits      OF((deflate_state *s, int value, int length));
-
-local void send_bits(s, value, length)
-    deflate_state *s;
-    int value;  /* value to send */
-    int length; /* number of bits */
-{
+local void send_bits(deflate_state *s, int value, int length) {
     Tracevv((stderr," l %2d v %4x ", length, value));
     Assert(length > 0 && length <= 15, "invalid length");
     s->bits_sent += (ulg)length;
@@ -253,8 +315,7 @@ local void send_bits(s, value, length)
 /* ===========================================================================
  * Initialize the various 'constant' tables.
  */
-local void tr_static_init()
-{
+local void tr_static_init(void) {
 #if defined(GEN_TREES_H) || !defined(STDC)
     static int static_init_done = 0;
     int n;        /* iterates over tree elements */
@@ -347,8 +408,7 @@ local void tr_static_init()
       ((i) == (last)? "\n};\n\n" :    \
        ((i) % (width) == (width) - 1 ? ",\n" : ", "))
 
-void gen_trees_header()
-{
+void gen_trees_header(void) {
     FILE *header = fopen("trees.h", "w");
     int i;
 
@@ -397,12 +457,26 @@ void gen_trees_header()
 }
 #endif /* GEN_TREES_H */
 
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(deflate_state *s) {
+    int n; /* iterates over tree elements */
+
+    /* Initialize the trees. */
+    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+    s->dyn_ltree[END_BLOCK].Freq = 1;
+    s->opt_len = s->static_len = 0L;
+    s->sym_next = s->matches = 0;
+}
+
 /* ===========================================================================
  * Initialize the tree data structures for a new zlib stream.
  */
-void ZLIB_INTERNAL _tr_init(s)
-    deflate_state *s;
-{
+void ZLIB_INTERNAL _tr_init(deflate_state *s) {
     tr_static_init();
 
     s->l_desc.dyn_tree = s->dyn_ltree;
@@ -425,24 +499,6 @@ void ZLIB_INTERNAL _tr_init(s)
     init_block(s);
 }
 
-/* ===========================================================================
- * Initialize a new block.
- */
-local void init_block(s)
-    deflate_state *s;
-{
-    int n; /* iterates over tree elements */
-
-    /* Initialize the trees. */
-    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
-    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
-    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-
-    s->dyn_ltree[END_BLOCK].Freq = 1;
-    s->opt_len = s->static_len = 0L;
-    s->sym_next = s->matches = 0;
-}
-
 #define SMALLEST 1
 /* Index within the heap array of least frequent node in the Huffman tree */
 
@@ -472,11 +528,7 @@ local void init_block(s)
  * when the heap property is re-established (each father smaller than its
  * two sons).
  */
-local void pqdownheap(s, tree, k)
-    deflate_state *s;
-    ct_data *tree;  /* the tree to restore */
-    int k;               /* node to move down */
-{
+local void pqdownheap(deflate_state *s, ct_data *tree, int k) {
     int v = s->heap[k];
     int j = k << 1;  /* left son of k */
     while (j <= s->heap_len) {
@@ -507,10 +559,7 @@ local void pqdownheap(s, tree, k)
  *     The length opt_len is updated; static_len is also updated if stree is
  *     not null.
  */
-local void gen_bitlen(s, desc)
-    deflate_state *s;
-    tree_desc *desc;    /* the tree descriptor */
-{
+local void gen_bitlen(deflate_state *s, tree_desc *desc) {
     ct_data *tree        = desc->dyn_tree;
     int max_code         = desc->max_code;
     const ct_data *stree = desc->stat_desc->static_tree;
@@ -585,48 +634,9 @@ local void gen_bitlen(s, desc)
     }
 }
 
-/* ===========================================================================
- * Generate the codes for a given tree and bit counts (which need not be
- * optimal).
- * IN assertion: the array bl_count contains the bit length statistics for
- * the given tree and the field len is set for all tree elements.
- * OUT assertion: the field code is set for all tree elements of non
- *     zero code length.
- */
-local void gen_codes(tree, max_code, bl_count)
-    ct_data *tree;             /* the tree to decorate */
-    int max_code;              /* largest code with non zero frequency */
-    ushf *bl_count;            /* number of codes at each bit length */
-{
-    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
-    unsigned code = 0;         /* running code value */
-    int bits;                  /* bit index */
-    int n;                     /* code index */
-
-    /* The distribution counts are first used to generate the code values
-     * without bit reversal.
-     */
-    for (bits = 1; bits <= MAX_BITS; bits++) {
-        code = (code + bl_count[bits - 1]) << 1;
-        next_code[bits] = (ush)code;
-    }
-    /* Check that the bit counts in bl_count are consistent. The last code
-     * must be all ones.
-     */
-    Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,
-            "inconsistent bit counts");
-    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
-    for (n = 0;  n <= max_code; n++) {
-        int len = tree[n].Len;
-        if (len == 0) continue;
-        /* Now reverse the bits */
-        tree[n].Code = (ush)bi_reverse(next_code[len]++, len);
-
-        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
-            n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1));
-    }
-}
+#ifdef DUMP_BL_TREE
+#  include 
+#endif
 
 /* ===========================================================================
  * Construct one Huffman tree and assigns the code bit strings and lengths.
@@ -636,10 +646,7 @@ local void gen_codes(tree, max_code, bl_count)
  *     and corresponding code. The length opt_len is updated; static_len is
  *     also updated if stree is not null. The field max_code is set.
  */
-local void build_tree(s, desc)
-    deflate_state *s;
-    tree_desc *desc; /* the tree descriptor */
-{
+local void build_tree(deflate_state *s, tree_desc *desc) {
     ct_data *tree         = desc->dyn_tree;
     const ct_data *stree  = desc->stat_desc->static_tree;
     int elems             = desc->stat_desc->elems;
@@ -724,11 +731,7 @@ local void build_tree(s, desc)
  * Scan a literal or distance tree to determine the frequencies of the codes
  * in the bit length tree.
  */
-local void scan_tree(s, tree, max_code)
-    deflate_state *s;
-    ct_data *tree;   /* the tree to be scanned */
-    int max_code;    /* and its largest code of non zero frequency */
-{
+local void scan_tree(deflate_state *s, ct_data *tree, int max_code) {
     int n;                     /* iterates over all tree elements */
     int prevlen = -1;          /* last emitted length */
     int curlen;                /* length of current code */
@@ -769,11 +772,7 @@ local void scan_tree(s, tree, max_code)
  * Send a literal or distance tree in compressed form, using the codes in
  * bl_tree.
  */
-local void send_tree(s, tree, max_code)
-    deflate_state *s;
-    ct_data *tree; /* the tree to be scanned */
-    int max_code;       /* and its largest code of non zero frequency */
-{
+local void send_tree(deflate_state *s, ct_data *tree, int max_code) {
     int n;                     /* iterates over all tree elements */
     int prevlen = -1;          /* last emitted length */
     int curlen;                /* length of current code */
@@ -820,9 +819,7 @@ local void send_tree(s, tree, max_code)
  * Construct the Huffman tree for the bit lengths and return the index in
  * bl_order of the last bit length code to send.
  */
-local int build_bl_tree(s)
-    deflate_state *s;
-{
+local int build_bl_tree(deflate_state *s) {
     int max_blindex;  /* index of last bit length code of non zero freq */
 
     /* Determine the bit length frequencies for literal and distance trees */
@@ -855,10 +852,8 @@ local int build_bl_tree(s)
  * lengths of the bit length codes, the literal tree and the distance tree.
  * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
  */
-local void send_all_trees(s, lcodes, dcodes, blcodes)
-    deflate_state *s;
-    int lcodes, dcodes, blcodes; /* number of codes for each tree */
-{
+local void send_all_trees(deflate_state *s, int lcodes, int dcodes,
+                          int blcodes) {
     int rank;                    /* index in bl_order */
 
     Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
@@ -884,12 +879,8 @@ local void send_all_trees(s, lcodes, dcodes, blcodes)
 /* ===========================================================================
  * Send a stored block
  */
-void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
-    deflate_state *s;
-    charf *buf;       /* input block */
-    ulg stored_len;   /* length of input block */
-    int last;         /* one if this is the last block for a file */
-{
+void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf,
+                                    ulg stored_len, int last) {
     send_bits(s, (STORED_BLOCK<<1) + last, 3);  /* send block type */
     bi_windup(s);        /* align on byte boundary */
     put_short(s, (ush)stored_len);
@@ -908,9 +899,7 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
 /* ===========================================================================
  * Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
  */
-void ZLIB_INTERNAL _tr_flush_bits(s)
-    deflate_state *s;
-{
+void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) {
     bi_flush(s);
 }
 
@@ -918,9 +907,7 @@ void ZLIB_INTERNAL _tr_flush_bits(s)
  * Send one empty static block to give enough lookahead for inflate.
  * This takes 10 bits, of which 7 may remain in the bit buffer.
  */
-void ZLIB_INTERNAL _tr_align(s)
-    deflate_state *s;
-{
+void ZLIB_INTERNAL _tr_align(deflate_state *s) {
     send_bits(s, STATIC_TREES<<1, 3);
     send_code(s, END_BLOCK, static_ltree);
 #ifdef ZLIB_DEBUG
@@ -929,16 +916,108 @@ void ZLIB_INTERNAL _tr_align(s)
     bi_flush(s);
 }
 
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(deflate_state *s, const ct_data *ltree,
+                          const ct_data *dtree) {
+    unsigned dist;      /* distance of matched string */
+    int lc;             /* match length or unmatched char (if dist == 0) */
+    unsigned sx = 0;    /* running index in symbol buffers */
+    unsigned code;      /* the code to send */
+    int extra;          /* number of extra bits to send */
+
+    if (s->sym_next != 0) do {
+#ifdef LIT_MEM
+        dist = s->d_buf[sx];
+        lc = s->l_buf[sx++];
+#else
+        dist = s->sym_buf[sx++] & 0xff;
+        dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
+        lc = s->sym_buf[sx++];
+#endif
+        if (dist == 0) {
+            send_code(s, lc, ltree); /* send a literal byte */
+            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+        } else {
+            /* Here, lc is the match length - MIN_MATCH */
+            code = _length_code[lc];
+            send_code(s, code + LITERALS + 1, ltree);   /* send length code */
+            extra = extra_lbits[code];
+            if (extra != 0) {
+                lc -= base_length[code];
+                send_bits(s, lc, extra);       /* send the extra length bits */
+            }
+            dist--; /* dist is now the match distance - 1 */
+            code = d_code(dist);
+            Assert (code < D_CODES, "bad d_code");
+
+            send_code(s, code, dtree);       /* send the distance code */
+            extra = extra_dbits[code];
+            if (extra != 0) {
+                dist -= (unsigned)base_dist[code];
+                send_bits(s, dist, extra);   /* send the extra distance bits */
+            }
+        } /* literal or match pair ? */
+
+        /* Check for no overlay of pending_buf on needed symbols */
+#ifdef LIT_MEM
+        Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow");
+#else
+        Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
+#endif
+
+    } while (sx < s->sym_next);
+
+    send_code(s, END_BLOCK, ltree);
+}
+
+/* ===========================================================================
+ * Check if the data type is TEXT or BINARY, using the following algorithm:
+ * - TEXT if the two conditions below are satisfied:
+ *    a) There are no non-portable control characters belonging to the
+ *       "block list" (0..6, 14..25, 28..31).
+ *    b) There is at least one printable character belonging to the
+ *       "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+ * - BINARY otherwise.
+ * - The following partially-portable control characters form a
+ *   "gray list" that is ignored in this detection algorithm:
+ *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+local int detect_data_type(deflate_state *s) {
+    /* block_mask is the bit mask of block-listed bytes
+     * set bits 0..6, 14..25, and 28..31
+     * 0xf3ffc07f = binary 11110011111111111100000001111111
+     */
+    unsigned long block_mask = 0xf3ffc07fUL;
+    int n;
+
+    /* Check for non-textual ("block-listed") bytes. */
+    for (n = 0; n <= 31; n++, block_mask >>= 1)
+        if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0))
+            return Z_BINARY;
+
+    /* Check for textual ("allow-listed") bytes. */
+    if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
+            || s->dyn_ltree[13].Freq != 0)
+        return Z_TEXT;
+    for (n = 32; n < LITERALS; n++)
+        if (s->dyn_ltree[n].Freq != 0)
+            return Z_TEXT;
+
+    /* There are no "block-listed" or "allow-listed" bytes:
+     * this stream either is empty or has tolerated ("gray-listed") bytes only.
+     */
+    return Z_BINARY;
+}
+
 /* ===========================================================================
  * Determine the best encoding for the current block: dynamic trees, static
  * trees or store, and write out the encoded block.
  */
-void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
-    deflate_state *s;
-    charf *buf;       /* input block, or NULL if too old */
-    ulg stored_len;   /* length of input block */
-    int last;         /* one if this is the last block for a file */
-{
+void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf,
+                                   ulg stored_len, int last) {
     ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
     int max_blindex = 0;  /* index of last bit length code of non zero freq */
 
@@ -1035,14 +1114,15 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
  * Save the match info and tally the frequency counts. Return true if
  * the current block must be flushed.
  */
-int ZLIB_INTERNAL _tr_tally(s, dist, lc)
-    deflate_state *s;
-    unsigned dist;  /* distance of matched string */
-    unsigned lc;    /* match length - MIN_MATCH or unmatched char (dist==0) */
-{
+int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) {
+#ifdef LIT_MEM
+    s->d_buf[s->sym_next] = (ush)dist;
+    s->l_buf[s->sym_next++] = (uch)lc;
+#else
     s->sym_buf[s->sym_next++] = (uch)dist;
     s->sym_buf[s->sym_next++] = (uch)(dist >> 8);
     s->sym_buf[s->sym_next++] = (uch)lc;
+#endif
     if (dist == 0) {
         /* lc is the unmatched char */
         s->dyn_ltree[lc].Freq++;
@@ -1059,147 +1139,3 @@ int ZLIB_INTERNAL _tr_tally(s, dist, lc)
     }
     return (s->sym_next == s->sym_end);
 }
-
-/* ===========================================================================
- * Send the block data compressed using the given Huffman trees
- */
-local void compress_block(s, ltree, dtree)
-    deflate_state *s;
-    const ct_data *ltree; /* literal tree */
-    const ct_data *dtree; /* distance tree */
-{
-    unsigned dist;      /* distance of matched string */
-    int lc;             /* match length or unmatched char (if dist == 0) */
-    unsigned sx = 0;    /* running index in sym_buf */
-    unsigned code;      /* the code to send */
-    int extra;          /* number of extra bits to send */
-
-    if (s->sym_next != 0) do {
-        dist = s->sym_buf[sx++] & 0xff;
-        dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
-        lc = s->sym_buf[sx++];
-        if (dist == 0) {
-            send_code(s, lc, ltree); /* send a literal byte */
-            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
-        } else {
-            /* Here, lc is the match length - MIN_MATCH */
-            code = _length_code[lc];
-            send_code(s, code + LITERALS + 1, ltree);   /* send length code */
-            extra = extra_lbits[code];
-            if (extra != 0) {
-                lc -= base_length[code];
-                send_bits(s, lc, extra);       /* send the extra length bits */
-            }
-            dist--; /* dist is now the match distance - 1 */
-            code = d_code(dist);
-            Assert (code < D_CODES, "bad d_code");
-
-            send_code(s, code, dtree);       /* send the distance code */
-            extra = extra_dbits[code];
-            if (extra != 0) {
-                dist -= (unsigned)base_dist[code];
-                send_bits(s, dist, extra);   /* send the extra distance bits */
-            }
-        } /* literal or match pair ? */
-
-        /* Check that the overlay between pending_buf and sym_buf is ok: */
-        Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
-
-    } while (sx < s->sym_next);
-
-    send_code(s, END_BLOCK, ltree);
-}
-
-/* ===========================================================================
- * Check if the data type is TEXT or BINARY, using the following algorithm:
- * - TEXT if the two conditions below are satisfied:
- *    a) There are no non-portable control characters belonging to the
- *       "block list" (0..6, 14..25, 28..31).
- *    b) There is at least one printable character belonging to the
- *       "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
- * - BINARY otherwise.
- * - The following partially-portable control characters form a
- *   "gray list" that is ignored in this detection algorithm:
- *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
- * IN assertion: the fields Freq of dyn_ltree are set.
- */
-local int detect_data_type(s)
-    deflate_state *s;
-{
-    /* block_mask is the bit mask of block-listed bytes
-     * set bits 0..6, 14..25, and 28..31
-     * 0xf3ffc07f = binary 11110011111111111100000001111111
-     */
-    unsigned long block_mask = 0xf3ffc07fUL;
-    int n;
-
-    /* Check for non-textual ("block-listed") bytes. */
-    for (n = 0; n <= 31; n++, block_mask >>= 1)
-        if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0))
-            return Z_BINARY;
-
-    /* Check for textual ("allow-listed") bytes. */
-    if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
-            || s->dyn_ltree[13].Freq != 0)
-        return Z_TEXT;
-    for (n = 32; n < LITERALS; n++)
-        if (s->dyn_ltree[n].Freq != 0)
-            return Z_TEXT;
-
-    /* There are no "block-listed" or "allow-listed" bytes:
-     * this stream either is empty or has tolerated ("gray-listed") bytes only.
-     */
-    return Z_BINARY;
-}
-
-/* ===========================================================================
- * Reverse the first len bits of a code, using straightforward code (a faster
- * method would use a table)
- * IN assertion: 1 <= len <= 15
- */
-local unsigned bi_reverse(code, len)
-    unsigned code; /* the value to invert */
-    int len;       /* its bit length */
-{
-    register unsigned res = 0;
-    do {
-        res |= code & 1;
-        code >>= 1, res <<= 1;
-    } while (--len > 0);
-    return res >> 1;
-}
-
-/* ===========================================================================
- * Flush the bit buffer, keeping at most 7 bits in it.
- */
-local void bi_flush(s)
-    deflate_state *s;
-{
-    if (s->bi_valid == 16) {
-        put_short(s, s->bi_buf);
-        s->bi_buf = 0;
-        s->bi_valid = 0;
-    } else if (s->bi_valid >= 8) {
-        put_byte(s, (Byte)s->bi_buf);
-        s->bi_buf >>= 8;
-        s->bi_valid -= 8;
-    }
-}
-
-/* ===========================================================================
- * Flush the bit buffer and align the output on a byte boundary
- */
-local void bi_windup(s)
-    deflate_state *s;
-{
-    if (s->bi_valid > 8) {
-        put_short(s, s->bi_buf);
-    } else if (s->bi_valid > 0) {
-        put_byte(s, (Byte)s->bi_buf);
-    }
-    s->bi_buf = 0;
-    s->bi_valid = 0;
-#ifdef ZLIB_DEBUG
-    s->bits_sent = (s->bits_sent + 7) & ~7;
-#endif
-}
diff --git a/src/java.base/share/native/libzip/zlib/uncompr.c b/src/java.base/share/native/libzip/zlib/uncompr.c
index 24af8d2453f..219c1d264d5 100644
--- a/src/java.base/share/native/libzip/zlib/uncompr.c
+++ b/src/java.base/share/native/libzip/zlib/uncompr.c
@@ -48,12 +48,8 @@
    Z_DATA_ERROR if the input data was corrupted, including if the input data is
    an incomplete zlib stream.
 */
-int ZEXPORT uncompress2(dest, destLen, source, sourceLen)
-    Bytef *dest;
-    uLongf *destLen;
-    const Bytef *source;
-    uLong *sourceLen;
-{
+int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source,
+                        uLong *sourceLen) {
     z_stream stream;
     int err;
     const uInt max = (uInt)-1;
@@ -107,11 +103,7 @@ int ZEXPORT uncompress2(dest, destLen, source, sourceLen)
            err;
 }
 
-int ZEXPORT uncompress(dest, destLen, source, sourceLen)
-    Bytef *dest;
-    uLongf *destLen;
-    const Bytef *source;
-    uLong sourceLen;
-{
+int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
+                       uLong sourceLen) {
     return uncompress2(dest, destLen, source, &sourceLen);
 }
diff --git a/src/java.base/share/native/libzip/zlib/zadler32.c b/src/java.base/share/native/libzip/zlib/zadler32.c
index e1480226310..acfd75b908e 100644
--- a/src/java.base/share/native/libzip/zlib/zadler32.c
+++ b/src/java.base/share/native/libzip/zlib/zadler32.c
@@ -31,8 +31,6 @@
 
 #include "zutil.h"
 
-local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
-
 #define BASE 65521U     /* largest prime smaller than 65536 */
 #define NMAX 5552
 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
@@ -84,11 +82,7 @@ local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
 #endif
 
 /* ========================================================================= */
-uLong ZEXPORT adler32_z(adler, buf, len)
-    uLong adler;
-    const Bytef *buf;
-    z_size_t len;
-{
+uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) {
     unsigned long sum2;
     unsigned n;
 
@@ -155,20 +149,12 @@ uLong ZEXPORT adler32_z(adler, buf, len)
 }
 
 /* ========================================================================= */
-uLong ZEXPORT adler32(adler, buf, len)
-    uLong adler;
-    const Bytef *buf;
-    uInt len;
-{
+uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) {
     return adler32_z(adler, buf, len);
 }
 
 /* ========================================================================= */
-local uLong adler32_combine_(adler1, adler2, len2)
-    uLong adler1;
-    uLong adler2;
-    z_off64_t len2;
-{
+local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) {
     unsigned long sum1;
     unsigned long sum2;
     unsigned rem;
@@ -193,18 +179,10 @@ local uLong adler32_combine_(adler1, adler2, len2)
 }
 
 /* ========================================================================= */
-uLong ZEXPORT adler32_combine(adler1, adler2, len2)
-    uLong adler1;
-    uLong adler2;
-    z_off_t len2;
-{
+uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) {
     return adler32_combine_(adler1, adler2, len2);
 }
 
-uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
-    uLong adler1;
-    uLong adler2;
-    z_off64_t len2;
-{
+uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) {
     return adler32_combine_(adler1, adler2, len2);
 }
diff --git a/src/java.base/share/native/libzip/zlib/zconf.h b/src/java.base/share/native/libzip/zlib/zconf.h
index 92b7eb23886..46204222f5d 100644
--- a/src/java.base/share/native/libzip/zlib/zconf.h
+++ b/src/java.base/share/native/libzip/zlib/zconf.h
@@ -23,7 +23,7 @@
  */
 
 /* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -265,7 +265,11 @@
 #endif
 
 #ifdef Z_SOLO
-   typedef unsigned long z_size_t;
+#  ifdef _WIN64
+     typedef unsigned long long z_size_t;
+#  else
+     typedef unsigned long z_size_t;
+#  endif
 #else
 #  define z_longlong long long
 #  if defined(NO_SIZE_T)
@@ -320,14 +324,6 @@
 #  endif
 #endif
 
-#ifndef Z_ARG /* function prototypes for stdarg */
-#  if defined(STDC) || defined(Z_HAVE_STDARG_H)
-#    define Z_ARG(args)  args
-#  else
-#    define Z_ARG(args)  ()
-#  endif
-#endif
-
 /* The following definitions for FAR are needed only for MSDOS mixed
  * model programming (small or medium model with some far allocations).
  * This was tested only with MSC; for other MSDOS compilers you may have
@@ -544,7 +540,7 @@ typedef uLong FAR uLongf;
 #if !defined(_WIN32) && defined(Z_LARGE64)
 #  define z_off64_t off64_t
 #else
-#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+#  if defined(_WIN32) && !defined(__GNUC__)
 #    define z_off64_t __int64
 #  else
 #    define z_off64_t z_off_t
diff --git a/src/java.base/share/native/libzip/zlib/zcrc32.c b/src/java.base/share/native/libzip/zlib/zcrc32.c
index 24f2350b55d..3f918f76b7c 100644
--- a/src/java.base/share/native/libzip/zlib/zcrc32.c
+++ b/src/java.base/share/native/libzip/zlib/zcrc32.c
@@ -127,19 +127,6 @@
 #  define ARMCRC32
 #endif
 
-/* Local functions. */
-local z_crc_t multmodp OF((z_crc_t a, z_crc_t b));
-local z_crc_t x2nmodp OF((z_off64_t n, unsigned k));
-
-#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
-    local z_word_t byte_swap OF((z_word_t word));
-#endif
-
-#if defined(W) && !defined(ARMCRC32)
-    local z_crc_t crc_word OF((z_word_t data));
-    local z_word_t crc_word_big OF((z_word_t data));
-#endif
-
 #if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
 /*
   Swap the bytes in a z_word_t to convert between little and big endian. Any
@@ -147,9 +134,7 @@ local z_crc_t x2nmodp OF((z_off64_t n, unsigned k));
   instruction, if one is available. This assumes that word_t is either 32 bits
   or 64 bits.
  */
-local z_word_t byte_swap(word)
-    z_word_t word;
-{
+local z_word_t byte_swap(z_word_t word) {
 #  if W == 8
     return
         (word & 0xff00000000000000) >> 56 |
@@ -170,24 +155,77 @@ local z_word_t byte_swap(word)
 }
 #endif
 
+#ifdef DYNAMIC_CRC_TABLE
+/* =========================================================================
+ * Table of powers of x for combining CRC-32s, filled in by make_crc_table()
+ * below.
+ */
+   local z_crc_t FAR x2n_table[32];
+#else
+/* =========================================================================
+ * Tables for byte-wise and braided CRC-32 calculations, and a table of powers
+ * of x for combining CRC-32s, all made by make_crc_table().
+ */
+#  include "crc32.h"
+#endif
+
 /* CRC polynomial. */
 #define POLY 0xedb88320         /* p(x) reflected, with x^32 implied */
 
-#ifdef DYNAMIC_CRC_TABLE
+/*
+  Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,
+  reflected. For speed, this requires that a not be zero.
+ */
+local z_crc_t multmodp(z_crc_t a, z_crc_t b) {
+    z_crc_t m, p;
+
+    m = (z_crc_t)1 << 31;
+    p = 0;
+    for (;;) {
+        if (a & m) {
+            p ^= b;
+            if ((a & (m - 1)) == 0)
+                break;
+        }
+        m >>= 1;
+        b = b & 1 ? (b >> 1) ^ POLY : b >> 1;
+    }
+    return p;
+}
 
+/*
+  Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been
+  initialized.
+ */
+local z_crc_t x2nmodp(z_off64_t n, unsigned k) {
+    z_crc_t p;
+
+    p = (z_crc_t)1 << 31;           /* x^0 == 1 */
+    while (n) {
+        if (n & 1)
+            p = multmodp(x2n_table[k & 31], p);
+        n >>= 1;
+        k++;
+    }
+    return p;
+}
+
+#ifdef DYNAMIC_CRC_TABLE
+/* =========================================================================
+ * Build the tables for byte-wise and braided CRC-32 calculations, and a table
+ * of powers of x for combining CRC-32s.
+ */
 local z_crc_t FAR crc_table[256];
-local z_crc_t FAR x2n_table[32];
-local void make_crc_table OF((void));
 #ifdef W
    local z_word_t FAR crc_big_table[256];
    local z_crc_t FAR crc_braid_table[W][256];
    local z_word_t FAR crc_braid_big_table[W][256];
-   local void braid OF((z_crc_t [][256], z_word_t [][256], int, int));
+   local void braid(z_crc_t [][256], z_word_t [][256], int, int);
 #endif
 #ifdef MAKECRCH
-   local void write_table OF((FILE *, const z_crc_t FAR *, int));
-   local void write_table32hi OF((FILE *, const z_word_t FAR *, int));
-   local void write_table64 OF((FILE *, const z_word_t FAR *, int));
+   local void write_table(FILE *, const z_crc_t FAR *, int);
+   local void write_table32hi(FILE *, const z_word_t FAR *, int);
+   local void write_table64(FILE *, const z_word_t FAR *, int);
 #endif /* MAKECRCH */
 
 /*
@@ -200,7 +238,6 @@ local void make_crc_table OF((void));
 
 /* Definition of once functionality. */
 typedef struct once_s once_t;
-local void once OF((once_t *, void (*)(void)));
 
 /* Check for the availability of atomics. */
 #if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \
@@ -220,10 +257,7 @@ struct once_s {
   invoke once() at the same time. The state must be a once_t initialized with
   ONCE_INIT.
  */
-local void once(state, init)
-    once_t *state;
-    void (*init)(void);
-{
+local void once(once_t *state, void (*init)(void)) {
     if (!atomic_load(&state->done)) {
         if (atomic_flag_test_and_set(&state->begun))
             while (!atomic_load(&state->done))
@@ -246,10 +280,7 @@ struct once_s {
 
 /* Test and set. Alas, not atomic, but tries to minimize the period of
    vulnerability. */
-local int test_and_set OF((int volatile *));
-local int test_and_set(flag)
-    int volatile *flag;
-{
+local int test_and_set(int volatile *flag) {
     int was;
 
     was = *flag;
@@ -258,10 +289,7 @@ local int test_and_set(flag)
 }
 
 /* Run the provided init() function once. This is not thread-safe. */
-local void once(state, init)
-    once_t *state;
-    void (*init)(void);
-{
+local void once(once_t *state, void (*init)(void)) {
     if (!state->done) {
         if (test_and_set(&state->begun))
             while (!state->done)
@@ -303,8 +331,7 @@ local once_t made = ONCE_INIT;
   combinations of CRC register values and incoming bytes.
  */
 
-local void make_crc_table()
-{
+local void make_crc_table(void) {
     unsigned i, j, n;
     z_crc_t p;
 
@@ -471,11 +498,7 @@ local void make_crc_table()
    Write the 32-bit values in table[0..k-1] to out, five per line in
    hexadecimal separated by commas.
  */
-local void write_table(out, table, k)
-    FILE *out;
-    const z_crc_t FAR *table;
-    int k;
-{
+local void write_table(FILE *out, const z_crc_t FAR *table, int k) {
     int n;
 
     for (n = 0; n < k; n++)
@@ -488,11 +511,7 @@ local void write_table(out, table, k)
    Write the high 32-bits of each value in table[0..k-1] to out, five per line
    in hexadecimal separated by commas.
  */
-local void write_table32hi(out, table, k)
-FILE *out;
-const z_word_t FAR *table;
-int k;
-{
+local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) {
     int n;
 
     for (n = 0; n < k; n++)
@@ -508,11 +527,7 @@ int k;
   bits. If not, then the type cast and format string can be adjusted
   accordingly.
  */
-local void write_table64(out, table, k)
-    FILE *out;
-    const z_word_t FAR *table;
-    int k;
-{
+local void write_table64(FILE *out, const z_word_t FAR *table, int k) {
     int n;
 
     for (n = 0; n < k; n++)
@@ -522,8 +537,7 @@ local void write_table64(out, table, k)
 }
 
 /* Actually do the deed. */
-int main()
-{
+int main(void) {
     make_crc_table();
     return 0;
 }
@@ -535,12 +549,7 @@ int main()
   Generate the little and big-endian braid tables for the given n and z_word_t
   size w. Each array must have room for w blocks of 256 elements.
  */
-local void braid(ltl, big, n, w)
-    z_crc_t ltl[][256];
-    z_word_t big[][256];
-    int n;
-    int w;
-{
+local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) {
     int k;
     z_crc_t i, p, q;
     for (k = 0; k < w; k++) {
@@ -555,69 +564,13 @@ local void braid(ltl, big, n, w)
 }
 #endif
 
-#else /* !DYNAMIC_CRC_TABLE */
-/* ========================================================================
- * Tables for byte-wise and braided CRC-32 calculations, and a table of powers
- * of x for combining CRC-32s, all made by make_crc_table().
- */
-#include "crc32.h"
 #endif /* DYNAMIC_CRC_TABLE */
 
-/* ========================================================================
- * Routines used for CRC calculation. Some are also required for the table
- * generation above.
- */
-
-/*
-  Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,
-  reflected. For speed, this requires that a not be zero.
- */
-local z_crc_t multmodp(a, b)
-    z_crc_t a;
-    z_crc_t b;
-{
-    z_crc_t m, p;
-
-    m = (z_crc_t)1 << 31;
-    p = 0;
-    for (;;) {
-        if (a & m) {
-            p ^= b;
-            if ((a & (m - 1)) == 0)
-                break;
-        }
-        m >>= 1;
-        b = b & 1 ? (b >> 1) ^ POLY : b >> 1;
-    }
-    return p;
-}
-
-/*
-  Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been
-  initialized.
- */
-local z_crc_t x2nmodp(n, k)
-    z_off64_t n;
-    unsigned k;
-{
-    z_crc_t p;
-
-    p = (z_crc_t)1 << 31;           /* x^0 == 1 */
-    while (n) {
-        if (n & 1)
-            p = multmodp(x2n_table[k & 31], p);
-        n >>= 1;
-        k++;
-    }
-    return p;
-}
-
 /* =========================================================================
  * This function can be used by asm versions of crc32(), and to force the
  * generation of the CRC tables in a threaded application.
  */
-const z_crc_t FAR * ZEXPORT get_crc_table()
-{
+const z_crc_t FAR * ZEXPORT get_crc_table(void) {
 #ifdef DYNAMIC_CRC_TABLE
     once(&made, make_crc_table);
 #endif /* DYNAMIC_CRC_TABLE */
@@ -643,11 +596,8 @@ const z_crc_t FAR * ZEXPORT get_crc_table()
 #define Z_BATCH_ZEROS 0xa10d3d0c    /* computed from Z_BATCH = 3990 */
 #define Z_BATCH_MIN 800             /* fewest words in a final batch */
 
-unsigned long ZEXPORT crc32_z(crc, buf, len)
-    unsigned long crc;
-    const unsigned char FAR *buf;
-    z_size_t len;
-{
+unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
+                              z_size_t len) {
     z_crc_t val;
     z_word_t crc1, crc2;
     const z_word_t *word;
@@ -747,18 +697,14 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
   least-significant byte of the word as the first byte of data, without any pre
   or post conditioning. This is used to combine the CRCs of each braid.
  */
-local z_crc_t crc_word(data)
-    z_word_t data;
-{
+local z_crc_t crc_word(z_word_t data) {
     int k;
     for (k = 0; k < W; k++)
         data = (data >> 8) ^ crc_table[data & 0xff];
     return (z_crc_t)data;
 }
 
-local z_word_t crc_word_big(data)
-    z_word_t data;
-{
+local z_word_t crc_word_big(z_word_t data) {
     int k;
     for (k = 0; k < W; k++)
         data = (data << 8) ^
@@ -769,11 +715,8 @@ local z_word_t crc_word_big(data)
 #endif
 
 /* ========================================================================= */
-unsigned long ZEXPORT crc32_z(crc, buf, len)
-    unsigned long crc;
-    const unsigned char FAR *buf;
-    z_size_t len;
-{
+unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
+                              z_size_t len) {
     /* Return initial CRC, if requested. */
     if (buf == Z_NULL) return 0;
 
@@ -805,8 +748,8 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
         words = (z_word_t const *)buf;
 
         /* Do endian check at execution time instead of compile time, since ARM
-           processors can change the endianess at execution time. If the
-           compiler knows what the endianess will be, it can optimize out the
+           processors can change the endianness at execution time. If the
+           compiler knows what the endianness will be, it can optimize out the
            check and the unused branch. */
         endian = 1;
         if (*(unsigned char *)&endian) {
@@ -1093,20 +1036,13 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
 #endif
 
 /* ========================================================================= */
-unsigned long ZEXPORT crc32(crc, buf, len)
-    unsigned long crc;
-    const unsigned char FAR *buf;
-    uInt len;
-{
+unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf,
+                            uInt len) {
     return crc32_z(crc, buf, len);
 }
 
 /* ========================================================================= */
-uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
-    uLong crc1;
-    uLong crc2;
-    z_off64_t len2;
-{
+uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) {
 #ifdef DYNAMIC_CRC_TABLE
     once(&made, make_crc_table);
 #endif /* DYNAMIC_CRC_TABLE */
@@ -1114,18 +1050,12 @@ uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
 }
 
 /* ========================================================================= */
-uLong ZEXPORT crc32_combine(crc1, crc2, len2)
-    uLong crc1;
-    uLong crc2;
-    z_off_t len2;
-{
+uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) {
     return crc32_combine64(crc1, crc2, (z_off64_t)len2);
 }
 
 /* ========================================================================= */
-uLong ZEXPORT crc32_combine_gen64(len2)
-    z_off64_t len2;
-{
+uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) {
 #ifdef DYNAMIC_CRC_TABLE
     once(&made, make_crc_table);
 #endif /* DYNAMIC_CRC_TABLE */
@@ -1133,17 +1063,11 @@ uLong ZEXPORT crc32_combine_gen64(len2)
 }
 
 /* ========================================================================= */
-uLong ZEXPORT crc32_combine_gen(len2)
-    z_off_t len2;
-{
+uLong ZEXPORT crc32_combine_gen(z_off_t len2) {
     return crc32_combine_gen64((z_off64_t)len2);
 }
 
 /* ========================================================================= */
-uLong ZEXPORT crc32_combine_op(crc1, crc2, op)
-    uLong crc1;
-    uLong crc2;
-    uLong op;
-{
+uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) {
     return multmodp(op, crc1) ^ (crc2 & 0xffffffff);
 }
diff --git a/src/java.base/share/native/libzip/zlib/zlib.h b/src/java.base/share/native/libzip/zlib/zlib.h
index 10146088795..07496b5f981 100644
--- a/src/java.base/share/native/libzip/zlib/zlib.h
+++ b/src/java.base/share/native/libzip/zlib/zlib.h
@@ -23,9 +23,9 @@
  */
 
 /* zlib.h -- interface of the 'zlib' general purpose compression library
-  version 1.2.13, October 13th, 2022
+  version 1.3.1, January 22nd, 2024
 
-  Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
+  Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -61,11 +61,11 @@
 extern "C" {
 #endif
 
-#define ZLIB_VERSION "1.2.13"
-#define ZLIB_VERNUM 0x12d0
+#define ZLIB_VERSION "1.3.1"
+#define ZLIB_VERNUM 0x1310
 #define ZLIB_VER_MAJOR 1
-#define ZLIB_VER_MINOR 2
-#define ZLIB_VER_REVISION 13
+#define ZLIB_VER_MINOR 3
+#define ZLIB_VER_REVISION 1
 #define ZLIB_VER_SUBREVISION 0
 
 /*
@@ -102,8 +102,8 @@ extern "C" {
   even in the case of corrupted input.
 */
 
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+typedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size);
+typedef void   (*free_func)(voidpf opaque, voidpf address);
 
 struct internal_state;
 
@@ -241,7 +241,7 @@ typedef gz_header FAR *gz_headerp;
 
                         /* basic functions */
 
-ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+ZEXTERN const char * ZEXPORT zlibVersion(void);
 /* The application can compare zlibVersion and ZLIB_VERSION for consistency.
    If the first character differs, the library code actually used is not
    compatible with the zlib.h header file used by the application.  This check
@@ -249,12 +249,12 @@ ZEXTERN const char * ZEXPORT zlibVersion OF((void));
  */
 
 /*
-ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+ZEXTERN int ZEXPORT deflateInit(z_streamp strm, int level);
 
      Initializes the internal stream state for compression.  The fields
    zalloc, zfree and opaque must be initialized before by the caller.  If
    zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
-   allocation functions.
+   allocation functions.  total_in, total_out, adler, and msg are initialized.
 
      The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
    1 gives best speed, 9 gives best compression, 0 gives no compression at all
@@ -271,7 +271,7 @@ ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
 */
 
 
-ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+ZEXTERN int ZEXPORT deflate(z_streamp strm, int flush);
 /*
     deflate compresses as much data as possible, and stops when the input
   buffer becomes empty or the output buffer becomes full.  It may introduce
@@ -344,8 +344,8 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
   with the same value of the flush parameter and more output space (updated
   avail_out), until the flush is complete (deflate returns with non-zero
   avail_out).  In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
-  avail_out is greater than six to avoid repeated flush markers due to
-  avail_out == 0 on return.
+  avail_out is greater than six when the flush marker begins, in order to avoid
+  repeated flush markers upon calling deflate() again when avail_out == 0.
 
     If the parameter flush is set to Z_FINISH, pending input is processed,
   pending output is flushed and deflate returns with Z_STREAM_END if there was
@@ -384,7 +384,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
 */
 
 
-ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+ZEXTERN int ZEXPORT deflateEnd(z_streamp strm);
 /*
      All dynamically allocated data structures for this stream are freed.
    This function discards any unprocessed input and does not flush any pending
@@ -399,7 +399,7 @@ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
 
 
 /*
-ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+ZEXTERN int ZEXPORT inflateInit(z_streamp strm);
 
      Initializes the internal stream state for decompression.  The fields
    next_in, avail_in, zalloc, zfree and opaque must be initialized before by
@@ -407,7 +407,8 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
    read or consumed.  The allocation of a sliding window will be deferred to
    the first call of inflate (if the decompression does not complete on the
    first call).  If zalloc and zfree are set to Z_NULL, inflateInit updates
-   them to use default allocation functions.
+   them to use default allocation functions.  total_in, total_out, adler, and
+   msg are initialized.
 
      inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
    memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
@@ -421,7 +422,7 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
 */
 
 
-ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+ZEXTERN int ZEXPORT inflate(z_streamp strm, int flush);
 /*
     inflate decompresses as much data as possible, and stops when the input
   buffer becomes empty or the output buffer becomes full.  It may introduce
@@ -541,7 +542,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
 */
 
 
-ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+ZEXTERN int ZEXPORT inflateEnd(z_streamp strm);
 /*
      All dynamically allocated data structures for this stream are freed.
    This function discards any unprocessed input and does not flush any pending
@@ -559,12 +560,12 @@ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
 */
 
 /*
-ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
-                                     int  level,
-                                     int  method,
-                                     int  windowBits,
-                                     int  memLevel,
-                                     int  strategy));
+ZEXTERN int ZEXPORT deflateInit2(z_streamp strm,
+                                 int level,
+                                 int method,
+                                 int windowBits,
+                                 int memLevel,
+                                 int strategy);
 
      This is another version of deflateInit with more compression options.  The
    fields zalloc, zfree and opaque must be initialized before by the caller.
@@ -631,9 +632,9 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
    compression: this will be done by deflate().
 */
 
-ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
-                                             const Bytef *dictionary,
-                                             uInt  dictLength));
+ZEXTERN int ZEXPORT deflateSetDictionary(z_streamp strm,
+                                         const Bytef *dictionary,
+                                         uInt  dictLength);
 /*
      Initializes the compression dictionary from the given byte sequence
    without producing any compressed output.  When using the zlib format, this
@@ -675,9 +676,9 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
    not perform any compression: this will be done by deflate().
 */
 
-ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm,
-                                             Bytef *dictionary,
-                                             uInt  *dictLength));
+ZEXTERN int ZEXPORT deflateGetDictionary(z_streamp strm,
+                                         Bytef *dictionary,
+                                         uInt  *dictLength);
 /*
      Returns the sliding dictionary being maintained by deflate.  dictLength is
    set to the number of bytes in the dictionary, and that many bytes are copied
@@ -697,8 +698,8 @@ ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm,
    stream state is inconsistent.
 */
 
-ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
-                                    z_streamp source));
+ZEXTERN int ZEXPORT deflateCopy(z_streamp dest,
+                                z_streamp source);
 /*
      Sets the destination stream as a complete copy of the source stream.
 
@@ -715,20 +716,20 @@ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
    destination.
 */
 
-ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+ZEXTERN int ZEXPORT deflateReset(z_streamp strm);
 /*
      This function is equivalent to deflateEnd followed by deflateInit, but
    does not free and reallocate the internal compression state.  The stream
    will leave the compression level and any other attributes that may have been
-   set unchanged.
+   set unchanged.  total_in, total_out, adler, and msg are initialized.
 
      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
    stream state was inconsistent (such as zalloc or state being Z_NULL).
 */
 
-ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
-                                      int level,
-                                      int strategy));
+ZEXTERN int ZEXPORT deflateParams(z_streamp strm,
+                                  int level,
+                                  int strategy);
 /*
      Dynamically update the compression level and compression strategy.  The
    interpretation of level and strategy is as in deflateInit2().  This can be
@@ -753,7 +754,7 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
    Then no more input data should be provided before the deflateParams() call.
    If this is done, the old level and strategy will be applied to the data
    compressed before deflateParams(), and the new level and strategy will be
-   applied to the the data compressed after deflateParams().
+   applied to the data compressed after deflateParams().
 
      deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream
    state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if
@@ -764,11 +765,11 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
    retried with more output space.
 */
 
-ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
-                                    int good_length,
-                                    int max_lazy,
-                                    int nice_length,
-                                    int max_chain));
+ZEXTERN int ZEXPORT deflateTune(z_streamp strm,
+                                int good_length,
+                                int max_lazy,
+                                int nice_length,
+                                int max_chain);
 /*
      Fine tune deflate's internal compression parameters.  This should only be
    used by someone who understands the algorithm used by zlib's deflate for
@@ -781,8 +782,8 @@ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
    returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
  */
 
-ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
-                                       uLong sourceLen));
+ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm,
+                                   uLong sourceLen);
 /*
      deflateBound() returns an upper bound on the compressed size after
    deflation of sourceLen bytes.  It must be called after deflateInit() or
@@ -796,9 +797,9 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
    than Z_FINISH or Z_NO_FLUSH are used.
 */
 
-ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
-                                       unsigned *pending,
-                                       int *bits));
+ZEXTERN int ZEXPORT deflatePending(z_streamp strm,
+                                   unsigned *pending,
+                                   int *bits);
 /*
      deflatePending() returns the number of bytes and bits of output that have
    been generated, but not yet provided in the available output.  The bytes not
@@ -811,9 +812,9 @@ ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
    stream state was inconsistent.
  */
 
-ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
-                                     int bits,
-                                     int value));
+ZEXTERN int ZEXPORT deflatePrime(z_streamp strm,
+                                 int bits,
+                                 int value);
 /*
      deflatePrime() inserts bits in the deflate output stream.  The intent
    is that this function is used to start off the deflate output with the bits
@@ -828,8 +829,8 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
    source stream state was inconsistent.
 */
 
-ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
-                                         gz_headerp head));
+ZEXTERN int ZEXPORT deflateSetHeader(z_streamp strm,
+                                     gz_headerp head);
 /*
      deflateSetHeader() provides gzip header information for when a gzip
    stream is requested by deflateInit2().  deflateSetHeader() may be called
@@ -845,16 +846,17 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
    gzip file" and give up.
 
      If deflateSetHeader is not used, the default gzip header has text false,
-   the time set to zero, and os set to 255, with no extra, name, or comment
-   fields.  The gzip header is returned to the default state by deflateReset().
+   the time set to zero, and os set to the current operating system, with no
+   extra, name, or comment fields.  The gzip header is returned to the default
+   state by deflateReset().
 
      deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
    stream state was inconsistent.
 */
 
 /*
-ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
-                                     int  windowBits));
+ZEXTERN int ZEXPORT inflateInit2(z_streamp strm,
+                                 int windowBits);
 
      This is another version of inflateInit with an extra parameter.  The
    fields next_in, avail_in, zalloc, zfree and opaque must be initialized
@@ -907,9 +909,9 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
    deferred until inflate() is called.
 */
 
-ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
-                                             const Bytef *dictionary,
-                                             uInt  dictLength));
+ZEXTERN int ZEXPORT inflateSetDictionary(z_streamp strm,
+                                         const Bytef *dictionary,
+                                         uInt  dictLength);
 /*
      Initializes the decompression dictionary from the given uncompressed byte
    sequence.  This function must be called immediately after a call of inflate,
@@ -930,9 +932,9 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
    inflate().
 */
 
-ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
-                                             Bytef *dictionary,
-                                             uInt  *dictLength));
+ZEXTERN int ZEXPORT inflateGetDictionary(z_streamp strm,
+                                         Bytef *dictionary,
+                                         uInt  *dictLength);
 /*
      Returns the sliding dictionary being maintained by inflate.  dictLength is
    set to the number of bytes in the dictionary, and that many bytes are copied
@@ -945,7 +947,7 @@ ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
    stream state is inconsistent.
 */
 
-ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+ZEXTERN int ZEXPORT inflateSync(z_streamp strm);
 /*
      Skips invalid compressed data until a possible full flush point (see above
    for the description of deflate with Z_FULL_FLUSH) can be found, or until all
@@ -958,14 +960,14 @@ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
      inflateSync returns Z_OK if a possible full flush point has been found,
    Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
    has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
-   In the success case, the application may save the current current value of
-   total_in which indicates where valid compressed data was found.  In the
-   error case, the application may repeatedly call inflateSync, providing more
-   input each time, until success or end of the input data.
+   In the success case, the application may save the current value of total_in
+   which indicates where valid compressed data was found.  In the error case,
+   the application may repeatedly call inflateSync, providing more input each
+   time, until success or end of the input data.
 */
 
-ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
-                                    z_streamp source));
+ZEXTERN int ZEXPORT inflateCopy(z_streamp dest,
+                                z_streamp source);
 /*
      Sets the destination stream as a complete copy of the source stream.
 
@@ -980,18 +982,19 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
    destination.
 */
 
-ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+ZEXTERN int ZEXPORT inflateReset(z_streamp strm);
 /*
      This function is equivalent to inflateEnd followed by inflateInit,
    but does not free and reallocate the internal decompression state.  The
    stream will keep attributes that may have been set by inflateInit2.
+   total_in, total_out, adler, and msg are initialized.
 
      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
    stream state was inconsistent (such as zalloc or state being Z_NULL).
 */
 
-ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
-                                      int windowBits));
+ZEXTERN int ZEXPORT inflateReset2(z_streamp strm,
+                                  int windowBits);
 /*
      This function is the same as inflateReset, but it also permits changing
    the wrap and window size requests.  The windowBits parameter is interpreted
@@ -1004,9 +1007,9 @@ ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
    the windowBits parameter is invalid.
 */
 
-ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
-                                     int bits,
-                                     int value));
+ZEXTERN int ZEXPORT inflatePrime(z_streamp strm,
+                                 int bits,
+                                 int value);
 /*
      This function inserts bits in the inflate input stream.  The intent is
    that this function is used to start inflating at a bit position in the
@@ -1025,7 +1028,7 @@ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
    stream state was inconsistent.
 */
 
-ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+ZEXTERN long ZEXPORT inflateMark(z_streamp strm);
 /*
      This function returns two values, one in the lower 16 bits of the return
    value, and the other in the remaining upper bits, obtained by shifting the
@@ -1053,8 +1056,8 @@ ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
    source stream state was inconsistent.
 */
 
-ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
-                                         gz_headerp head));
+ZEXTERN int ZEXPORT inflateGetHeader(z_streamp strm,
+                                     gz_headerp head);
 /*
      inflateGetHeader() requests that gzip header information be stored in the
    provided gz_header structure.  inflateGetHeader() may be called after
@@ -1094,8 +1097,8 @@ ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
 */
 
 /*
-ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
-                                        unsigned char FAR *window));
+ZEXTERN int ZEXPORT inflateBackInit(z_streamp strm, int windowBits,
+                                    unsigned char FAR *window);
 
      Initialize the internal stream state for decompression using inflateBack()
    calls.  The fields zalloc, zfree and opaque in strm must be initialized
@@ -1115,13 +1118,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
    the version of the header file.
 */
 
-typedef unsigned (*in_func) OF((void FAR *,
-                                z_const unsigned char FAR * FAR *));
-typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+typedef unsigned (*in_func)(void FAR *,
+                            z_const unsigned char FAR * FAR *);
+typedef int (*out_func)(void FAR *, unsigned char FAR *, unsigned);
 
-ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
-                                    in_func in, void FAR *in_desc,
-                                    out_func out, void FAR *out_desc));
+ZEXTERN int ZEXPORT inflateBack(z_streamp strm,
+                                in_func in, void FAR *in_desc,
+                                out_func out, void FAR *out_desc);
 /*
      inflateBack() does a raw inflate with a single call using a call-back
    interface for input and output.  This is potentially more efficient than
@@ -1189,7 +1192,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
    cannot return Z_OK.
 */
 
-ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+ZEXTERN int ZEXPORT inflateBackEnd(z_streamp strm);
 /*
      All memory allocated by inflateBackInit() is freed.
 
@@ -1197,7 +1200,7 @@ ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
    state was inconsistent.
 */
 
-ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+ZEXTERN uLong ZEXPORT zlibCompileFlags(void);
 /* Return flags indicating compile-time options.
 
     Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
@@ -1250,8 +1253,8 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
    you need special options.
 */
 
-ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
-                                 const Bytef *source, uLong sourceLen));
+ZEXTERN int ZEXPORT compress(Bytef *dest,   uLongf *destLen,
+                             const Bytef *source, uLong sourceLen);
 /*
      Compresses the source buffer into the destination buffer.  sourceLen is
    the byte length of the source buffer.  Upon entry, destLen is the total size
@@ -1265,9 +1268,9 @@ ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
    buffer.
 */
 
-ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
-                                  const Bytef *source, uLong sourceLen,
-                                  int level));
+ZEXTERN int ZEXPORT compress2(Bytef *dest,   uLongf *destLen,
+                              const Bytef *source, uLong sourceLen,
+                              int level);
 /*
      Compresses the source buffer into the destination buffer.  The level
    parameter has the same meaning as in deflateInit.  sourceLen is the byte
@@ -1281,15 +1284,15 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
    Z_STREAM_ERROR if the level parameter is invalid.
 */
 
-ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+ZEXTERN uLong ZEXPORT compressBound(uLong sourceLen);
 /*
      compressBound() returns an upper bound on the compressed size after
    compress() or compress2() on sourceLen bytes.  It would be used before a
    compress() or compress2() call to allocate the destination buffer.
 */
 
-ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
-                                   const Bytef *source, uLong sourceLen));
+ZEXTERN int ZEXPORT uncompress(Bytef *dest,   uLongf *destLen,
+                               const Bytef *source, uLong sourceLen);
 /*
      Decompresses the source buffer into the destination buffer.  sourceLen is
    the byte length of the source buffer.  Upon entry, destLen is the total size
@@ -1306,8 +1309,8 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
    buffer with the uncompressed data up to that point.
 */
 
-ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest,   uLongf *destLen,
-                                    const Bytef *source, uLong *sourceLen));
+ZEXTERN int ZEXPORT uncompress2(Bytef *dest,   uLongf *destLen,
+                                const Bytef *source, uLong *sourceLen);
 /*
      Same as uncompress, except that sourceLen is a pointer, where the
    length of the source is *sourceLen.  On return, *sourceLen is the number of
@@ -1326,7 +1329,7 @@ ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest,   uLongf *destLen,
 typedef struct gzFile_s *gzFile;    /* semi-opaque gzip file descriptor */
 
 /*
-ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode);
 
      Open the gzip (.gz) file at path for reading and decompressing, or
    compressing and writing.  The mode parameter is as in fopen ("rb" or "wb")
@@ -1363,7 +1366,7 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
    file could not be opened.
 */
 
-ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode);
 /*
      Associate a gzFile with the file descriptor fd.  File descriptors are
    obtained from calls like open, dup, creat, pipe or fileno (if the file has
@@ -1386,7 +1389,7 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
    will not detect if fd is invalid (unless fd is -1).
 */
 
-ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size);
 /*
      Set the internal buffer size used by this library's functions for file to
    size.  The default buffer size is 8192 bytes.  This function must be called
@@ -1402,7 +1405,7 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
    too late.
 */
 
-ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+ZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy);
 /*
      Dynamically update the compression level and strategy for file.  See the
    description of deflateInit2 for the meaning of these parameters. Previously
@@ -1413,7 +1416,7 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
    or Z_MEM_ERROR if there is a memory allocation error.
 */
 
-ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len);
 /*
      Read and decompress up to len uncompressed bytes from file into buf.  If
    the input file is not in gzip format, gzread copies the given number of
@@ -1443,8 +1446,8 @@ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
    Z_STREAM_ERROR.
 */
 
-ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
-                                     gzFile file));
+ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems,
+                                 gzFile file);
 /*
      Read and decompress up to nitems items of size size from file into buf,
    otherwise operating as gzread() does.  This duplicates the interface of
@@ -1469,14 +1472,14 @@ ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
    file, resetting and retrying on end-of-file, when size is not 1.
 */
 
-ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len));
+ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len);
 /*
      Compress and write the len uncompressed bytes at buf to file. gzwrite
    returns the number of uncompressed bytes written or 0 in case of error.
 */
 
-ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
-                                      z_size_t nitems, gzFile file));
+ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size,
+                                  z_size_t nitems, gzFile file);
 /*
      Compress and write nitems items of size size from buf to file, duplicating
    the interface of stdio's fwrite(), with size_t request and return types.  If
@@ -1489,7 +1492,7 @@ ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
    is returned, and the error state is set to Z_STREAM_ERROR.
 */
 
-ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
+ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...);
 /*
      Convert, format, compress, and write the arguments (...) to file under
    control of the string format, as in fprintf.  gzprintf returns the number of
@@ -1504,7 +1507,7 @@ ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
    This can be determined using zlibCompileFlags().
 */
 
-ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s);
 /*
      Compress and write the given null-terminated string s to file, excluding
    the terminating null character.
@@ -1512,7 +1515,7 @@ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
      gzputs returns the number of characters written, or -1 in case of error.
 */
 
-ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len);
 /*
      Read and decompress bytes from file into buf, until len-1 characters are
    read, or until a newline character is read and transferred to buf, or an
@@ -1526,13 +1529,13 @@ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
    buf are indeterminate.
 */
 
-ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+ZEXTERN int ZEXPORT gzputc(gzFile file, int c);
 /*
      Compress and write c, converted to an unsigned char, into file.  gzputc
    returns the value that was written, or -1 in case of error.
 */
 
-ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+ZEXTERN int ZEXPORT gzgetc(gzFile file);
 /*
      Read and decompress one byte from file.  gzgetc returns this byte or -1
    in case of end of file or error.  This is implemented as a macro for speed.
@@ -1541,7 +1544,7 @@ ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
    points to has been clobbered or not.
 */
 
-ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+ZEXTERN int ZEXPORT gzungetc(int c, gzFile file);
 /*
      Push c back onto the stream for file to be read as the first character on
    the next read.  At least one character of push-back is always allowed.
@@ -1553,7 +1556,7 @@ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
    gzseek() or gzrewind().
 */
 
-ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+ZEXTERN int ZEXPORT gzflush(gzFile file, int flush);
 /*
      Flush all pending output to file.  The parameter flush is as in the
    deflate() function.  The return value is the zlib error number (see function
@@ -1569,8 +1572,8 @@ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
 */
 
 /*
-ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
-                                   z_off_t offset, int whence));
+ZEXTERN z_off_t ZEXPORT gzseek(gzFile file,
+                               z_off_t offset, int whence);
 
      Set the starting position to offset relative to whence for the next gzread
    or gzwrite on file.  The offset represents a number of bytes in the
@@ -1588,7 +1591,7 @@ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
    would be before the current position.
 */
 
-ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
+ZEXTERN int ZEXPORT    gzrewind(gzFile file);
 /*
      Rewind file. This function is supported only for reading.
 
@@ -1596,7 +1599,7 @@ ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
 */
 
 /*
-ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
+ZEXTERN z_off_t ZEXPORT    gztell(gzFile file);
 
      Return the starting position for the next gzread or gzwrite on file.
    This position represents a number of bytes in the uncompressed data stream,
@@ -1607,7 +1610,7 @@ ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
 */
 
 /*
-ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+ZEXTERN z_off_t ZEXPORT gzoffset(gzFile file);
 
      Return the current compressed (actual) read or write offset of file.  This
    offset includes the count of bytes that precede the gzip stream, for example
@@ -1616,7 +1619,7 @@ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
    be used for a progress indicator.  On error, gzoffset() returns -1.
 */
 
-ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+ZEXTERN int ZEXPORT gzeof(gzFile file);
 /*
      Return true (1) if the end-of-file indicator for file has been set while
    reading, false (0) otherwise.  Note that the end-of-file indicator is set
@@ -1631,7 +1634,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
    has grown since the previous end of file was detected.
 */
 
-ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+ZEXTERN int ZEXPORT gzdirect(gzFile file);
 /*
      Return true (1) if file is being copied directly while reading, or false
    (0) if file is a gzip stream being decompressed.
@@ -1652,7 +1655,7 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
    gzip file reading and decompression, which may not be desired.)
 */
 
-ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
+ZEXTERN int ZEXPORT    gzclose(gzFile file);
 /*
      Flush all pending output for file, if necessary, close file and
    deallocate the (de)compression state.  Note that once file is closed, you
@@ -1665,8 +1668,8 @@ ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
    last read ended in the middle of a gzip stream, or Z_OK on success.
 */
 
-ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
-ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_r(gzFile file);
+ZEXTERN int ZEXPORT gzclose_w(gzFile file);
 /*
      Same as gzclose(), but gzclose_r() is only for use when reading, and
    gzclose_w() is only for use when writing or appending.  The advantage to
@@ -1677,7 +1680,7 @@ ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
    zlib library.
 */
 
-ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum);
 /*
      Return the error message for the last error which occurred on file.
    errnum is set to zlib error number.  If an error occurred in the file system
@@ -1693,7 +1696,7 @@ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
    functions above that do not distinguish those cases in their return values.
 */
 
-ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+ZEXTERN void ZEXPORT gzclearerr(gzFile file);
 /*
      Clear the error and end-of-file flags for file.  This is analogous to the
    clearerr() function in stdio.  This is useful for continuing to read a gzip
@@ -1710,7 +1713,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
    library.
 */
 
-ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+ZEXTERN uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len);
 /*
      Update a running Adler-32 checksum with the bytes buf[0..len-1] and
    return the updated checksum. An Adler-32 value is in the range of a 32-bit
@@ -1730,15 +1733,15 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
      if (adler != original_adler) error();
 */
 
-ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf,
-                                    z_size_t len));
+ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf,
+                                z_size_t len);
 /*
      Same as adler32(), but with a size_t length.
 */
 
 /*
-ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
-                                          z_off_t len2));
+ZEXTERN uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2,
+                                      z_off_t len2);
 
      Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
    and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
@@ -1748,7 +1751,7 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
    negative, the result has no meaning or utility.
 */
 
-ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+ZEXTERN uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len);
 /*
      Update a running CRC-32 with the bytes buf[0..len-1] and return the
    updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer.
@@ -1766,30 +1769,30 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
      if (crc != original_crc) error();
 */
 
-ZEXTERN uLong ZEXPORT crc32_z OF((uLong crc, const Bytef *buf,
-                                  z_size_t len));
+ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf,
+                              z_size_t len);
 /*
      Same as crc32(), but with a size_t length.
 */
 
 /*
-ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2);
 
      Combine two CRC-32 check values into one.  For two sequences of bytes,
    seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
    calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32
    check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
-   len2.
+   len2. len2 must be non-negative.
 */
 
 /*
-ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t len2));
+ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2);
 
      Return the operator corresponding to length len2, to be used with
-   crc32_combine_op().
+   crc32_combine_op(). len2 must be non-negative.
 */
 
-ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op));
+ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op);
 /*
      Give the same result as crc32_combine(), using op in place of len2. op is
    is generated from len2 by crc32_combine_gen(). This will be faster than
@@ -1802,20 +1805,20 @@ ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op));
 /* deflateInit and inflateInit are macros to allow checking the zlib version
  * and the compiler's view of z_stream:
  */
-ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
-                                     const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
-                                     const char *version, int stream_size));
-ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
-                                      int windowBits, int memLevel,
-                                      int strategy, const char *version,
-                                      int stream_size));
-ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
-                                      const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
-                                         unsigned char FAR *window,
-                                         const char *version,
-                                         int stream_size));
+ZEXTERN int ZEXPORT deflateInit_(z_streamp strm, int level,
+                                 const char *version, int stream_size);
+ZEXTERN int ZEXPORT inflateInit_(z_streamp strm,
+                                 const char *version, int stream_size);
+ZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int  level, int  method,
+                                  int windowBits, int memLevel,
+                                  int strategy, const char *version,
+                                  int stream_size);
+ZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int  windowBits,
+                                  const char *version, int stream_size);
+ZEXTERN int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits,
+                                     unsigned char FAR *window,
+                                     const char *version,
+                                     int stream_size);
 #ifdef Z_PREFIX_SET
 #  define z_deflateInit(strm, level) \
           deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
@@ -1860,7 +1863,7 @@ struct gzFile_s {
     unsigned char *next;
     z_off64_t pos;
 };
-ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));  /* backward compatibility */
+ZEXTERN int ZEXPORT gzgetc_(gzFile file);       /* backward compatibility */
 #ifdef Z_PREFIX_SET
 #  undef z_gzgetc
 #  define z_gzgetc(g) \
@@ -1877,13 +1880,13 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));  /* backward compatibility */
  * without large file support, _LFS64_LARGEFILE must also be true
  */
 #ifdef Z_LARGE64
-   ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
-   ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
-   ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
-   ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
-   ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
-   ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
-   ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off64_t));
+   ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *);
+   ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int);
+   ZEXTERN z_off64_t ZEXPORT gztell64(gzFile);
+   ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile);
+   ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t);
+   ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t);
+   ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t);
 #endif
 
 #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
@@ -1905,50 +1908,50 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));  /* backward compatibility */
 #    define crc32_combine_gen crc32_combine_gen64
 #  endif
 #  ifndef Z_LARGE64
-     ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
-     ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
-     ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
-     ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
-     ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
-     ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
-     ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t));
+     ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *);
+     ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int);
+     ZEXTERN z_off_t ZEXPORT gztell64(gzFile);
+     ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile);
+     ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t);
+     ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t);
+     ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t);
 #  endif
 #else
-   ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
-   ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
-   ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
-   ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
-   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
-   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
-   ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t));
+   ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *);
+   ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int);
+   ZEXTERN z_off_t ZEXPORT gztell(gzFile);
+   ZEXTERN z_off_t ZEXPORT gzoffset(gzFile);
+   ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t);
+   ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t);
+   ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t);
 #endif
 
 #else /* Z_SOLO */
 
-   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
-   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
-   ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t));
+   ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t);
+   ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t);
+   ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t);
 
 #endif /* !Z_SOLO */
 
 /* undocumented functions */
-ZEXTERN const char   * ZEXPORT zError           OF((int));
-ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp));
-ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table    OF((void));
-ZEXTERN int            ZEXPORT inflateUndermine OF((z_streamp, int));
-ZEXTERN int            ZEXPORT inflateValidate OF((z_streamp, int));
-ZEXTERN unsigned long  ZEXPORT inflateCodesUsed OF((z_streamp));
-ZEXTERN int            ZEXPORT inflateResetKeep OF((z_streamp));
-ZEXTERN int            ZEXPORT deflateResetKeep OF((z_streamp));
+ZEXTERN const char   * ZEXPORT zError(int);
+ZEXTERN int            ZEXPORT inflateSyncPoint(z_streamp);
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void);
+ZEXTERN int            ZEXPORT inflateUndermine(z_streamp, int);
+ZEXTERN int            ZEXPORT inflateValidate(z_streamp, int);
+ZEXTERN unsigned long  ZEXPORT inflateCodesUsed(z_streamp);
+ZEXTERN int            ZEXPORT inflateResetKeep(z_streamp);
+ZEXTERN int            ZEXPORT deflateResetKeep(z_streamp);
 #if defined(_WIN32) && !defined(Z_SOLO)
-ZEXTERN gzFile         ZEXPORT gzopen_w OF((const wchar_t *path,
-                                            const char *mode));
+ZEXTERN gzFile         ZEXPORT gzopen_w(const wchar_t *path,
+                                        const char *mode);
 #endif
 #if defined(STDC) || defined(Z_HAVE_STDARG_H)
 #  ifndef Z_SOLO
-ZEXTERN int            ZEXPORTVA gzvprintf Z_ARG((gzFile file,
-                                                  const char *format,
-                                                  va_list va));
+ZEXTERN int            ZEXPORTVA gzvprintf(gzFile file,
+                                           const char *format,
+                                           va_list va);
 #  endif
 #endif
 
diff --git a/src/java.base/share/native/libzip/zlib/zutil.c b/src/java.base/share/native/libzip/zlib/zutil.c
index ae147967861..92dda78497b 100644
--- a/src/java.base/share/native/libzip/zlib/zutil.c
+++ b/src/java.base/share/native/libzip/zlib/zutil.c
@@ -48,13 +48,11 @@ z_const char * const z_errmsg[10] = {
 };
 
 
-const char * ZEXPORT zlibVersion()
-{
+const char * ZEXPORT zlibVersion(void) {
     return ZLIB_VERSION;
 }
 
-uLong ZEXPORT zlibCompileFlags()
-{
+uLong ZEXPORT zlibCompileFlags(void) {
     uLong flags;
 
     flags = 0;
@@ -145,9 +143,7 @@ uLong ZEXPORT zlibCompileFlags()
 #  endif
 int ZLIB_INTERNAL z_verbose = verbose;
 
-void ZLIB_INTERNAL z_error(m)
-    char *m;
-{
+void ZLIB_INTERNAL z_error(char *m) {
     fprintf(stderr, "%s\n", m);
     exit(1);
 }
@@ -156,9 +152,7 @@ void ZLIB_INTERNAL z_error(m)
 /* exported to allow conversion of error code to string for compress() and
  * uncompress()
  */
-const char * ZEXPORT zError(err)
-    int err;
-{
+const char * ZEXPORT zError(int err) {
     return ERR_MSG(err);
 }
 
@@ -172,22 +166,14 @@ const char * ZEXPORT zError(err)
 
 #ifndef HAVE_MEMCPY
 
-void ZLIB_INTERNAL zmemcpy(dest, source, len)
-    Bytef* dest;
-    const Bytef* source;
-    uInt  len;
-{
+void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) {
     if (len == 0) return;
     do {
         *dest++ = *source++; /* ??? to be unrolled */
     } while (--len != 0);
 }
 
-int ZLIB_INTERNAL zmemcmp(s1, s2, len)
-    const Bytef* s1;
-    const Bytef* s2;
-    uInt  len;
-{
+int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) {
     uInt j;
 
     for (j = 0; j < len; j++) {
@@ -196,10 +182,7 @@ int ZLIB_INTERNAL zmemcmp(s1, s2, len)
     return 0;
 }
 
-void ZLIB_INTERNAL zmemzero(dest, len)
-    Bytef* dest;
-    uInt  len;
-{
+void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) {
     if (len == 0) return;
     do {
         *dest++ = 0;  /* ??? to be unrolled */
@@ -240,8 +223,7 @@ local ptr_table table[MAX_PTR];
  * a protected system like OS/2. Use Microsoft C instead.
  */
 
-voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size)
-{
+voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) {
     voidpf buf;
     ulg bsize = (ulg)items*size;
 
@@ -266,8 +248,7 @@ voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size)
     return buf;
 }
 
-void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
-{
+void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {
     int n;
 
     (void)opaque;
@@ -303,14 +284,12 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
 #  define _hfree   hfree
 #endif
 
-voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size)
-{
+voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) {
     (void)opaque;
     return _halloc((long)items, size);
 }
 
-void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
-{
+void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {
     (void)opaque;
     _hfree(ptr);
 }
@@ -323,25 +302,18 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
 #ifndef MY_ZCALLOC /* Any system without a special alloc function */
 
 #ifndef STDC
-extern voidp  malloc OF((uInt size));
-extern voidp  calloc OF((uInt items, uInt size));
-extern void   free   OF((voidpf ptr));
+extern voidp malloc(uInt size);
+extern voidp calloc(uInt items, uInt size);
+extern void free(voidpf ptr);
 #endif
 
-voidpf ZLIB_INTERNAL zcalloc(opaque, items, size)
-    voidpf opaque;
-    unsigned items;
-    unsigned size;
-{
+voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) {
     (void)opaque;
     return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
                               (voidpf)calloc(items, size);
 }
 
-void ZLIB_INTERNAL zcfree(opaque, ptr)
-    voidpf opaque;
-    voidpf ptr;
-{
+void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {
     (void)opaque;
     free(ptr);
 }
diff --git a/src/java.base/share/native/libzip/zlib/zutil.h b/src/java.base/share/native/libzip/zlib/zutil.h
index a7c842d26df..2b7e697bef9 100644
--- a/src/java.base/share/native/libzip/zlib/zutil.h
+++ b/src/java.base/share/native/libzip/zlib/zutil.h
@@ -23,7 +23,7 @@
  */
 
 /* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler
+ * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -80,7 +80,7 @@ typedef unsigned long  ulg;
 extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
 /* (size given to avoid silly warnings with Visual C++) */
 
-#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)]
 
 #define ERR_RETURN(strm,err) \
   return (strm->msg = ERR_MSG(err), (err))
@@ -161,17 +161,8 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
 #  endif
 #endif
 
-#if defined(MACOS) || defined(TARGET_OS_MAC)
+#if defined(MACOS)
 #  define OS_CODE  7
-#  ifndef Z_SOLO
-#    if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-#      include  /* for fdopen */
-#    else
-#      ifndef fdopen
-#        define fdopen(fd,mode) NULL /* No fdopen() */
-#      endif
-#    endif
-#  endif
 #endif
 
 #ifdef __acorn
@@ -194,18 +185,6 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
 #  define OS_CODE 19
 #endif
 
-#if defined(_BEOS_) || defined(RISCOS)
-#  define fdopen(fd,mode) NULL /* No fdopen() */
-#endif
-
-#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
-#  if defined(_WIN32_WCE)
-#    define fdopen(fd,mode) NULL /* No fdopen() */
-#  else
-#    define fdopen(fd,type)  _fdopen(fd,type)
-#  endif
-#endif
-
 #if defined(__BORLANDC__) && !defined(MSDOS)
   #pragma warn -8004
   #pragma warn -8008
@@ -215,9 +194,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
 /* provide prototypes for these when building zlib without LFS */
 #if !defined(_WIN32) && \
     (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
-    ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
-    ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
-    ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t));
+    ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t);
+    ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t);
+    ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t);
 #endif
 
         /* common defaults */
@@ -256,16 +235,16 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
 #    define zmemzero(dest, len) memset(dest, 0, len)
 #  endif
 #else
-   void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
-   int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
-   void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
+   void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len);
+   int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len);
+   void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len);
 #endif
 
 /* Diagnostic functions */
 #ifdef ZLIB_DEBUG
 #  include 
    extern int ZLIB_INTERNAL z_verbose;
-   extern void ZLIB_INTERNAL z_error OF((char *m));
+   extern void ZLIB_INTERNAL z_error(char *m);
 #  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
 #  define Trace(x) {if (z_verbose>=0) fprintf x ;}
 #  define Tracev(x) {if (z_verbose>0) fprintf x ;}
@@ -282,9 +261,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
 #endif
 
 #ifndef Z_SOLO
-   voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
-                                    unsigned size));
-   void ZLIB_INTERNAL zcfree  OF((voidpf opaque, voidpf ptr));
+   voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items,
+                                unsigned size);
+   void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr);
 #endif
 
 #define ZALLOC(strm, items, size) \
diff --git a/src/java.base/unix/native/libjli/java_md_common.c b/src/java.base/unix/native/libjli/java_md_common.c
index d9567d6788b..c71ddd4313a 100644
--- a/src/java.base/unix/native/libjli/java_md_common.c
+++ b/src/java.base/unix/native/libjli/java_md_common.c
@@ -45,20 +45,27 @@ static char* findLastPathComponent(char *buffer, const char *comp) {
 /*
  * Removes the trailing file name and any intermediate platform
  * directories, if any, and its enclosing directory.
+ * Second parameter is a hint about the type of a file. JNI_TRUE is for
+ * shared libraries and JNI_FALSE is for executables.
  * Ex: if a buffer contains "/foo/bin/javac" or "/foo/bin/x64/javac", the
  * truncated resulting buffer will contain "/foo".
  */
 static jboolean
-TruncatePath(char *buf)
+TruncatePath(char *buf, jboolean pathisdll)
 {
-    // try bin directory, maybe an executable
-    char *p = findLastPathComponent(buf, "/bin/");
+    /*
+     * If the file is a library, try lib directory first and then bin
+     * directory.
+     * If the file is an executable, try bin directory first and then lib
+     * directory.
+     */
+
+    char *p = findLastPathComponent(buf, pathisdll ? "/lib/" : "/bin/");
     if (p != NULL) {
         *p = '\0';
         return JNI_TRUE;
     }
-    // try lib directory, maybe a library
-    p = findLastPathComponent(buf, "/lib/");
+    p = findLastPathComponent(buf, pathisdll ? "/bin/" : "/lib/");
     if (p != NULL) {
         *p = '\0';
         return JNI_TRUE;
@@ -80,7 +87,7 @@ GetApplicationHome(char *buf, jint bufsize)
     } else {
         return JNI_FALSE;
     }
-    return TruncatePath(buf);
+    return TruncatePath(buf, JNI_FALSE);
 }
 
 /*
@@ -95,7 +102,7 @@ GetApplicationHomeFromDll(char *buf, jint bufsize)
     if (dladdr((void*)&GetApplicationHomeFromDll, &info) != 0) {
         char *path = realpath(info.dli_fname, buf);
         if (path == buf) {
-            return TruncatePath(buf);
+            return TruncatePath(buf, JNI_TRUE);
         }
     }
     return JNI_FALSE;
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m
index 150e82c6965..5826cbf31d1 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m
@@ -841,7 +841,7 @@ - (void) activateWindowMenuBar {
         isDisabled = !awtWindow.isEnabled;
     }
 
-    if (menuBar == nil) {
+    if (menuBar == nil && [ApplicationDelegate sharedDelegate] != nil) {
         menuBar = [[ApplicationDelegate sharedDelegate] defaultMenuBar];
         isDisabled = NO;
     }
@@ -1228,7 +1228,7 @@ + (AWTWindow *) lastKeyWindow {
         window.javaMenuBar = menuBar;
 
         CMenuBar* actualMenuBar = menuBar;
-        if (actualMenuBar == nil) {
+        if (actualMenuBar == nil && [ApplicationDelegate sharedDelegate] != nil) {
             actualMenuBar = [[ApplicationDelegate sharedDelegate] defaultMenuBar];
         }
 
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.m
index 590ed56e0c6..a8a821423de 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.m
@@ -116,8 +116,9 @@ + (ApplicationDelegate *)sharedDelegate {
 
     // don't install the EAWT delegate if another kind of NSApplication is installed, like say, Safari
     BOOL shouldInstall = NO;
+    BOOL overrideDelegate = (getenv("AWT_OVERRIDE_NSDELEGATE") != NULL);
     if (NSApp != nil) {
-        if ([NSApp isMemberOfClass:[NSApplication class]]) shouldInstall = YES;
+        if ([NSApp isMemberOfClass:[NSApplication class]] && overrideDelegate) shouldInstall = YES;
         if ([NSApp isKindOfClass:[NSApplicationAWT class]]) shouldInstall = YES;
     }
     checked = YES;
@@ -409,6 +410,19 @@ - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app {
     return NSTerminateLater;
 }
 
+- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app {
+    static BOOL checked = NO;
+    static BOOL supportsSecureState = YES;
+
+    if (checked == NO) {
+        checked = YES;
+        if (getenv("AWT_DISABLE_NSDELEGATE_SECURE_SAVE") != NULL) {
+            supportsSecureState = NO;
+        }
+    }
+    return supportsSecureState;
+}
+
 + (void)_systemWillPowerOff {
     [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SHUTDOWN];
 }
@@ -506,8 +520,10 @@ + (void)_setDockIconImage:(NSImage *)image {
     [dockImageView setImageScaling:NSImageScaleProportionallyUpOrDown];
     [dockImageView setImage:image];
 
-    [[ApplicationDelegate sharedDelegate].fProgressIndicator removeFromSuperview];
-    [dockImageView addSubview:[ApplicationDelegate sharedDelegate].fProgressIndicator];
+    if ([ApplicationDelegate sharedDelegate] != nil) {
+        [[ApplicationDelegate sharedDelegate].fProgressIndicator removeFromSuperview];
+        [dockImageView addSubview:[ApplicationDelegate sharedDelegate].fProgressIndicator];
+    }
 
     // add it to the NSDockTile
     [dockTile setContentView: dockImageView];
@@ -520,14 +536,15 @@ + (void)_setDockIconProgress:(NSNumber *)value {
 AWT_ASSERT_APPKIT_THREAD;
 
     ApplicationDelegate *delegate = [ApplicationDelegate sharedDelegate];
-    if ([value doubleValue] >= 0 && [value doubleValue] <=100) {
-        [delegate.fProgressIndicator setDoubleValue:[value doubleValue]];
-        [delegate.fProgressIndicator setHidden:NO];
-    } else {
-        [delegate.fProgressIndicator setHidden:YES];
+    if (delegate != nil) {
+        if ([value doubleValue] >= 0 && [value doubleValue] <=100) {
+            [delegate.fProgressIndicator setDoubleValue:[value doubleValue]];
+            [delegate.fProgressIndicator setHidden:NO];
+        } else {
+            [delegate.fProgressIndicator setHidden:YES];
+        }
+        [[NSApp dockTile] display];
     }
-
-    [[NSApp dockTile] display];
 }
 
 // Obtains the image of the Dock icon, either manually set, a drawn copy, or the default NSApplicationIcon
@@ -638,7 +655,9 @@ + (NSImage *)_dockIconImage {
 
     NSMenu *menu = (NSMenu *)jlong_to_ptr(nsMenuPtr);
     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
-        [ApplicationDelegate sharedDelegate].fDockMenu = menu;
+        if ([ApplicationDelegate sharedDelegate] != nil) {
+            [ApplicationDelegate sharedDelegate].fDockMenu = menu;
+        }
     }];
 
 JNI_COCOA_EXIT(env);
@@ -818,13 +837,15 @@ + (NSImage *)_dockIconImage {
 
     [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
         ApplicationDelegate *delegate = [ApplicationDelegate sharedDelegate];
-        switch (menuID) {
-            case com_apple_eawt__AppMenuBarHandler_MENU_ABOUT:
-                [delegate _updateAboutMenu:visible enabled:enabled];
-                break;
-            case com_apple_eawt__AppMenuBarHandler_MENU_PREFS:
-                [delegate _updatePreferencesMenu:visible enabled:enabled];
-                break;
+        if (delegate != nil) {
+            switch (menuID) {
+                case com_apple_eawt__AppMenuBarHandler_MENU_ABOUT:
+                    [delegate _updateAboutMenu:visible enabled:enabled];
+                    break;
+                case com_apple_eawt__AppMenuBarHandler_MENU_PREFS:
+                    [delegate _updatePreferencesMenu:visible enabled:enabled];
+                    break;
+            }
         }
     }];
 
@@ -843,7 +864,9 @@ + (NSImage *)_dockIconImage {
 
     CMenuBar *menu = (CMenuBar *)jlong_to_ptr(cMenuBarPtr);
     [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
-        [ApplicationDelegate sharedDelegate].fDefaultMenuBar = menu;
+        if ([ApplicationDelegate sharedDelegate] != nil) {
+            [ApplicationDelegate sharedDelegate].fDefaultMenuBar = menu;
+        }
     }];
 
 JNI_COCOA_EXIT(env);
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/CGraphicsDevice.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/CGraphicsDevice.m
index 9965cd5df93..0ae33ae045a 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/CGraphicsDevice.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/CGraphicsDevice.m
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023, 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
@@ -35,6 +35,7 @@
 #define DEFAULT_DEVICE_HEIGHT 768
 #define DEFAULT_DEVICE_DPI 72
 
+static NSInteger architecture = -1;
 /*
  * Convert the mode string to the more convinient bits per pixel value
  */
@@ -58,7 +59,17 @@ static int getBPPFromModeString(CFStringRef mode)
     return 0;
 }
 
-static BOOL isValidDisplayMode(CGDisplayModeRef mode){
+static BOOL isValidDisplayMode(CGDisplayModeRef mode) {
+    // Workaround for apple bug FB13261205, since it only affects arm based macs
+    // and arm support started with macOS 11 ignore the workaround for previous versions
+    if (@available(macOS 11, *)) {
+        if (architecture == -1) {
+            architecture = [[NSRunningApplication currentApplication] executableArchitecture];
+        }
+        if (architecture == NSBundleExecutableArchitectureARM64) {
+            return (CGDisplayModeGetPixelWidth(mode) >= 800);
+        }
+    }
     return (1 < CGDisplayModeGetWidth(mode) && 1 < CGDisplayModeGetHeight(mode));
 }
 
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuBar.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuBar.m
index 49a6a80da21..b02cc818063 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuBar.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuBar.m
@@ -210,9 +210,11 @@ -(void) deactivate {
         // In theory, this might cause flickering if the window gaining focus
         // has its own menu. However, I couldn't reproduce it on practice, so
         // perhaps this is a non issue.
-        CMenuBar* defaultMenu = [[ApplicationDelegate sharedDelegate] defaultMenuBar];
-        if (defaultMenu != nil) {
-            [CMenuBar activate:defaultMenu modallyDisabled:NO];
+        if ([ApplicationDelegate sharedDelegate] != nil) {
+            CMenuBar* defaultMenu = [[ApplicationDelegate sharedDelegate] defaultMenuBar];
+            if (defaultMenu != nil) {
+                [CMenuBar activate:defaultMenu modallyDisabled:NO];
+            }
         }
     }
 }
diff --git a/src/java.desktop/macosx/native/libosxapp/QueuingApplicationDelegate.m b/src/java.desktop/macosx/native/libosxapp/QueuingApplicationDelegate.m
index 034a990ebc8..ced48c72a36 100644
--- a/src/java.desktop/macosx/native/libosxapp/QueuingApplicationDelegate.m
+++ b/src/java.desktop/macosx/native/libosxapp/QueuingApplicationDelegate.m
@@ -200,6 +200,21 @@ - (void)_appDidUnhide
     } copy]];
 }
 
+
+- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app
+{
+    static BOOL checked = NO;
+    static BOOL supportsSecureState = YES;
+
+    if (checked == NO) {
+        checked = YES;
+        if (getenv("AWT_DISABLE_NSDELEGATE_SECURE_SAVE") != NULL) {
+            supportsSecureState = NO;
+        }
+    }
+    return supportsSecureState;
+}
+
 - (void)processQueuedEventsWithTargetDelegate:(id )delegate
 {
     self.realDelegate = delegate;
diff --git a/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java b/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java
index 438f9f399a0..f1a8a4bc007 100644
--- a/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java
+++ b/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, 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
@@ -23,7 +23,6 @@
  * questions.
  */
 
-
 package java.awt;
 
 import java.awt.image.BufferedImage;
@@ -36,7 +35,6 @@
 import sun.font.FontManagerFactory;
 import sun.java2d.HeadlessGraphicsEnvironment;
 import sun.java2d.SunGraphicsEnvironment;
-import sun.security.action.GetPropertyAction;
 
 /**
  *
diff --git a/src/java.desktop/share/classes/javax/swing/BufferStrategyPaintManager.java b/src/java.desktop/share/classes/javax/swing/BufferStrategyPaintManager.java
index 9ea050b0d80..3efacfcf225 100644
--- a/src/java.desktop/share/classes/javax/swing/BufferStrategyPaintManager.java
+++ b/src/java.desktop/share/classes/javax/swing/BufferStrategyPaintManager.java
@@ -243,6 +243,15 @@ public boolean paint(JComponent paintingComponent,
                 ((SunGraphics2D)bsg).constrain(xOffset + cx, yOffset + cy,
                                                x + w, y + h);
                 bsg.setClip(x, y, w, h);
+
+                if (!bufferComponent.isOpaque()) {
+                    final SunGraphics2D g2d = (SunGraphics2D) bsg;
+                    final Color oldBg = g2d.getBackground();
+                    g2d.setBackground(paintingComponent.getBackground());
+                    g2d.clearRect(x, y, w, h);
+                    g2d.setBackground(oldBg);
+                }
+
                 paintingComponent.paintToOffscreen(bsg, x, y, w, h,
                                                    x + w, y + h);
                 accumulate(xOffset + x, yOffset + y, w, h);
diff --git a/src/java.desktop/share/classes/javax/swing/JTabbedPane.java b/src/java.desktop/share/classes/javax/swing/JTabbedPane.java
index ee484e55c47..af5c917ee76 100644
--- a/src/java.desktop/share/classes/javax/swing/JTabbedPane.java
+++ b/src/java.desktop/share/classes/javax/swing/JTabbedPane.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, 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
@@ -31,6 +31,7 @@
 import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.FontMetrics;
+import java.awt.IllegalComponentStateException;
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.event.FocusListener;
@@ -2294,15 +2295,23 @@ public boolean contains(Point p) {
         }
 
         public Point getLocationOnScreen() {
-             Point parentLocation = parent.getLocationOnScreen();
+             Point parentLocation;
+             try {
+                 parentLocation = parent.getLocationOnScreen();
+             } catch (IllegalComponentStateException icse) {
+                 return null;
+             }
              Point componentLocation = getLocation();
+             if (parentLocation == null || componentLocation == null) {
+                 return null;
+             }
              componentLocation.translate(parentLocation.x, parentLocation.y);
              return componentLocation;
         }
 
         public Point getLocation() {
              Rectangle r = getBounds();
-             return new Point(r.x, r.y);
+             return r == null ? null : new Point(r.x, r.y);
         }
 
         public void setLocation(Point p) {
@@ -2319,7 +2328,7 @@ public void setBounds(Rectangle r) {
 
         public Dimension getSize() {
             Rectangle r = getBounds();
-            return new Dimension(r.width, r.height);
+            return r == null ? null : new Dimension(r.width, r.height);
         }
 
         public void setSize(Dimension d) {
diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java
index 56e7cf7a798..65905898d4c 100644
--- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java
+++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2022, 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,23 +25,47 @@
 
 package javax.swing.plaf.metal;
 
-import javax.swing.*;
-import javax.swing.border.*;
-import javax.swing.plaf.*;
-import javax.swing.plaf.basic.BasicBorders;
-import javax.swing.text.JTextComponent;
-
-import java.awt.Component;
-import java.awt.Insets;
+import java.awt.BasicStroke;
 import java.awt.Color;
+import java.awt.Component;
 import java.awt.Dialog;
 import java.awt.Frame;
 import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.Stroke;
 import java.awt.Window;
+import java.awt.geom.AffineTransform;
+
+import javax.swing.AbstractButton;
+import javax.swing.ButtonModel;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JInternalFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+import javax.swing.JToolBar;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.border.AbstractBorder;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.LineBorder;
+import javax.swing.border.MatteBorder;
+import javax.swing.plaf.BorderUIResource;
+import javax.swing.plaf.UIResource;
+import javax.swing.plaf.basic.BasicBorders;
+import javax.swing.text.JTextComponent;
 
 import sun.swing.StringUIClientPropertyKey;
 import sun.swing.SwingUtilities2;
 
+import static sun.java2d.pipe.Region.clipRound;
 
 /**
  * Factory object that can vend Borders appropriate for the metal L & F.
@@ -218,7 +242,7 @@ public Insets getBorderInsets(Component c, Insets newInsets) {
      */
     @SuppressWarnings("serial") // Superclass is not serializable across versions
     public static class InternalFrameBorder extends AbstractBorder implements UIResource {
-        private static final int corner = 14;
+        private static final int CORNER = 14;
 
         /**
          * Constructs a {@code InternalFrameBorder}.
@@ -226,8 +250,7 @@ public static class InternalFrameBorder extends AbstractBorder implements UIReso
         public InternalFrameBorder() {}
 
         public void paintBorder(Component c, Graphics g, int x, int y,
-                          int w, int h) {
-
+                                int w, int h) {
             Color background;
             Color highlight;
             Color shadow;
@@ -242,41 +265,99 @@ public void paintBorder(Component c, Graphics g, int x, int y,
                 shadow = MetalLookAndFeel.getControlInfo();
             }
 
-              g.setColor(background);
-              // Draw outermost lines
-              g.drawLine( 1, 0, w-2, 0);
-              g.drawLine( 0, 1, 0, h-2);
-              g.drawLine( w-1, 1, w-1, h-2);
-              g.drawLine( 1, h-1, w-2, h-1);
+            AffineTransform at = null;
+            Stroke oldStk = null;
+            boolean resetTransform = false;
+            int stkWidth = 1;
+            double scaleFactor = 1;
+
+            if (g instanceof Graphics2D g2d) {
+                at = g2d.getTransform();
+                scaleFactor = at.getScaleX();
+                oldStk = g2d.getStroke();
+
+                // if m01 or m10 is non-zero, then there is a rotation or shear
+                // skip resetting the transform
+                resetTransform = ((at.getShearX() == 0) && (at.getShearY() == 0));
+
+                if (resetTransform) {
+                    g2d.setTransform(new AffineTransform());
+                    stkWidth = clipRound(Math.min(at.getScaleX(), at.getScaleY()));
+                    g2d.setStroke(new BasicStroke((float) stkWidth));
+                }
+            }
 
-              // Draw the bulk of the border
-              for (int i = 1; i < 5; i++) {
-                  g.drawRect(x+i,y+i,w-(i*2)-1, h-(i*2)-1);
-              }
+            int xtranslation;
+            int ytranslation;
+            int width;
+            int height;
+
+            if (resetTransform) {
+                double xx = at.getScaleX() * x + at.getTranslateX();
+                double yy = at.getScaleY() * y + at.getTranslateY();
+                xtranslation = clipRound(xx);
+                ytranslation = clipRound(yy);
+                width = clipRound(at.getScaleX() * w + xx) - xtranslation;
+                height = clipRound(at.getScaleY() * h + yy) - ytranslation;
+            } else {
+                xtranslation = x;
+                ytranslation = y;
+                width = w;
+                height = h;
+            }
+            g.translate(xtranslation, ytranslation);
 
-              if (c instanceof JInternalFrame &&
-                               ((JInternalFrame)c).isResizable()) {
-                  g.setColor(highlight);
-                  // Draw the Long highlight lines
-                  g.drawLine( corner+1, 3, w-corner, 3);
-                  g.drawLine( 3, corner+1, 3, h-corner);
-                  g.drawLine( w-2, corner+1, w-2, h-corner);
-                  g.drawLine( corner+1, h-2, w-corner, h-2);
-
-                  g.setColor(shadow);
-                  // Draw the Long shadow lines
-                  g.drawLine( corner, 2, w-corner-1, 2);
-                  g.drawLine( 2, corner, 2, h-corner-1);
-                  g.drawLine( w-3, corner, w-3, h-corner-1);
-                  g.drawLine( corner, h-3, w-corner-1, h-3);
-              }
+            // scaled border
+            int thickness = (int) Math.ceil(4 * scaleFactor);
 
-          }
+            g.setColor(background);
+            // Draw the bulk of the border
+            for (int i = 0; i <= thickness; i++) {
+                g.drawRect(i, i, width - (i * 2), height - (i * 2));
+            }
+
+            if (c instanceof JInternalFrame && ((JInternalFrame)c).isResizable()) {
+                // midpoint at which highlight & shadow lines
+                // are positioned on the border
+                int midPoint = thickness / 2;
+                int offset = (((scaleFactor - stkWidth) >= 0) && ((stkWidth % 2) != 0)) ? 1 : 0;
+                int loc1 = thickness % 2 == 0 ? midPoint + stkWidth / 2 - stkWidth : midPoint;
+                int loc2 = thickness % 2 == 0 ? midPoint + stkWidth / 2 : midPoint + stkWidth;
+                // scaled corner
+                int corner = (int) Math.round(CORNER * scaleFactor);
+
+                // Draw the Long highlight lines
+                g.setColor(highlight);
+                g.drawLine(corner + 1, loc2, width - corner, loc2); //top
+                g.drawLine(loc2, corner + 1, loc2, height - corner); //left
+                g.drawLine((width - offset) - loc1, corner + 1,
+                        (width - offset) - loc1, height - corner); //right
+                g.drawLine(corner + 1, (height - offset) - loc1,
+                        width - corner, (height - offset) - loc1); //bottom
 
-          public Insets getBorderInsets(Component c, Insets newInsets) {
-              newInsets.set(5, 5, 5, 5);
-              return newInsets;
-          }
+                // Draw the Long shadow lines
+                g.setColor(shadow);
+                g.drawLine(corner, loc1, width - corner - 1, loc1);
+                g.drawLine(loc1, corner, loc1, height - corner - 1);
+                g.drawLine((width - offset) - loc2, corner,
+                        (width - offset) - loc2, height - corner - 1);
+                g.drawLine(corner, (height - offset) - loc2,
+                        width - corner - 1, (height - offset) - loc2);
+            }
+
+            // restore previous transform
+            g.translate(-xtranslation, -ytranslation);
+            if (resetTransform) {
+                Graphics2D g2d = (Graphics2D) g;
+                g2d.setTransform(at);
+                g2d.setStroke(oldStk);
+            }
+        }
+
+        public Insets getBorderInsets(Component c, Insets newInsets) {
+            newInsets.set(4, 4, 4, 4);
+            return newInsets;
+        }
     }
 
     /**
diff --git a/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java b/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java
index 3352e0e79f8..958b3a899a0 100644
--- a/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java
+++ b/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java
@@ -1821,8 +1821,6 @@ void empty() {
     }
 
 
-    static final Border noBorder = new EmptyBorder(0,0,0,0);
-
     /**
      * Class to carry out some of the duties of
      * CSS formatting.  Implementations of this
@@ -2523,7 +2521,6 @@ String formatRomanDigit(int level, int digit) {
         private boolean checkedForStart;
         private int start;
         private CSS.Value type;
-        URL imageurl;
         private StyleSheet ss = null;
         Icon img = null;
         private int bulletgap = 5;
@@ -3227,8 +3224,6 @@ else if (firstChar == '#') {
 
     // ---- Variables ---------------------------------------------
 
-    static final int DEFAULT_FONT_SIZE = 3;
-
     private transient Object fontSizeInherit;
 
     private CSS css;
diff --git a/src/java.desktop/share/legal/lcms.md b/src/java.desktop/share/legal/lcms.md
index da86a9c47ca..02af4fff000 100644
--- a/src/java.desktop/share/legal/lcms.md
+++ b/src/java.desktop/share/legal/lcms.md
@@ -1,34 +1,29 @@
-## Little Color Management System (LCMS) v2.15
+## Little Color Management System (LCMS) v2.16
 
 ### LCMS License
 
-README.1ST file information
 
-LittleCMS core is released under MIT License
+MIT License
 
----------------------------------
-
-Little CMS
-Copyright (c) 1998-2023 Marti Maria Saguer
+Copyright (C) 1998-2023 Marti Maria Saguer
 
 Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject
-to the following conditions:
+a copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following conditions:
 
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 ---------------------------------
 The below license applies to the following files:
@@ -47,7 +42,6 @@ Users of this code must verify correctness for their application.
 ### AUTHORS File Information
 ```
 
-
 Main Author
 ------------
 Marti Maria
@@ -91,6 +85,7 @@ Philipp Knechtges
 Amyspark
 Lovell Fuller
 Eli Schwartz
+Diogo Teles Sant'Anna
 
 Special Thanks
 --------------
diff --git a/src/java.desktop/share/native/liblcms/LCMS.c b/src/java.desktop/share/native/liblcms/LCMS.c
index 430186cd554..26280bf120b 100644
--- a/src/java.desktop/share/native/liblcms/LCMS.c
+++ b/src/java.desktop/share/native/liblcms/LCMS.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2024, 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
@@ -188,8 +188,13 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
         }
     }
 
+    cmsUInt32Number dwFlags = 0;
+    if (T_EXTRA(inFormatter) > 0 && T_EXTRA(outFormatter) > 0) {
+        dwFlags |= cmsFLAGS_COPY_ALPHA;
+    }
+
     sTrans = cmsCreateMultiprofileTransform(iccArray, j,
-        inFormatter, outFormatter, renderType, cmsFLAGS_COPY_ALPHA);
+        inFormatter, outFormatter, renderType, dwFlags);
 
     (*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0);
 
diff --git a/src/java.desktop/share/native/liblcms/cmsalpha.c b/src/java.desktop/share/native/liblcms/cmsalpha.c
index e69259e8a51..78d3ca6b671 100644
--- a/src/java.desktop/share/native/liblcms/cmsalpha.c
+++ b/src/java.desktop/share/native/liblcms/cmsalpha.c
@@ -431,7 +431,7 @@ static cmsFormatterAlphaFn FormattersAlpha[6][6] = {
 
 // This function computes the distance from each component to the next one in bytes.
 static
-void ComputeIncrementsForChunky(cmsUInt32Number Format,
+cmsBool ComputeIncrementsForChunky(cmsUInt32Number Format,
                                 cmsUInt32Number ComponentStartingOrder[],
                                 cmsUInt32Number ComponentPointerIncrements[])
 {
@@ -445,7 +445,7 @@ void ComputeIncrementsForChunky(cmsUInt32Number Format,
 
        // Sanity check
        if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
-           return;
+           return FALSE;
 
         memset(channels, 0, sizeof(channels));
 
@@ -482,13 +482,15 @@ void ComputeIncrementsForChunky(cmsUInt32Number Format,
 
        for (i = 0; i < extra; i++)
               ComponentStartingOrder[i] = channels[i + nchannels];
+
+       return TRUE;
 }
 
 
 
 //  On planar configurations, the distance is the stride added to any non-negative
 static
-void ComputeIncrementsForPlanar(cmsUInt32Number Format,
+cmsBool ComputeIncrementsForPlanar(cmsUInt32Number Format,
                                 cmsUInt32Number BytesPerPlane,
                                 cmsUInt32Number ComponentStartingOrder[],
                                 cmsUInt32Number ComponentPointerIncrements[])
@@ -502,7 +504,7 @@ void ComputeIncrementsForPlanar(cmsUInt32Number Format,
 
        // Sanity check
        if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
-           return;
+           return FALSE;
 
        memset(channels, 0, sizeof(channels));
 
@@ -538,29 +540,29 @@ void ComputeIncrementsForPlanar(cmsUInt32Number Format,
 
        for (i = 0; i < extra; i++)
               ComponentStartingOrder[i] = channels[i + nchannels];
+
+       return TRUE;
 }
 
 
 
 // Dispatcher por chunky and planar RGB
 static
-void  ComputeComponentIncrements(cmsUInt32Number Format,
+cmsBool ComputeComponentIncrements(cmsUInt32Number Format,
                                  cmsUInt32Number BytesPerPlane,
                                  cmsUInt32Number ComponentStartingOrder[],
                                  cmsUInt32Number ComponentPointerIncrements[])
 {
        if (T_PLANAR(Format)) {
 
-              ComputeIncrementsForPlanar(Format,  BytesPerPlane, ComponentStartingOrder, ComponentPointerIncrements);
+              return ComputeIncrementsForPlanar(Format,  BytesPerPlane, ComponentStartingOrder, ComponentPointerIncrements);
        }
        else {
-              ComputeIncrementsForChunky(Format,  ComponentStartingOrder, ComponentPointerIncrements);
+              return ComputeIncrementsForChunky(Format,  ComponentStartingOrder, ComponentPointerIncrements);
        }
 
 }
 
-
-
 // Handles extra channels copying alpha if requested by the flags
 void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
                                                void* out,
@@ -595,8 +597,10 @@ void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
         return;
 
     // Compute the increments
-    ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements);
-    ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements);
+    if (!ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements))
+        return;
+    if (!ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements))
+        return;
 
     // Check for conversions 8, 16, half, float, dbl
     copyValueFn = _cmsGetFormatterAlpha(p->ContextID, p->InputFormat, p->OutputFormat);
diff --git a/src/java.desktop/share/native/liblcms/cmscgats.c b/src/java.desktop/share/native/liblcms/cmscgats.c
index 9d0aea27d73..57725ae4731 100644
--- a/src/java.desktop/share/native/liblcms/cmscgats.c
+++ b/src/java.desktop/share/native/liblcms/cmscgats.c
@@ -87,7 +87,7 @@ typedef enum {
         SEOF,       // End of stream
         SSYNERROR,  // Syntax error found on stream
 
-        // Keywords
+        // IT8 symbols
 
         SBEGIN_DATA,
         SBEGIN_DATA_FORMAT,
@@ -95,7 +95,19 @@ typedef enum {
         SEND_DATA_FORMAT,
         SKEYWORD,
         SDATA_FORMAT_ID,
-        SINCLUDE
+        SINCLUDE,
+
+        // Cube symbols
+
+        SDOMAIN_MAX,
+        SDOMAIN_MIN,
+        S_LUT1D_SIZE,
+        S_LUT1D_INPUT_RANGE,
+        S_LUT3D_SIZE,
+        S_LUT3D_INPUT_RANGE,
+        S_LUT_IN_VIDEO_RANGE,
+        S_LUT_OUT_VIDEO_RANGE,
+        STITLE
 
     } SYMBOL;
 
@@ -178,6 +190,10 @@ typedef struct struct_it8 {
         cmsUInt32Number  TablesCount;                     // How many tables in this stream
         cmsUInt32Number  nTable;                          // The actual table
 
+        // Partser type
+        cmsBool        IsCUBE;
+
+        // Tables
         TABLE Tab[MAXTABLES];
 
         // Memory management
@@ -237,8 +253,8 @@ typedef struct {
 
    } KEYWORD;
 
-// The keyword->symbol translation table. Sorting is required.
-static const KEYWORD TabKeys[] = {
+// The keyword->symbol translation tables. Sorting is required.
+static const KEYWORD TabKeysIT8[] = {
 
         {"$INCLUDE",               SINCLUDE},   // This is an extension!
         {".INCLUDE",               SINCLUDE},   // This is an extension!
@@ -251,7 +267,25 @@ static const KEYWORD TabKeys[] = {
         {"KEYWORD",                SKEYWORD}
         };
 
-#define NUMKEYS (sizeof(TabKeys)/sizeof(KEYWORD))
+#define NUMKEYS_IT8 (sizeof(TabKeysIT8)/sizeof(KEYWORD))
+
+static const KEYWORD TabKeysCUBE[] = {
+
+        {"DOMAIN_MAX",             SDOMAIN_MAX },
+        {"DOMAIN_MIN",             SDOMAIN_MIN },
+        {"LUT_1D_SIZE",            S_LUT1D_SIZE },
+        {"LUT_1D_INPUT_RANGE",     S_LUT1D_INPUT_RANGE },
+        {"LUT_3D_SIZE",            S_LUT3D_SIZE },
+        {"LUT_3D_INPUT_RANGE",     S_LUT3D_INPUT_RANGE },
+        {"LUT_IN_VIDEO_RANGE",     S_LUT_IN_VIDEO_RANGE },
+        {"LUT_OUT_VIDEO_RANGE",    S_LUT_OUT_VIDEO_RANGE },
+        {"TITLE",                  STITLE }
+
+};
+
+#define NUMKEYS_CUBE (sizeof(TabKeysCUBE)/sizeof(KEYWORD))
+
+
 
 // Predefined properties
 
@@ -455,7 +489,7 @@ void StringCat(string* s, const char* c)
 static
 cmsBool isseparator(int c)
 {
-    return (c == ' ') || (c == '\t') ;
+    return (c == ' ') || (c == '\t');
 }
 
 // Checks whatever c is a valid identifier char
@@ -476,7 +510,7 @@ cmsBool isidchar(int c)
 static
 cmsBool isfirstidchar(int c)
 {
-     return !isdigit(c) && ismiddle(c);
+     return c != '-' && !isdigit(c) && ismiddle(c);
 }
 
 // Guess whether the supplied path looks like an absolute path
@@ -515,13 +549,13 @@ cmsBool BuildAbsolutePath(const char *relPath, const char *basePath, char *buffe
     // Already absolute?
     if (isabsolutepath(relPath)) {
 
-        strncpy(buffer, relPath, MaxLen);
+        memcpy(buffer, relPath, MaxLen);
         buffer[MaxLen-1] = 0;
         return TRUE;
     }
 
     // No, search for last
-    strncpy(buffer, basePath, MaxLen);
+    memcpy(buffer, basePath, MaxLen);
     buffer[MaxLen-1] = 0;
 
     tail = strrchr(buffer, DIR_CHAR);
@@ -603,10 +637,10 @@ void NextCh(cmsIT8* it8)
 
 // Try to see if current identifier is a keyword, if so return the referred symbol
 static
-SYMBOL BinSrchKey(const char *id)
+SYMBOL BinSrchKey(const char *id, int NumKeys, const KEYWORD* TabKeys)
 {
     int l = 1;
-    int r = NUMKEYS;
+    int r = NumKeys;
     int x, res;
 
     while (r >= l)
@@ -776,7 +810,7 @@ cmsFloat64Number ParseFloatNumber(const char *Buffer)
 }
 
 
-// Reads a string, special case to avoid infinite resursion on .include
+// Reads a string, special case to avoid infinite recursion on .include
 static
 void InStringSymbol(cmsIT8* it8)
 {
@@ -833,7 +867,9 @@ void InSymbol(cmsIT8* it8)
             } while (isidchar(it8->ch));
 
 
-            key = BinSrchKey(StringPtr(it8->id));
+            key = BinSrchKey(StringPtr(it8->id),
+                    it8->IsCUBE ? NUMKEYS_CUBE : NUMKEYS_IT8,
+                    it8->IsCUBE ? TabKeysCUBE : TabKeysIT8);
             if (key == SUNDEFINED) it8->sy = SIDENT;
             else it8->sy = key;
 
@@ -942,6 +978,7 @@ void InSymbol(cmsIT8* it8)
                         snprintf(buffer, sizeof(buffer), it8 ->DoubleFormatter, it8->dnum);
                     }
 
+                    StringClear(it8->id);
                     StringCat(it8->id, buffer);
 
                     do {
@@ -971,7 +1008,7 @@ void InSymbol(cmsIT8* it8)
         // Next line
         case '\r':
             NextCh(it8);
-            if (it8 ->ch == '\n')
+            if (it8->ch == '\n')
                 NextCh(it8);
             it8->sy = SEOLN;
             it8->lineno++;
@@ -1292,7 +1329,12 @@ KEYVALUE* AddToList(cmsIT8* it8, KEYVALUE** Head, const char *Key, const char *S
 
         // This may work for editing properties
 
-        //     return SynError(it8, "duplicate key <%s>", Key);
+        if (cmsstrcasecmp(Key, "NUMBER_OF_FIELDS") == 0 ||
+            cmsstrcasecmp(Key, "NUMBER_OF_SETS") == 0) {
+
+            SynError(it8, "duplicate key <%s>", Key);
+            return NULL;
+        }
     }
     else {
 
@@ -1413,6 +1455,8 @@ cmsHANDLE  CMSEXPORT cmsIT8Alloc(cmsContext ContextID)
     it8->MemoryBlock = NULL;
     it8->MemorySink  = NULL;
 
+    it8->IsCUBE = FALSE;
+
     it8 ->nTable = 0;
 
     it8->ContextID = ContextID;
@@ -1694,7 +1738,7 @@ char* GetData(cmsIT8* it8, int nSet, int nField)
     int nSamples    = t -> nSamples;
     int nPatches    = t -> nPatches;
 
-    if (nSet >= nPatches || nField >= nSamples)
+    if (nSet < 0 || nSet >= nPatches || nField < 0 || nField >= nSamples)
         return NULL;
 
     if (!t->Data) return NULL;
@@ -1879,11 +1923,14 @@ void WriteDataFormat(SAVESTREAM* fp, cmsIT8* it8)
        WriteStr(fp, " ");
        nSamples = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
 
-       for (i = 0; i < nSamples; i++) {
+       if (nSamples <= t->nSamples) {
 
-              WriteStr(fp, t->DataFormat[i]);
-              WriteStr(fp, ((i == (nSamples-1)) ? "\n" : "\t"));
-          }
+           for (i = 0; i < nSamples; i++) {
+
+               WriteStr(fp, t->DataFormat[i]);
+               WriteStr(fp, ((i == (nSamples - 1)) ? "\n" : "\t"));
+           }
+       }
 
        WriteStr (fp, "END_DATA_FORMAT\n");
 }
@@ -1893,39 +1940,42 @@ void WriteDataFormat(SAVESTREAM* fp, cmsIT8* it8)
 static
 void WriteData(SAVESTREAM* fp, cmsIT8* it8)
 {
-       int  i, j;
+       int  i, j, nPatches;
        TABLE* t = GetTable(it8);
 
        if (!t->Data) return;
 
        WriteStr (fp, "BEGIN_DATA\n");
 
-       t->nPatches = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
+       nPatches = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
 
-       for (i = 0; i < t-> nPatches; i++) {
+       if (nPatches <= t->nPatches) {
 
-              WriteStr(fp, " ");
+           for (i = 0; i < nPatches; i++) {
 
-              for (j = 0; j < t->nSamples; j++) {
+               WriteStr(fp, " ");
 
-                     char *ptr = t->Data[i*t->nSamples+j];
+               for (j = 0; j < t->nSamples; j++) {
 
-                     if (ptr == NULL) WriteStr(fp, "\"\"");
-                     else {
-                         // If value contains whitespace, enclose within quote
+                   char* ptr = t->Data[i * t->nSamples + j];
 
-                         if (strchr(ptr, ' ') != NULL) {
+                   if (ptr == NULL) WriteStr(fp, "\"\"");
+                   else {
+                       // If value contains whitespace, enclose within quote
 
-                             WriteStr(fp, "\"");
-                             WriteStr(fp, ptr);
-                             WriteStr(fp, "\"");
-                         }
-                         else
-                            WriteStr(fp, ptr);
-                     }
+                       if (strchr(ptr, ' ') != NULL) {
 
-                     WriteStr(fp, ((j == (t->nSamples-1)) ? "\n" : "\t"));
-              }
+                           WriteStr(fp, "\"");
+                           WriteStr(fp, ptr);
+                           WriteStr(fp, "\"");
+                       }
+                       else
+                           WriteStr(fp, ptr);
+                   }
+
+                   WriteStr(fp, ((j == (t->nSamples - 1)) ? "\n" : "\t"));
+               }
+           }
        }
        WriteStr (fp, "END_DATA\n");
 }
@@ -1946,15 +1996,29 @@ cmsBool CMSEXPORT cmsIT8SaveToFile(cmsHANDLE hIT8, const char* cFileName)
 
     for (i=0; i < it8 ->TablesCount; i++) {
 
-            cmsIT8SetTable(hIT8, i);
-            WriteHeader(it8, &sd);
-            WriteDataFormat(&sd, it8);
-            WriteData(&sd, it8);
+        TABLE* t;
+
+        if (cmsIT8SetTable(hIT8, i) < 0) goto Error;
+
+        /**
+        * Check for wrong data
+        */
+        t = GetTable(it8);
+        if (t->Data == NULL) goto Error;
+        if (t->DataFormat == NULL) goto Error;
+
+        WriteHeader(it8, &sd);
+        WriteDataFormat(&sd, it8);
+        WriteData(&sd, it8);
     }
 
     if (fclose(sd.stream) != 0) return FALSE;
-
     return TRUE;
+
+Error:
+    fclose(sd.stream);
+    return FALSE;
+
 }
 
 
@@ -2331,78 +2395,72 @@ void CookPointers(cmsIT8* it8)
     int idField, i;
     char* Fld;
     cmsUInt32Number j;
-    cmsUInt32Number nOldTable = it8 ->nTable;
+    cmsUInt32Number nOldTable = it8->nTable;
 
-    for (j=0; j < it8 ->TablesCount; j++) {
+    for (j = 0; j < it8->TablesCount; j++) {
 
-    TABLE* t = it8 ->Tab + j;
+        TABLE* t = it8->Tab + j;
 
-    t -> SampleID = 0;
-    it8 ->nTable = j;
+        t->SampleID = 0;
+        it8->nTable = j;
 
-    for (idField = 0; idField < t -> nSamples; idField++)
-    {
-        if (t ->DataFormat == NULL){
-            SynError(it8, "Undefined DATA_FORMAT");
-            return;
-        }
+        for (idField = 0; idField < t->nSamples; idField++)
+        {
+            if (t->DataFormat == NULL) {
+                SynError(it8, "Undefined DATA_FORMAT");
+                return;
+            }
 
-        Fld = t->DataFormat[idField];
-        if (!Fld) continue;
+            Fld = t->DataFormat[idField];
+            if (!Fld) continue;
 
 
-        if (cmsstrcasecmp(Fld, "SAMPLE_ID") == 0) {
+            if (cmsstrcasecmp(Fld, "SAMPLE_ID") == 0) {
 
-            t -> SampleID = idField;
-        }
+                t->SampleID = idField;
+            }
 
-        // "LABEL" is an extension. It keeps references to forward tables
+            // "LABEL" is an extension. It keeps references to forward tables
 
-        if ((cmsstrcasecmp(Fld, "LABEL") == 0) || Fld[0] == '$') {
+            if ((cmsstrcasecmp(Fld, "LABEL") == 0) || Fld[0] == '$') {
 
-            // Search for table references...
-            for (i = 0; i < t->nPatches; i++) {
+                // Search for table references...
+                for (i = 0; i < t->nPatches; i++) {
 
-                char* Label = GetData(it8, i, idField);
+                    char* Label = GetData(it8, i, idField);
 
-                if (Label) {
+                    if (Label) {
 
-                    cmsUInt32Number k;
+                        cmsUInt32Number k;
 
-                    // This is the label, search for a table containing
-                    // this property
+                        // This is the label, search for a table containing
+                        // this property
 
-                    for (k = 0; k < it8->TablesCount; k++) {
+                        for (k = 0; k < it8->TablesCount; k++) {
 
-                        TABLE* Table = it8->Tab + k;
-                        KEYVALUE* p;
+                            TABLE* Table = it8->Tab + k;
+                            KEYVALUE* p;
 
-                        if (IsAvailableOnList(Table->HeaderList, Label, NULL, &p)) {
+                            if (IsAvailableOnList(Table->HeaderList, Label, NULL, &p)) {
 
-                            // Available, keep type and table
-                            char Buffer[256];
+                                // Available, keep type and table
+                                char Buffer[256];
 
-                            char* Type = p->Value;
-                            int  nTable = (int)k;
+                                char* Type = p->Value;
+                                int  nTable = (int)k;
 
-                            snprintf(Buffer, 255, "%s %d %s", Label, nTable, Type);
+                                snprintf(Buffer, 255, "%s %d %s", Label, nTable, Type);
 
-                            SetData(it8, i, idField, Buffer);
+                                SetData(it8, i, idField, Buffer);
+                            }
                         }
                     }
-
-
                 }
-
             }
-
-
         }
-
-    }
     }
 
-    it8 ->nTable = nOldTable;
+    it8->nTable = nOldTable;
 }
 
 // Try to infere if the file is a CGATS/IT8 file at all. Read first line
@@ -2493,7 +2551,7 @@ cmsHANDLE  CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cm
     if (it8->MemoryBlock == NULL)
     {
         cmsIT8Free(hIT8);
-        return FALSE;
+        return NULL;
     }
 
     strncpy(it8 ->MemoryBlock, (const char*) Ptr, len);
@@ -2505,7 +2563,7 @@ cmsHANDLE  CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cm
     if (!ParseIT8(it8, type-1)) {
 
         cmsIT8Free(hIT8);
-        return FALSE;
+        return NULL;
     }
 
     CookPointers(it8);
@@ -2602,17 +2660,17 @@ cmsUInt32Number CMSEXPORT cmsIT8EnumProperties(cmsHANDLE hIT8, char ***PropertyN
     }
 
 
-        Props = (char**)AllocChunk(it8, sizeof(char*) * n);
-        if (Props != NULL) {
-
-                // Pass#2 - Fill pointers
-                n = 0;
-                for (p = t->HeaderList; p != NULL; p = p->Next) {
-                        Props[n++] = p->Keyword;
-                }
+    Props = (char**)AllocChunk(it8, sizeof(char*) * n);
+    if (Props != NULL) {
 
+        // Pass#2 - Fill pointers
+        n = 0;
+        for (p = t->HeaderList; p != NULL; p = p->Next) {
+            Props[n++] = p->Keyword;
         }
-        *PropertyNames = Props;
+
+    }
+    *PropertyNames = Props;
 
     return n;
 }
@@ -2972,3 +3030,236 @@ void CMSEXPORT cmsIT8DefineDblFormat(cmsHANDLE hIT8, const char* Formatter)
     it8 ->DoubleFormatter[sizeof(it8 ->DoubleFormatter)-1] = 0;
 }
 
+
+static
+cmsBool ReadNumbers(cmsIT8* cube, int n, cmsFloat64Number* arr)
+{
+    int i;
+
+    for (i = 0; i < n; i++) {
+
+        if (cube->sy == SINUM)
+            arr[i] = cube->inum;
+        else
+            if (cube->sy == SDNUM)
+                arr[i] = cube->dnum;
+            else
+                return SynError(cube, "Number expected");
+
+        InSymbol(cube);
+    }
+
+    return CheckEOLN(cube);
+}
+
+static
+cmsBool ParseCube(cmsIT8* cube, cmsStage** Shaper, cmsStage** CLUT, char title[])
+{
+    cmsFloat64Number domain_min[3] = { 0, 0, 0 };
+    cmsFloat64Number domain_max[3] = { 1.0, 1.0, 1.0 };
+    cmsFloat64Number check_0_1[2] = { 0, 1.0 };
+    int shaper_size = 0;
+    int lut_size = 0;
+    int i;
+
+    InSymbol(cube);
+
+    while (cube->sy != SEOF) {
+        switch (cube->sy)
+        {
+        // Set profile description
+        case STITLE:
+            InSymbol(cube);
+            if (!Check(cube, SSTRING, "Title string expected")) return FALSE;
+            memcpy(title, StringPtr(cube->str), MAXSTR);
+            title[MAXSTR - 1] = 0;
+            InSymbol(cube);
+            break;
+
+        // Define domain
+        case SDOMAIN_MIN:
+            InSymbol(cube);
+            if (!ReadNumbers(cube, 3, domain_min)) return FALSE;
+            break;
+
+        case SDOMAIN_MAX:
+            InSymbol(cube);
+            if (!ReadNumbers(cube, 3, domain_max)) return FALSE;
+            break;
+
+        // Define shaper
+        case S_LUT1D_SIZE:
+            InSymbol(cube);
+            if (!Check(cube, SINUM, "Shaper size expected")) return FALSE;
+            shaper_size = cube->inum;
+            InSymbol(cube);
+            break;
+
+        // Deefine CLUT
+        case S_LUT3D_SIZE:
+            InSymbol(cube);
+            if (!Check(cube, SINUM, "LUT size expected")) return FALSE;
+            lut_size = cube->inum;
+            InSymbol(cube);
+            break;
+
+        // Range. If present, has to be 0..1.0
+        case S_LUT1D_INPUT_RANGE:
+        case S_LUT3D_INPUT_RANGE:
+            InSymbol(cube);
+            if (!ReadNumbers(cube, 2, check_0_1)) return FALSE;
+            if (check_0_1[0] != 0 || check_0_1[1] != 1.0) {
+                return SynError(cube, "Unsupported format");
+            }
+            break;
+
+        case SEOLN:
+            InSymbol(cube);
+            break;
+
+        default:
+        case S_LUT_IN_VIDEO_RANGE:
+        case S_LUT_OUT_VIDEO_RANGE:
+            return SynError(cube, "Unsupported format");
+
+            // Read and create tables
+        case SINUM:
+        case SDNUM:
+
+            if (shaper_size > 0) {
+
+                cmsToneCurve* curves[3];
+                cmsFloat32Number* shapers = (cmsFloat32Number*)_cmsMalloc(cube->ContextID, 3 * shaper_size * sizeof(cmsFloat32Number));
+                if (shapers == NULL) return FALSE;
+
+                for (i = 0; i < shaper_size; i++) {
+
+                    cmsFloat64Number nums[3];
+
+                    if (!ReadNumbers(cube, 3, nums)) return FALSE;
+
+                    shapers[i + 0]               = (cmsFloat32Number) ((nums[0] - domain_min[0]) / (domain_max[0] - domain_min[0]));
+                    shapers[i + 1 * shaper_size] = (cmsFloat32Number) ((nums[1] - domain_min[1]) / (domain_max[1] - domain_min[1]));
+                    shapers[i + 2 * shaper_size] = (cmsFloat32Number) ((nums[2] - domain_min[2]) / (domain_max[2] - domain_min[2]));
+                }
+
+                for (i = 0; i < 3; i++) {
+
+                    curves[i] = cmsBuildTabulatedToneCurveFloat(cube->ContextID, shaper_size,
+                        &shapers[i * shaper_size]);
+                    if (curves[i] == NULL) return FALSE;
+                }
+
+                *Shaper = cmsStageAllocToneCurves(cube->ContextID, 3, curves);
+
+                cmsFreeToneCurveTriple(curves);
+            }
+
+            if (lut_size > 0) {
+
+                int nodes = lut_size * lut_size * lut_size;
+
+                cmsFloat32Number* lut_table = _cmsMalloc(cube->ContextID, nodes * 3 * sizeof(cmsFloat32Number));
+                if (lut_table == NULL) return FALSE;
+
+                for (i = 0; i < nodes; i++) {
+
+                    cmsFloat64Number nums[3];
+
+                    if (!ReadNumbers(cube, 3, nums)) return FALSE;
+
+                    lut_table[i * 3 + 2] = (cmsFloat32Number) ((nums[0] - domain_min[0]) / (domain_max[0] - domain_min[0]));
+                    lut_table[i * 3 + 1] = (cmsFloat32Number) ((nums[1] - domain_min[1]) / (domain_max[1] - domain_min[1]));
+                    lut_table[i * 3 + 0] = (cmsFloat32Number) ((nums[2] - domain_min[2]) / (domain_max[2] - domain_min[2]));
+                }
+
+                *CLUT = cmsStageAllocCLutFloat(cube->ContextID, lut_size, 3, 3, lut_table);
+                _cmsFree(cube->ContextID, lut_table);
+            }
+
+            if (!Check(cube, SEOF, "Extra symbols found in file")) return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+// Share the parser to read .cube format and create RGB devicelink profiles
+cmsHPROFILE CMSEXPORT cmsCreateDeviceLinkFromCubeFileTHR(cmsContext ContextID, const char* cFileName)
+{
+    cmsHPROFILE hProfile = NULL;
+    cmsIT8* cube = NULL;
+    cmsPipeline* Pipeline = NULL;
+    cmsStage* CLUT = NULL;
+    cmsStage* Shaper = NULL;
+    cmsMLU* DescriptionMLU = NULL;
+    char title[MAXSTR];
+
+    _cmsAssert(cFileName != NULL);
+
+    cube = (cmsIT8*) cmsIT8Alloc(ContextID);
+    if (!cube) return NULL;
+
+    cube->IsCUBE = TRUE;
+    cube->FileStack[0]->Stream = fopen(cFileName, "rt");
+
+    if (!cube->FileStack[0]->Stream) goto Done;
+
+    strncpy(cube->FileStack[0]->FileName, cFileName, cmsMAX_PATH - 1);
+    cube->FileStack[0]->FileName[cmsMAX_PATH - 1] = 0;
+
+    if (!ParseCube(cube, &Shaper, &CLUT, title)) goto Done;
+
+    // Success on parsing, let's create the profile
+    hProfile = cmsCreateProfilePlaceholder(ContextID);
+    if (!hProfile) goto Done;
+
+    cmsSetProfileVersion(hProfile, 4.4);
+
+    cmsSetDeviceClass(hProfile, cmsSigLinkClass);
+    cmsSetColorSpace(hProfile,  cmsSigRgbData);
+    cmsSetPCS(hProfile,         cmsSigRgbData);
+
+    cmsSetHeaderRenderingIntent(hProfile, INTENT_PERCEPTUAL);
+
+    // Creates a Pipeline to hold CLUT and shaper
+    Pipeline = cmsPipelineAlloc(ContextID, 3, 3);
+    if (Pipeline == NULL) goto Done;
+
+    // Populates the pipeline
+    if (Shaper != NULL) {
+        if (!cmsPipelineInsertStage(Pipeline, cmsAT_BEGIN, Shaper))
+            goto Done;
+    }
+
+    if (CLUT != NULL) {
+        if (!cmsPipelineInsertStage(Pipeline, cmsAT_END, CLUT))
+            goto Done;
+    }
+
+    // Propagate the description. We put no copyright because we know
+    // nothing on the copyrighted state of the .cube
+    DescriptionMLU = cmsMLUalloc(ContextID, 1);
+    if (!cmsMLUsetUTF8(DescriptionMLU, cmsNoLanguage, cmsNoCountry, title)) goto Done;
+
+    // Flush the tags
+    if (!cmsWriteTag(hProfile, cmsSigProfileDescriptionTag, DescriptionMLU)) goto Done;
+    if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, (void*)Pipeline)) goto Done;
+
+Done:
+
+    if (DescriptionMLU != NULL)
+        cmsMLUfree(DescriptionMLU);
+
+    if (Pipeline != NULL)
+        cmsPipelineFree(Pipeline);
+
+    cmsIT8Free((cmsHANDLE) cube);
+
+    return hProfile;
+}
+
+cmsHPROFILE CMSEXPORT cmsCreateDeviceLinkFromCubeFile(const char* cFileName)
+{
+    return cmsCreateDeviceLinkFromCubeFileTHR(NULL, cFileName);
+}
diff --git a/src/java.desktop/share/native/liblcms/cmscnvrt.c b/src/java.desktop/share/native/liblcms/cmscnvrt.c
index b73d594f2ec..d18865b15b9 100644
--- a/src/java.desktop/share/native/liblcms/cmscnvrt.c
+++ b/src/java.desktop/share/native/liblcms/cmscnvrt.c
@@ -263,7 +263,7 @@ cmsFloat64Number CHAD2Temp(const cmsMAT3* Chad)
 
 // Compute a CHAD based on a given temperature
 static
-    void Temp2CHAD(cmsMAT3* Chad, cmsFloat64Number Temp)
+void Temp2CHAD(cmsMAT3* Chad, cmsFloat64Number Temp)
 {
     cmsCIEXYZ White;
     cmsCIExyY ChromaticityOfWhite;
@@ -744,6 +744,16 @@ int BlackPreservingGrayOnlySampler(CMSREGISTER const cmsUInt16Number In[], CMSRE
     return TRUE;
 }
 
+
+// Check whatever the profile is a CMYK->CMYK devicelink
+static
+cmsBool is_cmyk_devicelink(cmsHPROFILE hProfile)
+{
+    return cmsGetDeviceClass(hProfile) == cmsSigLinkClass &&
+            cmsGetColorSpace(hProfile) == cmsSigCmykData &&
+            cmsGetColorSpace(hProfile) == cmsSigCmykData;
+}
+
 // This is the entry for black-preserving K-only intents, which are non-ICC
 static
 cmsPipeline*  BlackPreservingKOnlyIntents(cmsContext     ContextID,
@@ -776,14 +786,16 @@ cmsPipeline*  BlackPreservingKOnlyIntents(cmsContext     ContextID,
     lastProfilePos = nProfiles - 1;
     hLastProfile = hProfiles[lastProfilePos];
 
-    while (lastProfilePos > 1)
+    // Skip CMYK->CMYK devicelinks on ending
+    while (is_cmyk_devicelink(hLastProfile))
     {
-        hLastProfile = hProfiles[--lastProfilePos];
-        if (cmsGetColorSpace(hLastProfile) != cmsSigCmykData ||
-            cmsGetDeviceClass(hLastProfile) != cmsSigLinkClass)
+        if (lastProfilePos < 2)
             break;
+
+        hLastProfile = hProfiles[--lastProfilePos];
     }
 
+
     preservationProfilesCount = lastProfilePos + 1;
 
     // Check for non-cmyk profiles
@@ -800,7 +812,7 @@ cmsPipeline*  BlackPreservingKOnlyIntents(cmsContext     ContextID,
 
     // Create a LUT holding normal ICC transform
     bp.cmyk2cmyk = DefaultICCintents(ContextID,
-                                     preservationProfilesCount,
+        preservationProfilesCount,
         ICCIntents,
         hProfiles,
         BPC,
@@ -812,7 +824,7 @@ cmsPipeline*  BlackPreservingKOnlyIntents(cmsContext     ContextID,
     // Now, compute the tone curve
     bp.KTone = _cmsBuildKToneCurve(ContextID,
         4096,
-                                    preservationProfilesCount,
+        preservationProfilesCount,
         ICCIntents,
         hProfiles,
         BPC,
@@ -1002,12 +1014,13 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext     ContextID,
     lastProfilePos = nProfiles - 1;
     hLastProfile = hProfiles[lastProfilePos];
 
-    while (lastProfilePos > 1)
+    // Skip CMYK->CMYK devicelinks on ending
+    while (is_cmyk_devicelink(hLastProfile))
     {
-        hLastProfile = hProfiles[--lastProfilePos];
-        if (cmsGetColorSpace(hLastProfile) != cmsSigCmykData ||
-            cmsGetDeviceClass(hLastProfile) != cmsSigLinkClass)
+        if (lastProfilePos < 2)
             break;
+
+        hLastProfile = hProfiles[--lastProfilePos];
     }
 
     preservationProfilesCount = lastProfilePos + 1;
@@ -1177,8 +1190,7 @@ cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUIn
     cmsIntentsList* pt;
     cmsUInt32Number nIntents;
 
-
-    for (nIntents=0, pt = ctx->Intents; pt != NULL; pt = pt -> Next)
+    for (nIntents=0, pt = DefaultIntents; pt != NULL; pt = pt -> Next)
     {
         if (nIntents < nMax) {
             if (Codes != NULL)
@@ -1191,7 +1203,7 @@ cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUIn
         nIntents++;
     }
 
-    for (nIntents=0, pt = DefaultIntents; pt != NULL; pt = pt -> Next)
+    for (pt = ctx->Intents; pt != NULL; pt = pt -> Next)
     {
         if (nIntents < nMax) {
             if (Codes != NULL)
@@ -1203,6 +1215,7 @@ cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUIn
 
         nIntents++;
     }
+
     return nIntents;
 }
 
diff --git a/src/java.desktop/share/native/liblcms/cmserr.c b/src/java.desktop/share/native/liblcms/cmserr.c
index 739cc0b2c98..9fb7db89c9a 100644
--- a/src/java.desktop/share/native/liblcms/cmserr.c
+++ b/src/java.desktop/share/native/liblcms/cmserr.c
@@ -101,7 +101,7 @@ long int CMSEXPORT cmsfilelength(FILE* f)
 //
 // This is the interface to low-level memory management routines. By default a simple
 // wrapping to malloc/free/realloc is provided, although there is a limit on the max
-// amount of memoy that can be reclaimed. This is mostly as a safety feature to prevent
+// amount of memory that can be reclaimed. This is mostly as a safety feature to prevent
 // bogus or evil code to allocate huge blocks that otherwise lcms would never need.
 
 #define MAX_MEMORY_FOR_ALLOC  ((cmsUInt32Number)(1024U*1024U*512U))
@@ -121,7 +121,8 @@ cmsBool   _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plug
 static
 void* _cmsMallocDefaultFn(cmsContext ContextID, cmsUInt32Number size)
 {
-    if (size > MAX_MEMORY_FOR_ALLOC) return NULL;  // Never allow over maximum
+    // Never allow 0 or over maximum
+    if (size == 0 || size > MAX_MEMORY_FOR_ALLOC) return NULL;
 
     return (void*) malloc(size);
 
@@ -263,7 +264,7 @@ cmsBool  _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase *Data)
 
     // NULL forces to reset to defaults. In this special case, the defaults are stored in the context structure.
     // Remaining plug-ins does NOT have any copy in the context structure, but this is somehow special as the
-    // context internal data should be malloce'd by using those functions.
+    // context internal data should be malloc'ed by using those functions.
     if (Data == NULL) {
 
        struct _cmsContext_struct* ctx = ( struct _cmsContext_struct*) ContextID;
diff --git a/src/java.desktop/share/native/liblcms/cmsgamma.c b/src/java.desktop/share/native/liblcms/cmsgamma.c
index 08409434064..8e489a43c55 100644
--- a/src/java.desktop/share/native/liblcms/cmsgamma.c
+++ b/src/java.desktop/share/native/liblcms/cmsgamma.c
@@ -329,6 +329,10 @@ cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsUInt32Number nEnt
         return p;
 
 Error:
+    for (i=0; i < nSegments; i++) {
+        if (p ->Segments && p ->Segments[i].SampledPoints) _cmsFree(ContextID, p ->Segments[i].SampledPoints);
+        if (p ->SegInterp && p ->SegInterp[i]) _cmsFree(ContextID, p ->SegInterp[i]);
+    }
     if (p -> SegInterp) _cmsFree(ContextID, p -> SegInterp);
     if (p -> Segments) _cmsFree(ContextID, p -> Segments);
     if (p -> Evals) _cmsFree(ContextID, p -> Evals);
@@ -622,10 +626,16 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
     case 6:
         e = Params[1]*R + Params[2];
 
-        if (e < 0)
-            Val = Params[3];
-        else
-            Val = pow(e, Params[0]) + Params[3];
+        // On gamma 1.0, don't clamp
+        if (Params[0] == 1.0) {
+            Val = e + Params[3];
+        }
+        else {
+            if (e < 0)
+                Val = Params[3];
+            else
+                Val = pow(e, Params[0]) + Params[3];
+        }
         break;
 
     // ((Y - c) ^1/Gamma - b) / a
@@ -1520,13 +1530,13 @@ cmsFloat64Number CMSEXPORT cmsEstimateGamma(const cmsToneCurve* t, cmsFloat64Num
     return (sum / n);   // The mean
 }
 
+// Retrieve segments on tone curves
 
-// Retrieve parameters on one-segment tone curves
-
-cmsFloat64Number* CMSEXPORT cmsGetToneCurveParams(const cmsToneCurve* t)
+const cmsCurveSegment* CMSEXPORT cmsGetToneCurveSegment(cmsInt32Number n, const cmsToneCurve* t)
 {
     _cmsAssert(t != NULL);
 
-    if (t->nSegments != 1) return NULL;
-    return t->Segments[0].Params;
+    if (n < 0 || n >= (cmsInt32Number) t->nSegments) return NULL;
+    return t->Segments + n;
 }
+
diff --git a/src/java.desktop/share/native/liblcms/cmsgmt.c b/src/java.desktop/share/native/liblcms/cmsgmt.c
index 60a01aa5088..e9ee73b52cd 100644
--- a/src/java.desktop/share/native/liblcms/cmsgmt.c
+++ b/src/java.desktop/share/native/liblcms/cmsgmt.c
@@ -248,7 +248,7 @@ int GamutSampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Nu
     cmsUInt16Number Proof[cmsMAXCHANNELS], Proof2[cmsMAXCHANNELS];
     cmsFloat64Number dE1, dE2, ErrorRatio;
 
-    // Assume in-gamut by default.
+    // Assume in-gamut by default. NEVER READ, USED FOR DEBUG PURPOSES.
     ErrorRatio = 1.0;
 
     // Convert input to Lab
@@ -625,7 +625,7 @@ cmsBool CMSEXPORT cmsDesaturateLab(cmsCIELab* Lab,
 // Actually, doing that "well" is quite hard, since every component may behave completely different.
 // Since the true point of this function is to detect suitable optimizations, I am imposing some requirements
 // that simplifies things: only RGB, and only profiles that can got in both directions.
-// The algorithm obtains Y from a syntetical gray R=G=B. Then least squares fitting is used to estimate gamma.
+// The algorithm obtains Y from a synthetical gray R=G=B. Then least squares fitting is used to estimate gamma.
 // For gamma close to 1.0, RGB is linear. On profiles not supported, -1 is returned.
 
 cmsFloat64Number CMSEXPORT cmsDetectRGBProfileGamma(cmsHPROFILE hProfile, cmsFloat64Number threshold)
diff --git a/src/java.desktop/share/native/liblcms/cmsio0.c b/src/java.desktop/share/native/liblcms/cmsio0.c
index 6763970f619..05baa9392e2 100644
--- a/src/java.desktop/share/native/liblcms/cmsio0.c
+++ b/src/java.desktop/share/native/liblcms/cmsio0.c
@@ -560,6 +560,20 @@ cmsHPROFILE CMSEXPORT cmsCreateProfilePlaceholder(cmsContext ContextID)
     // Set default version
     Icc ->Version =  0x02100000;
 
+    // Set default CMM (that's me!)
+    Icc ->CMM = lcmsSignature;
+
+    // Set default creator
+    // Created by LittleCMS (that's me!)
+    Icc ->creator = lcmsSignature;
+
+    // Set default platform
+#ifdef CMS_IS_WINDOWS_
+    Icc ->platform = cmsSigMicrosoft;
+#else
+    Icc ->platform = cmsSigMacintosh;
+#endif
+
     // Set default device class
     Icc->DeviceClass = cmsSigDisplayClass;
 
@@ -813,11 +827,13 @@ cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
     }
 
     // Adjust endianness of the used parameters
+    Icc -> CMM             = _cmsAdjustEndianess32(Header.cmmId);
     Icc -> DeviceClass     = (cmsProfileClassSignature) _cmsAdjustEndianess32(Header.deviceClass);
     Icc -> ColorSpace      = (cmsColorSpaceSignature)   _cmsAdjustEndianess32(Header.colorSpace);
     Icc -> PCS             = (cmsColorSpaceSignature)   _cmsAdjustEndianess32(Header.pcs);
 
     Icc -> RenderingIntent = _cmsAdjustEndianess32(Header.renderingIntent);
+    Icc -> platform        = (cmsPlatformSignature)_cmsAdjustEndianess32(Header.platform);
     Icc -> flags           = _cmsAdjustEndianess32(Header.flags);
     Icc -> manufacturer    = _cmsAdjustEndianess32(Header.manufacturer);
     Icc -> model           = _cmsAdjustEndianess32(Header.model);
@@ -922,7 +938,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
     cmsUInt32Number Count;
 
     Header.size        = _cmsAdjustEndianess32(UsedSpace);
-    Header.cmmId       = _cmsAdjustEndianess32(lcmsSignature);
+    Header.cmmId       = _cmsAdjustEndianess32(Icc ->CMM);
     Header.version     = _cmsAdjustEndianess32(Icc ->Version);
 
     Header.deviceClass = (cmsProfileClassSignature) _cmsAdjustEndianess32(Icc -> DeviceClass);
@@ -934,11 +950,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
 
     Header.magic       = _cmsAdjustEndianess32(cmsMagicNumber);
 
-#ifdef CMS_IS_WINDOWS_
-    Header.platform    = (cmsPlatformSignature) _cmsAdjustEndianess32(cmsSigMicrosoft);
-#else
-    Header.platform    = (cmsPlatformSignature) _cmsAdjustEndianess32(cmsSigMacintosh);
-#endif
+    Header.platform    = (cmsPlatformSignature) _cmsAdjustEndianess32(Icc -> platform);
 
     Header.flags        = _cmsAdjustEndianess32(Icc -> flags);
     Header.manufacturer = _cmsAdjustEndianess32(Icc -> manufacturer);
@@ -954,8 +966,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
     Header.illuminant.Y = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->Y));
     Header.illuminant.Z = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->Z));
 
-    // Created by LittleCMS (that's me!)
-    Header.creator      = _cmsAdjustEndianess32(lcmsSignature);
+    Header.creator      = _cmsAdjustEndianess32(Icc ->creator);
 
     memset(&Header.reserved, 0, sizeof(Header.reserved));
 
diff --git a/src/java.desktop/share/native/liblcms/cmsio1.c b/src/java.desktop/share/native/liblcms/cmsio1.c
index bd8a832ac40..e42d4d38987 100644
--- a/src/java.desktop/share/native/liblcms/cmsio1.c
+++ b/src/java.desktop/share/native/liblcms/cmsio1.c
@@ -607,7 +607,7 @@ cmsPipeline* _cmsReadFloatOutputTag(cmsHPROFILE hProfile, cmsTagSignature tagFlo
     return NULL;
 }
 
-// Create an output MPE LUT from agiven profile. Version mismatches are handled here
+// Create an output MPE LUT from a given profile. Version mismatches are handled here
 cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent)
 {
     cmsTagTypeSignature OriginalType;
@@ -1056,3 +1056,13 @@ cmsUInt32Number  CMSEXPORT cmsGetProfileInfoASCII(cmsHPROFILE hProfile, cmsInfoT
 
     return cmsMLUgetASCII(mlu, LanguageCode, CountryCode, Buffer, BufferSize);
 }
+
+cmsUInt32Number  CMSEXPORT cmsGetProfileInfoUTF8(cmsHPROFILE hProfile, cmsInfoType Info,
+                                                          const char LanguageCode[3], const char CountryCode[3],
+                                                          char* Buffer, cmsUInt32Number BufferSize)
+{
+    const cmsMLU* mlu = GetInfo(hProfile, Info);
+    if (mlu == NULL) return 0;
+
+    return cmsMLUgetUTF8(mlu, LanguageCode, CountryCode, Buffer, BufferSize);
+}
diff --git a/src/java.desktop/share/native/liblcms/cmslut.c b/src/java.desktop/share/native/liblcms/cmslut.c
index 24114632ad0..b544c948625 100644
--- a/src/java.desktop/share/native/liblcms/cmslut.c
+++ b/src/java.desktop/share/native/liblcms/cmslut.c
@@ -504,6 +504,9 @@ cmsUInt32Number CubeSize(const cmsUInt32Number Dims[], cmsUInt32Number b)
         if (rv > UINT_MAX / dim) return 0;
     }
 
+    // Again, prevent overflow
+    if (rv > UINT_MAX / 15) return 0;
+
     return rv;
 }
 
@@ -843,7 +846,13 @@ cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler
     cmsUInt32Number nInputs, nOutputs;
     cmsUInt32Number* nSamples;
     cmsFloat32Number In[MAX_INPUT_DIMENSIONS+1], Out[MAX_STAGE_CHANNELS];
-    _cmsStageCLutData* clut = (_cmsStageCLutData*) mpe->Data;
+    _cmsStageCLutData* clut;
+
+    if (mpe == NULL) return FALSE;
+
+    clut = (_cmsStageCLutData*)mpe->Data;
+
+    if (clut == NULL) return FALSE;
 
     nSamples = clut->Params ->nSamples;
     nInputs  = clut->Params ->nInputs;
diff --git a/src/java.desktop/share/native/liblcms/cmsnamed.c b/src/java.desktop/share/native/liblcms/cmsnamed.c
index 04280180230..d3cd97d4aea 100644
--- a/src/java.desktop/share/native/liblcms/cmsnamed.c
+++ b/src/java.desktop/share/native/liblcms/cmsnamed.c
@@ -229,17 +229,145 @@ void strFrom16(char str[3], cmsUInt16Number n)
     str[0] = (char)(n >> 8);
     str[1] = (char)n;
     str[2] = (char)0;
+}
+
+
+// Convert from UTF8 to wchar, returns len.
+static
+cmsUInt32Number decodeUTF8(wchar_t* out, const char* in)
+{
+    cmsUInt32Number codepoint = 0;
+    cmsUInt32Number size = 0;
+
+    while (*in)
+    {
+        cmsUInt8Number ch = (cmsUInt8Number) *in;
+
+        if (ch <= 0x7f)
+        {
+            codepoint = ch;
+        }
+        else if (ch <= 0xbf)
+        {
+            codepoint = (codepoint << 6) | (ch & 0x3f);
+        }
+        else if (ch <= 0xdf)
+        {
+            codepoint = ch & 0x1f;
+        }
+        else if (ch <= 0xef)
+        {
+            codepoint = ch & 0x0f;
+        }
+        else
+        {
+            codepoint = ch & 0x07;
+        }
+
+        in++;
 
+        if (((*in & 0xc0) != 0x80) && (codepoint <= 0x10ffff))
+        {
+            if (sizeof(wchar_t) > 2)
+            {
+                if (out) *out++ = (wchar_t) codepoint;
+                size++;
+            }
+            else
+                if (codepoint > 0xffff)
+                {
+                    if (out)
+                    {
+                        *out++ = (wchar_t)(0xd800 + (codepoint >> 10));
+                        *out++ = (wchar_t)(0xdc00 + (codepoint & 0x03ff));
+                        size += 2;
+                    }
+                }
+                else
+                    if (codepoint < 0xd800 || codepoint >= 0xe000)
+                    {
+                        if (out) *out++ = (wchar_t) codepoint;
+                        size++;
+                    }
+        }
+    }
+
+    return size;
+}
+
+// Convert from wchar_t to UTF8
+static
+cmsUInt32Number encodeUTF8(char* out, const wchar_t* in, cmsUInt32Number max_wchars, cmsUInt32Number max_chars)
+{
+    cmsUInt32Number codepoint = 0;
+    cmsUInt32Number size = 0;
+    cmsUInt32Number len_w = 0;
+
+    while (*in && len_w < max_wchars)
+    {
+        if (*in >= 0xd800 && *in <= 0xdbff)
+            codepoint = ((*in - 0xd800) << 10) + 0x10000;
+        else
+        {
+            if (*in >= 0xdc00 && *in <= 0xdfff)
+                codepoint |= *in - 0xdc00;
+            else
+                codepoint = *in;
+
+            if (codepoint <= 0x7f)
+            {
+                if (out && (size + 1 < max_chars)) *out++ = (char)codepoint;
+                size++;
+            }
+
+            else if (codepoint <= 0x7ff)
+            {
+                if (out && (max_chars > 0) && (size + 2 < max_chars))
+                {
+                    *out++ = (char)(cmsUInt32Number)(0xc0 | ((codepoint >> 6) & 0x1f));
+                    *out++ = (char)(cmsUInt32Number)(0x80 | (codepoint & 0x3f));
+                }
+                size += 2;
+            }
+            else if (codepoint <= 0xffff)
+            {
+                if (out && (max_chars > 0) && (size + 3 < max_chars))
+                {
+                    *out++ = (char)(cmsUInt32Number)(0xe0 | ((codepoint >> 12) & 0x0f));
+                    *out++ = (char)(cmsUInt32Number)(0x80 | ((codepoint >> 6) & 0x3f));
+                    *out++ = (char)(cmsUInt32Number)(0x80 | (codepoint & 0x3f));
+                }
+                size += 3;
+            }
+            else
+            {
+                if (out && (max_chars > 0) && (size + 4 < max_chars))
+                {
+                    *out++ = (char)(cmsUInt32Number)(0xf0 | ((codepoint >> 18) & 0x07));
+                    *out++ = (char)(cmsUInt32Number)(0x80 | ((codepoint >> 12) & 0x3f));
+                    *out++ = (char)(cmsUInt32Number)(0x80 | ((codepoint >> 6) & 0x3f));
+                    *out++ = (char)(cmsUInt32Number)(0x80 | (codepoint & 0x3f));
+                }
+                size += 4;
+            }
+
+            codepoint = 0;
+        }
+
+        in++; len_w++;
+    }
+
+    return size;
 }
 
 // Add an ASCII entry. Do not add any \0 termination (ICC1v43_2010-12.pdf page 61)
 // In the case the user explicitly sets an empty string, we force a \0
 cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString)
 {
-    cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString);
+    cmsUInt32Number i, len = (cmsUInt32Number)strlen(ASCIIString);
     wchar_t* WStr;
     cmsBool  rc;
-    cmsUInt16Number Lang  = strTo16(LanguageCode);
+    cmsUInt16Number Lang = strTo16(LanguageCode);
     cmsUInt16Number Cntry = strTo16(CountryCode);
 
     if (mlu == NULL) return FALSE;
@@ -247,22 +375,56 @@ cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const
     // len == 0 would prevent operation, so we set a empty string pointing to zero
     if (len == 0)
     {
-        len = 1;
+        wchar_t empty = 0;
+        return AddMLUBlock(mlu, sizeof(wchar_t), &empty, Lang, Cntry);
     }
 
-    WStr = (wchar_t*) _cmsCalloc(mlu ->ContextID, len,  sizeof(wchar_t));
+    WStr = (wchar_t*)_cmsCalloc(mlu->ContextID, len, sizeof(wchar_t));
     if (WStr == NULL) return FALSE;
 
-    for (i=0; i < len; i++)
-        WStr[i] = (wchar_t) ASCIIString[i];
+    for (i = 0; i < len; i++)
+        WStr[i] = (wchar_t)ASCIIString[i];
 
-    rc = AddMLUBlock(mlu, len  * sizeof(wchar_t), WStr, Lang, Cntry);
+    rc = AddMLUBlock(mlu, len * sizeof(wchar_t), WStr, Lang, Cntry);
 
-    _cmsFree(mlu ->ContextID, WStr);
+    _cmsFree(mlu->ContextID, WStr);
     return rc;
 
 }
 
+// Add an UTF8 entry. Do not add any \0 termination (ICC1v43_2010-12.pdf page 61)
+// In the case the user explicitly sets an empty string, we force a \0
+cmsBool CMSEXPORT cmsMLUsetUTF8(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* UTF8String)
+{
+    cmsUInt32Number UTF8len;
+    wchar_t* WStr;
+    cmsBool  rc;
+    cmsUInt16Number Lang  = strTo16(LanguageCode);
+    cmsUInt16Number Cntry = strTo16(CountryCode);
+
+    if (mlu == NULL) return FALSE;
+
+    if (*UTF8String == '\0')
+    {
+        wchar_t empty = 0;
+        return AddMLUBlock(mlu, sizeof(wchar_t), &empty, Lang, Cntry);
+    }
+
+    // Len excluding terminator 0
+    UTF8len = decodeUTF8(NULL, UTF8String);
+
+    // Get space for dest
+    WStr = (wchar_t*) _cmsCalloc(mlu ->ContextID, UTF8len,  sizeof(wchar_t));
+    if (WStr == NULL) return FALSE;
+
+    decodeUTF8(WStr, UTF8String);
+
+    rc = AddMLUBlock(mlu, UTF8len  * sizeof(wchar_t), WStr, Lang, Cntry);
+
+    _cmsFree(mlu ->ContextID, WStr);
+    return rc;
+}
+
 // We don't need any wcs support library
 static
 cmsUInt32Number mywcslen(const wchar_t *s)
@@ -401,7 +563,7 @@ const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu,
 
     if (v->StrW + v->Len > mlu->PoolSize) return NULL;
 
-    return(wchar_t*) ((cmsUInt8Number*) mlu ->MemPool + v ->StrW);
+    return (wchar_t*) ((cmsUInt8Number*) mlu ->MemPool + v ->StrW);
 }
 
 
@@ -439,10 +601,12 @@ cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
     // Precess each character
     for (i=0; i < ASCIIlen; i++) {
 
-        if (Wide[i] == 0)
-            Buffer[i] = 0;
+        wchar_t wc = Wide[i];
+
+        if (wc < 0xff)
+            Buffer[i] = (char)wc;
         else
-            Buffer[i] = (char) Wide[i];
+            Buffer[i] = '?';
     }
 
     // We put a termination "\0"
@@ -450,6 +614,46 @@ cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
     return ASCIIlen + 1;
 }
 
+
+// Obtain a UTF8 representation of the wide string. Setting buffer to NULL returns the len
+cmsUInt32Number CMSEXPORT cmsMLUgetUTF8(const cmsMLU* mlu,
+                                       const char LanguageCode[3], const char CountryCode[3],
+                                       char* Buffer, cmsUInt32Number BufferSize)
+{
+    const wchar_t *Wide;
+    cmsUInt32Number  StrLen = 0;
+    cmsUInt32Number UTF8len;
+
+    cmsUInt16Number Lang  = strTo16(LanguageCode);
+    cmsUInt16Number Cntry = strTo16(CountryCode);
+
+    // Sanitize
+    if (mlu == NULL) return 0;
+
+    // Get WideChar
+    Wide = _cmsMLUgetWide(mlu, &StrLen, Lang, Cntry, NULL, NULL);
+    if (Wide == NULL) return 0;
+
+    UTF8len = encodeUTF8(NULL, Wide, StrLen / sizeof(wchar_t), BufferSize);
+
+    // Maybe we want only to know the len?
+    if (Buffer == NULL) return UTF8len + 1; // Note the zero at the end
+
+    // No buffer size means no data
+    if (BufferSize <= 0) return 0;
+
+    // Some clipping may be required
+    if (BufferSize < UTF8len + 1)
+        UTF8len = BufferSize - 1;
+
+    // Process it
+    encodeUTF8(Buffer, Wide, StrLen / sizeof(wchar_t), BufferSize);
+
+    // We put a termination "\0"
+    Buffer[UTF8len] = 0;
+    return UTF8len + 1;
+}
+
 // Obtain a wide representation of the MLU, on depending on current locale settings
 cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu,
                                       const char LanguageCode[3], const char CountryCode[3],
@@ -470,12 +674,12 @@ cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu,
     // Maybe we want only to know the len?
     if (Buffer == NULL) return StrLen + sizeof(wchar_t);
 
-  // No buffer size means no data
-    if (BufferSize <= 0) return 0;
+    // Invalid buffer size means no data
+    if (BufferSize < sizeof(wchar_t)) return 0;
 
     // Some clipping may be required
     if (BufferSize < StrLen + sizeof(wchar_t))
-        StrLen = BufferSize - + sizeof(wchar_t);
+        StrLen = BufferSize - sizeof(wchar_t);
 
     memmove(Buffer, Wide, StrLen);
     Buffer[StrLen / sizeof(wchar_t)] = 0;
@@ -843,13 +1047,19 @@ void CMSEXPORT cmsFreeProfileSequenceDescription(cmsSEQ* pseq)
 {
     cmsUInt32Number i;
 
-    for (i=0; i < pseq ->n; i++) {
-        if (pseq ->seq[i].Manufacturer != NULL) cmsMLUfree(pseq ->seq[i].Manufacturer);
-        if (pseq ->seq[i].Model != NULL) cmsMLUfree(pseq ->seq[i].Model);
-        if (pseq ->seq[i].Description != NULL) cmsMLUfree(pseq ->seq[i].Description);
+    if (pseq == NULL)
+        return;
+
+    if (pseq ->seq != NULL) {
+        for (i=0; i < pseq ->n; i++) {
+            if (pseq ->seq[i].Manufacturer != NULL) cmsMLUfree(pseq ->seq[i].Manufacturer);
+            if (pseq ->seq[i].Model != NULL) cmsMLUfree(pseq ->seq[i].Model);
+            if (pseq ->seq[i].Description != NULL) cmsMLUfree(pseq ->seq[i].Description);
+        }
+
+        _cmsFree(pseq ->ContextID, pseq ->seq);
     }
 
-    if (pseq ->seq != NULL) _cmsFree(pseq ->ContextID, pseq ->seq);
     _cmsFree(pseq -> ContextID, pseq);
 }
 
diff --git a/src/java.desktop/share/native/liblcms/cmsopt.c b/src/java.desktop/share/native/liblcms/cmsopt.c
index 3e81ae1df1b..421a4f4a701 100644
--- a/src/java.desktop/share/native/liblcms/cmsopt.c
+++ b/src/java.desktop/share/native/liblcms/cmsopt.c
@@ -212,6 +212,7 @@ cmsBool  isFloatMatrixIdentity(const cmsMAT3* a)
 
        return TRUE;
 }
+
 // if two adjacent matrices are found, multiply them.
 static
 cmsBool _MultiplyMatrix(cmsPipeline* Lut)
@@ -1142,14 +1143,17 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
 
         // Store result in curve
         for (t=0; t < OriginalLut ->InputChannels; t++)
-            Trans[t] ->Table16[i] = _cmsQuickSaturateWord(Out[t] * 65535.0);
+        {
+            if (Trans[t]->Table16 != NULL)
+                Trans[t] ->Table16[i] = _cmsQuickSaturateWord(Out[t] * 65535.0);
+        }
     }
 
     // Slope-limit the obtained curves
     for (t = 0; t < OriginalLut ->InputChannels; t++)
         SlopeLimiting(Trans[t]);
 
-    // Check for validity
+    // Check for validity. lIsLinear is here for debug purposes
     lIsSuitable = TRUE;
     lIsLinear   = TRUE;
     for (t=0; (lIsSuitable && (t < OriginalLut ->InputChannels)); t++) {
@@ -1753,6 +1757,8 @@ cmsBool OptimizeMatrixShaper(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
 
                      _cmsStageMatrixData* Data = (_cmsStageMatrixData*)cmsStageData(Matrix1);
 
+                     if (Matrix1->InputChannels != 3 || Matrix1->OutputChannels != 3) return FALSE;
+
                      // Copy the matrix to our result
                      memcpy(&res, Data->Double, sizeof(res));
 
@@ -1797,7 +1803,7 @@ cmsBool OptimizeMatrixShaper(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
         _cmsStageToneCurvesData* mpeC2 = (_cmsStageToneCurvesData*) cmsStageData(Curve2);
 
         // In this particular optimization, cache does not help as it takes more time to deal with
-        // the cache that with the pixel handling
+        // the cache than with the pixel handling
         *dwFlags |= cmsFLAGS_NOCACHE;
 
         // Setup the optimizarion routines
@@ -1954,7 +1960,7 @@ cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,
     for (mpe = cmsPipelineGetPtrToFirstStage(*PtrLut);
         mpe != NULL;
         mpe = cmsStageNext(mpe)) {
-        if (cmsStageType(mpe) == cmsSigNamedColorElemType) return FALSE;
+            if (cmsStageType(mpe) == cmsSigNamedColorElemType) return FALSE;
     }
 
     // Try to get rid of identities and trivial conversions.
diff --git a/src/java.desktop/share/native/liblcms/cmspack.c b/src/java.desktop/share/native/liblcms/cmspack.c
index da5fc6019d3..fc875995a80 100644
--- a/src/java.desktop/share/native/liblcms/cmspack.c
+++ b/src/java.desktop/share/native/liblcms/cmspack.c
@@ -2980,6 +2980,108 @@ cmsUInt8Number* PackFloatFrom16(CMSREGISTER _cmsTRANSFORM* info,
 
 // --------------------------------------------------------------------------------------------------------
 
+static
+cmsUInt8Number* PackBytesFromFloat(_cmsTRANSFORM* info,
+                                    cmsFloat32Number wOut[],
+                                    cmsUInt8Number* output,
+                                    cmsUInt32Number Stride)
+{
+    cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
+    cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
+    cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
+    cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
+    cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
+    cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
+    cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
+    cmsUInt8Number* swap1 = (cmsUInt8Number*)output;
+    cmsFloat64Number v = 0;
+    cmsUInt8Number vv = 0;
+    cmsUInt32Number i, start = 0;
+
+    if (ExtraFirst)
+        start = Extra;
+
+    for (i = 0; i < nChan; i++) {
+
+        cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
+
+        v = wOut[index] * 65535.0;
+
+        if (Reverse)
+            v = 65535.0 - v;
+
+        vv =  FROM_16_TO_8(_cmsQuickSaturateWord(v));
+
+        if (Planar)
+            ((cmsUInt8Number*)output)[(i + start) * Stride] = vv;
+        else
+            ((cmsUInt8Number*)output)[i + start] = vv;
+    }
+
+
+    if (Extra == 0 && SwapFirst) {
+
+        memmove(swap1 + 1, swap1, (nChan - 1) * sizeof(cmsUInt8Number));
+        *swap1 = vv;
+    }
+
+    if (T_PLANAR(info->OutputFormat))
+        return output + sizeof(cmsUInt8Number);
+    else
+        return output + (nChan + Extra) * sizeof(cmsUInt8Number);
+}
+
+static
+cmsUInt8Number* PackWordsFromFloat(_cmsTRANSFORM* info,
+                                    cmsFloat32Number wOut[],
+                                    cmsUInt8Number* output,
+                                    cmsUInt32Number Stride)
+{
+    cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
+    cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
+    cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
+    cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
+    cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
+    cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
+    cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
+    cmsUInt16Number* swap1 = (cmsUInt16Number*)output;
+    cmsFloat64Number v = 0;
+    cmsUInt16Number vv = 0;
+    cmsUInt32Number i, start = 0;
+
+    if (ExtraFirst)
+        start = Extra;
+
+    for (i = 0; i < nChan; i++) {
+
+        cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
+
+        v = wOut[index] * 65535.0;
+
+        if (Reverse)
+            v = 65535.0 - v;
+
+        vv = _cmsQuickSaturateWord(v);
+
+        if (Planar)
+            ((cmsUInt16Number*)output)[(i + start) * Stride] = vv;
+        else
+            ((cmsUInt16Number*)output)[i + start] = vv;
+    }
+
+    if (Extra == 0 && SwapFirst) {
+
+        memmove(swap1 + 1, swap1, (nChan - 1) * sizeof(cmsUInt16Number));
+        *swap1 = vv;
+    }
+
+    if (T_PLANAR(info->OutputFormat))
+        return output + sizeof(cmsUInt16Number);
+    else
+        return output + (nChan + Extra) * sizeof(cmsUInt16Number);
+}
+
+
 static
 cmsUInt8Number* PackFloatsFromFloat(_cmsTRANSFORM* info,
                                     cmsFloat32Number wOut[],
@@ -3143,6 +3245,77 @@ cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info,
 }
 
 
+static
+cmsUInt8Number* PackEncodedBytesLabV2FromFloat(_cmsTRANSFORM* Info,
+                                           cmsFloat32Number wOut[],
+                                           cmsUInt8Number* output,
+                                           cmsUInt32Number Stride)
+{
+    cmsCIELab Lab;
+    cmsUInt16Number wlab[3];
+
+    Lab.L = (cmsFloat64Number)(wOut[0] * 100.0);
+    Lab.a = (cmsFloat64Number)(wOut[1] * 255.0 - 128.0);
+    Lab.b = (cmsFloat64Number)(wOut[2] * 255.0 - 128.0);
+
+    cmsFloat2LabEncoded(wlab, &Lab);
+
+    if (T_PLANAR(Info -> OutputFormat)) {
+
+        Stride /= PixelSize(Info->OutputFormat);
+
+        output[0]        = wlab[0] >> 8;
+        output[Stride]   = wlab[1] >> 8;
+        output[Stride*2] = wlab[2] >> 8;
+
+        return output + 1;
+    }
+    else {
+
+        output[0] = wlab[0] >> 8;
+        output[1] = wlab[1] >> 8;
+        output[2] = wlab[2] >> 8;
+
+        return output + (3 + T_EXTRA(Info ->OutputFormat));
+    }
+}
+
+static
+cmsUInt8Number* PackEncodedWordsLabV2FromFloat(_cmsTRANSFORM* Info,
+                                           cmsFloat32Number wOut[],
+                                           cmsUInt8Number* output,
+                                           cmsUInt32Number Stride)
+{
+    cmsCIELab Lab;
+    cmsUInt16Number wlab[3];
+
+    Lab.L = (cmsFloat64Number)(wOut[0] * 100.0);
+    Lab.a = (cmsFloat64Number)(wOut[1] * 255.0 - 128.0);
+    Lab.b = (cmsFloat64Number)(wOut[2] * 255.0 - 128.0);
+
+    cmsFloat2LabEncodedV2(wlab, &Lab);
+
+    if (T_PLANAR(Info -> OutputFormat)) {
+
+        Stride /= PixelSize(Info->OutputFormat);
+
+        ((cmsUInt16Number*) output)[0]        = wlab[0];
+        ((cmsUInt16Number*) output)[Stride]   = wlab[1];
+        ((cmsUInt16Number*) output)[Stride*2] = wlab[2];
+
+        return output + sizeof(cmsUInt16Number);
+    }
+    else {
+
+         ((cmsUInt16Number*) output)[0] = wlab[0];
+         ((cmsUInt16Number*) output)[1] = wlab[1];
+         ((cmsUInt16Number*) output)[2] = wlab[2];
+
+        return output + (3 + T_EXTRA(Info ->OutputFormat)) * sizeof(cmsUInt16Number);
+    }
+}
+
+
 // From 0..1 range to 0..MAX_ENCODEABLE_XYZ
 static
 cmsUInt8Number* PackXYZFloatFromFloat(_cmsTRANSFORM* Info,
@@ -3676,10 +3849,20 @@ static const cmsFormattersFloat OutputFormattersFloat[] = {
     {     TYPE_Lab_DBL,                                                ANYPLANAR|ANYEXTRA,   PackLabDoubleFromFloat},
     {     TYPE_XYZ_DBL,                                                ANYPLANAR|ANYEXTRA,   PackXYZDoubleFromFloat},
 
+    {     TYPE_LabV2_8,                                                ANYPLANAR|ANYEXTRA,   PackEncodedBytesLabV2FromFloat},
+    {     TYPE_LabV2_16,                                               ANYPLANAR|ANYEXTRA,   PackEncodedWordsLabV2FromFloat},
+
     {     FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|
                              ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE,   PackFloatsFromFloat },
     {     FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|
                              ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE,   PackDoublesFromFloat },
+
+    {     BYTES_SH(2), ANYPLANAR|
+                             ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE,   PackWordsFromFloat },
+
+    {     BYTES_SH(1), ANYPLANAR|
+                             ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE,   PackBytesFromFloat },
+
 #ifndef CMS_NO_HALF_SUPPORT
     {     FLOAT_SH(1)|BYTES_SH(2),
                              ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE,   PackHalfFromFloat },
@@ -3890,7 +4073,7 @@ cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsU
     cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile);
 
     cmsUInt32Number ColorSpaceBits = (cmsUInt32Number) _cmsLCMScolorSpace(ColorSpace);
-    cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace);
+    cmsInt32Number  nOutputChans = cmsChannelsOfColorSpace(ColorSpace);
     cmsUInt32Number Float = lIsFloat ? 1U : 0;
 
     // Unsupported color space?
diff --git a/src/java.desktop/share/native/liblcms/cmsplugin.c b/src/java.desktop/share/native/liblcms/cmsplugin.c
index c2808bb9278..f84e0172c81 100644
--- a/src/java.desktop/share/native/liblcms/cmsplugin.c
+++ b/src/java.desktop/share/native/liblcms/cmsplugin.c
@@ -393,12 +393,7 @@ cmsBool CMSEXPORT  _cmsWriteXYZNumber(cmsIOHANDLER* io, const cmsCIEXYZ* XYZ)
 // from Fixed point 8.8 to double
 cmsFloat64Number CMSEXPORT _cms8Fixed8toDouble(cmsUInt16Number fixed8)
 {
-       cmsUInt8Number  msb, lsb;
-
-       lsb = (cmsUInt8Number) (fixed8 & 0xff);
-       msb = (cmsUInt8Number) (((cmsUInt16Number) fixed8 >> 8) & 0xff);
-
-       return (cmsFloat64Number) ((cmsFloat64Number) msb + ((cmsFloat64Number) lsb / 256.0));
+    return fixed8 / 256.0;
 }
 
 cmsUInt16Number CMSEXPORT _cmsDoubleTo8Fixed8(cmsFloat64Number val)
@@ -410,19 +405,7 @@ cmsUInt16Number CMSEXPORT _cmsDoubleTo8Fixed8(cmsFloat64Number val)
 // from Fixed point 15.16 to double
 cmsFloat64Number CMSEXPORT _cms15Fixed16toDouble(cmsS15Fixed16Number fix32)
 {
-    cmsFloat64Number floater, sign, mid;
-    int Whole, FracPart;
-
-    sign  = (fix32 < 0 ? -1 : 1);
-    fix32 = abs(fix32);
-
-    Whole     = (cmsUInt16Number)(fix32 >> 16) & 0xffff;
-    FracPart  = (cmsUInt16Number)(fix32 & 0xffff);
-
-    mid     = (cmsFloat64Number) FracPart / 65536.0;
-    floater = (cmsFloat64Number) Whole + mid;
-
-    return sign * floater;
+    return fix32 / 65536.0;
 }
 
 // from double to Fixed point 15.16
diff --git a/src/java.desktop/share/native/liblcms/cmsps2.c b/src/java.desktop/share/native/liblcms/cmsps2.c
index 537f6854067..9a2ab464f31 100644
--- a/src/java.desktop/share/native/liblcms/cmsps2.c
+++ b/src/java.desktop/share/native/liblcms/cmsps2.c
@@ -460,48 +460,46 @@ void EmitLab2XYZ(cmsIOHANDLER* m)
     _cmsIOPrintf(m, "]\n");
 }
 
-static
-void EmitSafeGuardBegin(cmsIOHANDLER* m, const char* name)
-{
-    _cmsIOPrintf(m, "%%LCMS2: Save previous definition of %s on the operand stack\n", name);
-    _cmsIOPrintf(m, "currentdict /%s known { /%s load } { null } ifelse\n", name, name);
-}
 
-static
-void EmitSafeGuardEnd(cmsIOHANDLER* m, const char* name, int depth)
-{
-    _cmsIOPrintf(m, "%%LCMS2: Restore previous definition of %s\n", name);
-    if (depth > 1) {
-        // cycle topmost items on the stack to bring the previous definition to the front
-        _cmsIOPrintf(m, "%d -1 roll ", depth);
-    }
-    _cmsIOPrintf(m, "dup null eq { pop currentdict /%s undef } { /%s exch def } ifelse\n", name, name);
-}
 
 // Outputs a table of words. It does use 16 bits
 
 static
-void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table, const char* name)
+void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table)
 {
     cmsUInt32Number i;
     cmsFloat64Number gamma;
 
-    if (Table == NULL) return; // Error
+    /**
+    * On error, empty tables or lienar assume gamma 1.0
+    */
+    if (Table == NULL ||
+        Table->nEntries <= 0 ||
+        cmsIsToneCurveLinear(Table)) {
 
-    if (Table ->nEntries <= 0) return;  // Empty table
+        _cmsIOPrintf(m, "{ 1 } bind ");
+        return;
+    }
 
-    // Suppress whole if identity
-    if (cmsIsToneCurveLinear(Table)) return;
 
     // Check if is really an exponential. If so, emit "exp"
     gamma = cmsEstimateGamma(Table, 0.001);
      if (gamma > 0) {
-            _cmsIOPrintf(m, "/%s { %g exp } bind def\n", name, gamma);
+            _cmsIOPrintf(m, "{ %g exp } bind ", gamma);
             return;
      }
 
-    EmitSafeGuardBegin(m, "lcms2gammatable");
-    _cmsIOPrintf(m, "/lcms2gammatable [");
+    _cmsIOPrintf(m, "{ ");
+
+    // Bounds check
+    EmitRangeCheck(m);
+
+    // Emit intepolation code
+
+    // PostScript code                      Stack
+    // ===============                      ========================
+                                            // v
+    _cmsIOPrintf(m, " [");
 
     for (i=0; i < Table->nEntries; i++) {
     if (i % 10 == 0)
@@ -509,20 +507,8 @@ void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table, const char* name)
         _cmsIOPrintf(m, "%d ", Table->Table16[i]);
     }
 
-    _cmsIOPrintf(m, "] def\n");
+    _cmsIOPrintf(m, "] ");                        // v tab
 
-
-    // Emit interpolation code
-
-    // PostScript code                            Stack
-    // ===============                            ========================
-                                                  // v
-    _cmsIOPrintf(m, "/%s {\n  ", name);
-
-    // Bounds check
-    EmitRangeCheck(m);
-
-    _cmsIOPrintf(m, "\n  //lcms2gammatable ");    // v tab
     _cmsIOPrintf(m, "dup ");                      // v tab tab
     _cmsIOPrintf(m, "length 1 sub ");             // v tab dom
     _cmsIOPrintf(m, "3 -1 roll ");                // tab dom v
@@ -549,9 +535,7 @@ void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table, const char* name)
     _cmsIOPrintf(m, "add ");                      // y
     _cmsIOPrintf(m, "65535 div\n");               // result
 
-    _cmsIOPrintf(m, "} bind def\n");
-
-    EmitSafeGuardEnd(m, "lcms2gammatable", 1);
+    _cmsIOPrintf(m, " } bind ");
 }
 
 
@@ -568,10 +552,10 @@ cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, cmsUInt32Numb
 // Does write a set of gamma curves
 
 static
-void EmitNGamma(cmsIOHANDLER* m, cmsUInt32Number n, cmsToneCurve* g[], const char* nameprefix)
+void EmitNGamma(cmsIOHANDLER* m, cmsUInt32Number n, cmsToneCurve* g[])
 {
     cmsUInt32Number i;
-    static char buffer[2048];
+
 
     for( i=0; i < n; i++ )
     {
@@ -579,12 +563,10 @@ void EmitNGamma(cmsIOHANDLER* m, cmsUInt32Number n, cmsToneCurve* g[], const cha
 
         if (i > 0 && GammaTableEquals(g[i-1]->Table16, g[i]->Table16, g[i-1]->nEntries, g[i]->nEntries)) {
 
-            _cmsIOPrintf(m, "/%s%d /%s%d load def\n", nameprefix, i, nameprefix, i-1);
+            _cmsIOPrintf(m, "dup ");
         }
         else {
-            snprintf(buffer, sizeof(buffer), "%s%d", nameprefix, (int) i);
-        buffer[sizeof(buffer)-1] = '\0';
-            Emit1Gamma(m, g[i], buffer);
+            Emit1Gamma(m, g[i]);
         }
     }
 
@@ -708,18 +690,21 @@ void WriteCLUT(cmsIOHANDLER* m, cmsStage* mpe, const char* PreMaj,
     sc.FixWhite = FixWhite;
     sc.ColorSpace = ColorSpace;
 
-    _cmsIOPrintf(m, "[");
+    if (sc.Pipeline != NULL && sc.Pipeline->Params != NULL) {
 
-    for (i=0; i < sc.Pipeline->Params->nInputs; i++)
-        _cmsIOPrintf(m, " %d ", sc.Pipeline->Params->nSamples[i]);
+        _cmsIOPrintf(m, "[");
 
-    _cmsIOPrintf(m, " [\n");
+        for (i = 0; i < sc.Pipeline->Params->nInputs; i++)
+            _cmsIOPrintf(m, " %d ", sc.Pipeline->Params->nSamples[i]);
 
-    cmsStageSampleCLut16bit(mpe, OutputValueSampler, (void*) &sc, SAMPLER_INSPECT);
+        _cmsIOPrintf(m, " [\n");
 
-    _cmsIOPrintf(m, PostMin);
-    _cmsIOPrintf(m, PostMaj);
-    _cmsIOPrintf(m, "] ");
+        cmsStageSampleCLut16bit(mpe, OutputValueSampler, (void*)&sc, SAMPLER_INSPECT);
+
+        _cmsIOPrintf(m, PostMin);
+        _cmsIOPrintf(m, PostMaj);
+        _cmsIOPrintf(m, "] ");
+    }
 
 }
 
@@ -733,11 +718,11 @@ int EmitCIEBasedA(cmsIOHANDLER* m, cmsToneCurve* Curve, cmsCIEXYZ* BlackPoint)
     _cmsIOPrintf(m, "[ /CIEBasedA\n");
     _cmsIOPrintf(m, "  <<\n");
 
-    EmitSafeGuardBegin(m, "lcms2gammaproc");
-    Emit1Gamma(m, Curve, "lcms2gammaproc");
+    _cmsIOPrintf(m, "/DecodeA ");
+
+    Emit1Gamma(m, Curve);
 
-    _cmsIOPrintf(m, "/DecodeA /lcms2gammaproc load\n");
-    EmitSafeGuardEnd(m, "lcms2gammaproc", 3);
+    _cmsIOPrintf(m, " \n");
 
     _cmsIOPrintf(m, "/MatrixA [ 0.9642 1.0000 0.8249 ]\n");
     _cmsIOPrintf(m, "/RangeLMN [ 0.0 0.9642 0.0 1.0000 0.0 0.8249 ]\n");
@@ -761,19 +746,11 @@ int EmitCIEBasedABC(cmsIOHANDLER* m, cmsFloat64Number* Matrix, cmsToneCurve** Cu
 
     _cmsIOPrintf(m, "[ /CIEBasedABC\n");
     _cmsIOPrintf(m, "<<\n");
+    _cmsIOPrintf(m, "/DecodeABC [ ");
+
+    EmitNGamma(m, 3, CurveSet);
 
-    EmitSafeGuardBegin(m, "lcms2gammaproc0");
-    EmitSafeGuardBegin(m, "lcms2gammaproc1");
-    EmitSafeGuardBegin(m, "lcms2gammaproc2");
-    EmitNGamma(m, 3, CurveSet, "lcms2gammaproc");
-    _cmsIOPrintf(m, "/DecodeABC [\n");
-    _cmsIOPrintf(m, "   /lcms2gammaproc0 load\n");
-    _cmsIOPrintf(m, "   /lcms2gammaproc1 load\n");
-    _cmsIOPrintf(m, "   /lcms2gammaproc2 load\n");
     _cmsIOPrintf(m, "]\n");
-    EmitSafeGuardEnd(m, "lcms2gammaproc2", 3);
-    EmitSafeGuardEnd(m, "lcms2gammaproc1", 3);
-    EmitSafeGuardEnd(m, "lcms2gammaproc0", 3);
 
     _cmsIOPrintf(m, "/MatrixABC [ " );
 
@@ -805,10 +782,8 @@ int EmitCIEBasedDEF(cmsIOHANDLER* m, cmsPipeline* Pipeline, cmsUInt32Number Inte
 {
     const char* PreMaj;
     const char* PostMaj;
-    const char* PreMin, * PostMin;
+    const char* PreMin, *PostMin;
     cmsStage* mpe;
-    int i, numchans;
-    static char buffer[2048];
 
     mpe = Pipeline->Elements;
 
@@ -837,34 +812,18 @@ int EmitCIEBasedDEF(cmsIOHANDLER* m, cmsPipeline* Pipeline, cmsUInt32Number Inte
 
     if (cmsStageType(mpe) == cmsSigCurveSetElemType) {
 
-        numchans = (int) cmsStageOutputChannels(mpe);
-        for (i = 0; i < numchans; ++i) {
-            snprintf(buffer, sizeof(buffer), "lcms2gammaproc%d", i);
-            buffer[sizeof(buffer) - 1] = '\0';
-            EmitSafeGuardBegin(m, buffer);
-        }
-        EmitNGamma(m, cmsStageOutputChannels(mpe), _cmsStageGetPtrToCurveSet(mpe), "lcms2gammaproc");
-        _cmsIOPrintf(m, "/DecodeDEF [\n");
-        for (i = 0; i < numchans; ++i) {
-            snprintf(buffer, sizeof(buffer), "  /lcms2gammaproc%d load\n", i);
-            buffer[sizeof(buffer) - 1] = '\0';
-            _cmsIOPrintf(m, buffer);
-        }
+        _cmsIOPrintf(m, "/DecodeDEF [ ");
+        EmitNGamma(m, cmsStageOutputChannels(mpe), _cmsStageGetPtrToCurveSet(mpe));
         _cmsIOPrintf(m, "]\n");
-        for (i = numchans - 1; i >= 0; --i) {
-            snprintf(buffer, sizeof(buffer), "lcms2gammaproc%d", i);
-            buffer[sizeof(buffer) - 1] = '\0';
-            EmitSafeGuardEnd(m, buffer, 3);
-        }
 
-        mpe = mpe->Next;
+        mpe = mpe ->Next;
     }
 
     if (cmsStageType(mpe) == cmsSigCLutElemType) {
 
-        _cmsIOPrintf(m, "/Table ");
-        WriteCLUT(m, mpe, PreMaj, PostMaj, PreMin, PostMin, FALSE, (cmsColorSpaceSignature)0);
-        _cmsIOPrintf(m, "]\n");
+            _cmsIOPrintf(m, "/Table ");
+            WriteCLUT(m, mpe, PreMaj, PostMaj, PreMin, PostMin, FALSE, (cmsColorSpaceSignature) 0);
+            _cmsIOPrintf(m, "]\n");
     }
 
     EmitLab2XYZ(m);
@@ -1024,9 +983,9 @@ int WriteInputMatrixShaper(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsStage* Matr
                 for (j = 0; j < 3; j++)
                     Mat.v[i].n[j] *= MAX_ENCODEABLE_XYZ;
 
-            rc = EmitCIEBasedABC(m, (cmsFloat64Number *)&Mat,
-                _cmsStageGetPtrToCurveSet(Shaper),
-                &BlackPointAdaptedToD50);
+            rc = EmitCIEBasedABC(m,  (cmsFloat64Number *) &Mat,
+                                _cmsStageGetPtrToCurveSet(Shaper),
+                                 &BlackPointAdaptedToD50);
         }
         else {
 
@@ -1053,10 +1012,15 @@ int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number
 
     hLab  = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
     xform = cmsCreateTransform(hNamedColor, TYPE_NAMED_COLOR_INDEX, hLab, TYPE_Lab_DBL, Intent, 0);
+    cmsCloseProfile(hLab);
+
     if (xform == NULL) return 0;
 
     NamedColorList = cmsGetNamedColorList(xform);
-    if (NamedColorList == NULL) return 0;
+    if (NamedColorList == NULL) {
+        cmsDeleteTransform(xform);
+        return 0;
+    }
 
     _cmsIOPrintf(m, "<<\n");
     _cmsIOPrintf(m, "(colorlistcomment) (%s)\n", "Named color CSA");
@@ -1065,7 +1029,6 @@ int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number
 
     nColors   = cmsNamedColorCount(NamedColorList);
 
-
     for (i=0; i < nColors; i++) {
 
         cmsUInt16Number In[1];
@@ -1080,12 +1043,9 @@ int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number
         _cmsIOPrintf(m, "  (%s) [ %.3f %.3f %.3f ]\n", ColorName, Lab.L, Lab.a, Lab.b);
     }
 
-
-
     _cmsIOPrintf(m, ">>\n");
 
     cmsDeleteTransform(xform);
-    cmsCloseProfile(hLab);
     return 1;
 }
 
@@ -1339,7 +1299,7 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent
     cmsUInt32Number InFrm = TYPE_Lab_16;
     cmsUInt32Number RelativeEncodingIntent;
     cmsColorSpaceSignature ColorSpace;
-
+    cmsStage* first;
 
     hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
     if (hLab == NULL) return 0;
@@ -1366,7 +1326,6 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent
     cmsCloseProfile(hLab);
 
     if (xform == NULL) {
-
         cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Cannot create transform Lab -> Profile in CRD creation");
         return 0;
     }
@@ -1374,10 +1333,12 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent
     // Get a copy of the internal devicelink
     v = (_cmsTRANSFORM*) xform;
     DeviceLink = cmsPipelineDup(v ->Lut);
-    if (DeviceLink == NULL) return 0;
-
+    if (DeviceLink == NULL) {
+        cmsDeleteTransform(xform);
+        return 0;
+    }
 
-    // We need a CLUT
+     // We need a CLUT
     dwFlags |= cmsFLAGS_FORCE_CLUT;
     _cmsOptimizePipeline(m->ContextID, &DeviceLink, RelativeEncodingIntent, &InFrm, &OutputFormat, &dwFlags);
 
@@ -1404,8 +1365,10 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent
 
     _cmsIOPrintf(m, "/RenderTable ");
 
-
-    WriteCLUT(m, cmsPipelineGetPtrToFirstStage(DeviceLink), "<", ">\n", "", "", lFixWhite, ColorSpace);
+    first = cmsPipelineGetPtrToFirstStage(DeviceLink);
+    if (first != NULL) {
+        WriteCLUT(m, first, "<", ">\n", "", "", lFixWhite, ColorSpace);
+    }
 
     _cmsIOPrintf(m, " %d {} bind ", nChannels);
 
@@ -1414,7 +1377,6 @@ int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent
 
     _cmsIOPrintf(m, "]\n");
 
-
     EmitIntent(m, Intent);
 
     _cmsIOPrintf(m, ">>\n");
@@ -1477,7 +1439,10 @@ int WriteNamedColorCRD(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number
 
 
     NamedColorList = cmsGetNamedColorList(xform);
-    if (NamedColorList == NULL) return 0;
+    if (NamedColorList == NULL) {
+        cmsDeleteTransform(xform);
+        return 0;
+    }
 
     _cmsIOPrintf(m, "<<\n");
     _cmsIOPrintf(m, "(colorlistcomment) (%s) \n", "Named profile");
diff --git a/src/java.desktop/share/native/liblcms/cmssamp.c b/src/java.desktop/share/native/liblcms/cmssamp.c
index 8a01f7ec685..74f5f4bff29 100644
--- a/src/java.desktop/share/native/liblcms/cmssamp.c
+++ b/src/java.desktop/share/native/liblcms/cmssamp.c
@@ -152,7 +152,7 @@ cmsBool  BlackPointAsDarkerColorant(cmsHPROFILE    hInput,
     // Convert black to Lab
     cmsDoTransform(xform, Black, &Lab, 1);
 
-    // Force it to be neutral, check for inconsistences
+    // Force it to be neutral, check for inconsistencies
     Lab.a = Lab.b = 0;
     if (Lab.L > 50 || Lab.L < 0) Lab.L = 0;
 
diff --git a/src/java.desktop/share/native/liblcms/cmstypes.c b/src/java.desktop/share/native/liblcms/cmstypes.c
index 7b07b6b9cf4..862f393497a 100644
--- a/src/java.desktop/share/native/liblcms/cmstypes.c
+++ b/src/java.desktop/share/native/liblcms/cmstypes.c
@@ -122,7 +122,7 @@ cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsMemoryClient
     return TRUE;
 }
 
-// Return handler for a given type or NULL if not found. Shared between normal types and MPE. It first tries the additons
+// Return handler for a given type or NULL if not found. Shared between normal types and MPE. It first tries the additions
 // made by plug-ins and then the built-in defaults.
 static
 cmsTagTypeHandler* GetHandler(cmsTagTypeSignature sig, _cmsTagTypeLinkedList* PluginLinkedList, _cmsTagTypeLinkedList* DefaultLinkedList)
@@ -954,6 +954,7 @@ static
 void *Type_Text_Description_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
 {
     char* Text = NULL;
+    wchar_t* UnicodeString = NULL;
     cmsMLU* mlu = NULL;
     cmsUInt32Number  AsciiCount;
     cmsUInt32Number  i, UnicodeCode, UnicodeCount;
@@ -973,7 +974,7 @@ void *Type_Text_Description_Read(struct _cms_typehandler_struct* self, cmsIOHAND
     if (SizeOfTag < AsciiCount) return NULL;
 
     // All seems Ok, allocate the container
-    mlu = cmsMLUalloc(self ->ContextID, 1);
+    mlu = cmsMLUalloc(self ->ContextID, 2);
     if (mlu == NULL) return NULL;
 
     // As many memory as size of tag
@@ -998,15 +999,30 @@ void *Type_Text_Description_Read(struct _cms_typehandler_struct* self, cmsIOHAND
     if (!_cmsReadUInt32Number(io, &UnicodeCount)) goto Done;
     SizeOfTag -= 2* sizeof(cmsUInt32Number);
 
-    if (SizeOfTag < UnicodeCount*sizeof(cmsUInt16Number)) goto Done;
+    if (UnicodeCount == 0 || SizeOfTag < UnicodeCount*sizeof(cmsUInt16Number)) goto Done;
+
+    UnicodeString = (wchar_t*)_cmsMallocZero(self->ContextID, (UnicodeCount + 1) * sizeof(wchar_t));
+    if (UnicodeString == NULL) goto Done;
+
+    if (!_cmsReadWCharArray(io, UnicodeCount, UnicodeString)) {
+        _cmsFree(self->ContextID, (void*)UnicodeString);
+        goto Done;
+    }
+
+    UnicodeString[UnicodeCount] = 0;
 
-    for (i=0; i < UnicodeCount; i++) {
-        if (!io ->Read(io, &Dummy, sizeof(cmsUInt16Number), 1)) goto Done;
+    if (!cmsMLUsetWide(mlu, cmsV2Unicode, cmsV2Unicode, UnicodeString)) {
+        _cmsFree(self->ContextID, (void*)UnicodeString);
+        goto Done;
     }
+
+    _cmsFree(self->ContextID, (void*)UnicodeString);
+    UnicodeString = NULL;
+
     SizeOfTag -= UnicodeCount*sizeof(cmsUInt16Number);
 
     // Skip ScriptCode code if present. Some buggy profiles does have less
-    // data that stricttly required. We need to skip it as this type may come
+    // data that strictly required. We need to skip it as this type may come
     // embedded in other types.
 
     if (SizeOfTag >= sizeof(cmsUInt16Number) + sizeof(cmsUInt8Number) + 67) {
@@ -1026,6 +1042,7 @@ void *Type_Text_Description_Read(struct _cms_typehandler_struct* self, cmsIOHAND
     return mlu;
 
 Error:
+    if (UnicodeString)  _cmsFree(self->ContextID, (void*)UnicodeString);
     if (Text) _cmsFree(self ->ContextID, (void*) Text);
     if (mlu) cmsMLUfree(mlu);
     return NULL;
@@ -1078,7 +1095,7 @@ cmsBool  Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
 
         // Get both representations.
         cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry,  Text, len * sizeof(char));
-        cmsMLUgetWide(mlu,  cmsNoLanguage, cmsNoCountry,  Wide, len * sizeof(wchar_t));
+        cmsMLUgetWide(mlu,  cmsV2Unicode,  cmsV2Unicode,  Wide, len * sizeof(wchar_t));
     }
 
     // Tell the real text len including the null terminator and padding
@@ -1577,8 +1594,6 @@ void *Type_MLU_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU
     if (SizeOfTag == 0)
     {
         Block = NULL;
-        NumOfWchar = 0;
-
     }
     else
     {
@@ -1940,7 +1955,7 @@ void *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms
 
 // We only allow a specific MPE structure: Matrix plus prelin, plus clut, plus post-lin.
 static
-cmsBool  Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
+cmsBool Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
 {
     cmsUInt32Number j, nTabSize, i;
     cmsUInt8Number  val;
@@ -1953,6 +1968,12 @@ cmsBool  Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
 
     // Disassemble the LUT into components.
     mpe = NewLUT -> Elements;
+
+    if (mpe == NULL) {  // Should never be empty. Corrupted?
+        cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "empty LUT8 is not supported");
+        return FALSE;
+    }
+
     if (mpe ->Type == cmsSigMatrixElemType) {
 
         if (mpe->InputChannels != 3 || mpe->OutputChannels != 3) return FALSE;
@@ -2694,8 +2715,8 @@ cmsBool WriteSetOfCurves(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
         // If this is a table-based curve, use curve type even on V4
         CurrentType = Type;
 
-        if ((Curves[i] ->nSegments == 0)||
-            ((Curves[i]->nSegments == 2) && (Curves[i] ->Segments[1].Type == 0)) )
+        if ((Curves[i] ->nSegments == 0) ||                                         // 16 bits tabulated
+            ((Curves[i]->nSegments == 3) && (Curves[i] ->Segments[1].Type == 0)) )  // Floating-point tabulated
             CurrentType = cmsSigCurveType;
         else
         if (Curves[i] ->Segments[0].Type < 0)
@@ -4459,8 +4480,8 @@ void *Type_MPEclut_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
     if (!_cmsReadUInt16Number(io, &InputChans)) return NULL;
     if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL;
 
-    if (InputChans == 0) goto Error;
-    if (OutputChans == 0) goto Error;
+    if (InputChans == 0 || InputChans >= cmsMAXCHANNELS) goto Error;
+    if (OutputChans == 0 || OutputChans >= cmsMAXCHANNELS) goto Error;
 
     if (io ->Read(io, Dimensions8, sizeof(cmsUInt8Number), 16) != 16)
         goto Error;
@@ -5250,11 +5271,13 @@ cmsBool WriteOneMLUC(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,  _c
     }
 
     Before = io ->Tell(io);
-    e ->Offsets[i] = Before - BaseOffset;
+    if (e->Offsets != NULL)
+        e ->Offsets[i] = Before - BaseOffset;
 
     if (!Type_MLU_Write(self, io, (void*) mlu, 1)) return FALSE;
 
-    e ->Sizes[i] = io ->Tell(io) - Before;
+    if (e->Sizes != NULL)
+        e ->Sizes[i] = io ->Tell(io) - Before;
     return TRUE;
 }
 
@@ -5499,6 +5522,216 @@ void Type_VideoSignal_Free(struct _cms_typehandler_struct* self, void* Ptr)
     _cmsFree(self->ContextID, Ptr);
 }
 
+
+// ********************************************************************************
+// Microsoft's MHC2 Type support
+// ********************************************************************************
+
+static
+void SetIdentity(cmsFloat64Number XYZ2XYZmatrix[3][4])
+{
+    XYZ2XYZmatrix[0][0] = 1.0; XYZ2XYZmatrix[0][1] = 0.0; XYZ2XYZmatrix[0][2] = 0.0; XYZ2XYZmatrix[0][3] = 0.0;
+    XYZ2XYZmatrix[1][0] = 0.0; XYZ2XYZmatrix[1][1] = 1.0; XYZ2XYZmatrix[1][2] = 0.0; XYZ2XYZmatrix[1][3] = 0.0;
+    XYZ2XYZmatrix[2][0] = 0.0; XYZ2XYZmatrix[2][1] = 0.0; XYZ2XYZmatrix[2][2] = 1.0; XYZ2XYZmatrix[2][3] = 0.0;
+}
+
+static
+cmsBool CloseEnough(cmsFloat64Number a, cmsFloat64Number b)
+{
+    return fabs(b - a) < (1.0 / 65535.0);
+}
+
+cmsBool IsIdentity(cmsFloat64Number XYZ2XYZmatrix[3][4])
+{
+    cmsFloat64Number Identity[3][4];
+    int i, j;
+
+    SetIdentity(Identity);
+
+    for (i = 0; i < 3; i++)
+        for (j = 0; j < 4; j++)
+            if (!CloseEnough(XYZ2XYZmatrix[i][j], Identity[i][j])) return FALSE;
+
+    return TRUE;
+}
+
+static
+void Type_MHC2_Free(struct _cms_typehandler_struct* self, void* Ptr)
+{
+    cmsMHC2Type* mhc2 = (cmsMHC2Type*)Ptr;
+
+    if (mhc2->RedCurve != NULL) _cmsFree(self->ContextID, mhc2->RedCurve);
+    if (mhc2->GreenCurve != NULL) _cmsFree(self->ContextID, mhc2->GreenCurve);
+    if (mhc2->BlueCurve != NULL) _cmsFree(self->ContextID, mhc2->BlueCurve);
+
+    _cmsFree(self->ContextID, Ptr);
+}
+
+void* Type_MHC2_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n)
+{
+    cmsMHC2Type* mhc2 = _cmsDupMem(self->ContextID, Ptr, sizeof(cmsMHC2Type));
+
+    mhc2->RedCurve = _cmsDupMem(self->ContextID,   mhc2->RedCurve, mhc2->CurveEntries*sizeof(cmsFloat64Number));
+    mhc2->GreenCurve = _cmsDupMem(self->ContextID, mhc2->GreenCurve, mhc2->CurveEntries * sizeof(cmsFloat64Number));
+    mhc2->BlueCurve = _cmsDupMem(self->ContextID,  mhc2->BlueCurve, mhc2->CurveEntries * sizeof(cmsFloat64Number));
+
+    if (mhc2->RedCurve == NULL ||
+        mhc2->GreenCurve == NULL ||
+        mhc2->BlueCurve == NULL) {
+
+        Type_MHC2_Free(self, mhc2);
+        return NULL;
+    }
+
+    return mhc2;
+
+    cmsUNUSED_PARAMETER(n);
+}
+
+
+static
+cmsBool WriteDoubles(cmsIOHANDLER* io, cmsUInt32Number n, cmsFloat64Number* Values)
+{
+    cmsUInt32Number i;
+
+    for (i = 0; i < n; i++) {
+
+        if (!_cmsWrite15Fixed16Number(io, *Values++)) return FALSE;
+    }
+
+    return TRUE;
+}
+
+static
+cmsBool Type_MHC2_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
+{
+    cmsMHC2Type* mhc2 = (cmsMHC2Type*)Ptr;
+    cmsUInt32Number BaseOffset = io->Tell(io) - sizeof(_cmsTagBase);
+    cmsUInt32Number TablesOffsetPos;
+    cmsUInt32Number MatrixOffset;
+    cmsUInt32Number OffsetRedTable, OffsetGreenTable, OffsetBlueTable;
+
+    if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
+    if (!_cmsWriteUInt32Number(io, mhc2->CurveEntries)) return FALSE;
+
+    if (!_cmsWrite15Fixed16Number(io, mhc2->MinLuminance)) return FALSE;
+    if (!_cmsWrite15Fixed16Number(io, mhc2->PeakLuminance)) return FALSE;
+
+    TablesOffsetPos = io->Tell(io);
+
+    if (!_cmsWriteUInt32Number(io, 0)) return FALSE;    // Matrix
+    if (!_cmsWriteUInt32Number(io, 0)) return FALSE;    // Curve R
+    if (!_cmsWriteUInt32Number(io, 0)) return FALSE;    // Curve G
+    if (!_cmsWriteUInt32Number(io, 0)) return FALSE;    // Curve B
+
+
+    if (IsIdentity(mhc2->XYZ2XYZmatrix))
+    {
+        MatrixOffset = 0;
+    }
+    else
+    {
+        MatrixOffset = io->Tell(io) - BaseOffset;
+        if (!WriteDoubles(io, 3 * 4, &mhc2->XYZ2XYZmatrix[0][0])) return FALSE;
+    }
+
+    OffsetRedTable = io->Tell(io) - BaseOffset;
+    if (!WriteDoubles(io, mhc2->CurveEntries, mhc2->RedCurve)) return FALSE;
+    OffsetGreenTable = io->Tell(io) - BaseOffset;
+    if (!WriteDoubles(io, mhc2->CurveEntries, mhc2->GreenCurve)) return FALSE;
+    OffsetBlueTable = io->Tell(io) - BaseOffset;
+    if (!WriteDoubles(io, mhc2->CurveEntries, mhc2->BlueCurve)) return FALSE;
+
+    if (!io->Seek(io, TablesOffsetPos)) return FALSE;
+
+    if (!_cmsWriteUInt32Number(io, MatrixOffset)) return FALSE;
+    if (!_cmsWriteUInt32Number(io, OffsetRedTable)) return FALSE;
+    if (!_cmsWriteUInt32Number(io, OffsetGreenTable)) return FALSE;
+    if (!_cmsWriteUInt32Number(io, OffsetBlueTable)) return FALSE;
+
+    return TRUE;
+
+    cmsUNUSED_PARAMETER(self);
+    cmsUNUSED_PARAMETER(nItems);
+}
+
+
+static
+cmsBool ReadDoublesAt(cmsIOHANDLER* io, cmsUInt32Number At, cmsUInt32Number n, cmsFloat64Number* Values)
+{
+    cmsUInt32Number CurrentPos = io->Tell(io);
+    cmsUInt32Number i;
+
+    if (!io->Seek(io, At)) return FALSE;
+
+    for (i = 0; i < n; i++) {
+
+        if (!_cmsRead15Fixed16Number(io, Values++)) return FALSE;
+    }
+
+    if (!io->Seek(io, CurrentPos)) return FALSE;
+
+    return TRUE;
+}
+
+static
+void* Type_MHC2_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
+{
+    cmsMHC2Type* mhc2 = NULL;
+
+    cmsUInt32Number BaseOffset = io->Tell(io) - sizeof(_cmsTagBase);
+    cmsUInt32Number MatrixOffset;
+    cmsUInt32Number OffsetRedTable, OffsetGreenTable, OffsetBlueTable;
+
+    if (!_cmsReadUInt32Number(io, NULL)) return NULL;
+
+    mhc2 = (cmsMHC2Type*)_cmsCalloc(self->ContextID, 1, sizeof(cmsMHC2Type));
+    if (mhc2 == NULL) return NULL;
+
+    if (!_cmsReadUInt32Number(io,    &mhc2->CurveEntries)) goto Error;
+
+    if (mhc2->CurveEntries > 4096) goto Error;
+
+    mhc2->RedCurve = (cmsFloat64Number*)_cmsCalloc(self->ContextID, mhc2->CurveEntries, sizeof(cmsFloat64Number));
+    mhc2->GreenCurve = (cmsFloat64Number*)_cmsCalloc(self->ContextID, mhc2->CurveEntries, sizeof(cmsFloat64Number));
+    mhc2->BlueCurve = (cmsFloat64Number*)_cmsCalloc(self->ContextID, mhc2->CurveEntries, sizeof(cmsFloat64Number));
+
+    if (mhc2->RedCurve == NULL ||
+        mhc2->GreenCurve == NULL ||
+        mhc2->BlueCurve == NULL)  goto Error;
+
+    if (!_cmsRead15Fixed16Number(io, &mhc2->MinLuminance)) goto Error;
+    if (!_cmsRead15Fixed16Number(io, &mhc2->PeakLuminance)) goto Error;
+
+    if (!_cmsReadUInt32Number(io, &MatrixOffset)) goto Error;
+    if (!_cmsReadUInt32Number(io, &OffsetRedTable)) goto Error;
+    if (!_cmsReadUInt32Number(io, &OffsetGreenTable)) goto Error;
+    if (!_cmsReadUInt32Number(io, &OffsetBlueTable)) goto Error;
+
+    if (MatrixOffset == 0)
+        SetIdentity(mhc2->XYZ2XYZmatrix);
+    else
+    {
+        if (!ReadDoublesAt(io, BaseOffset + MatrixOffset, 3*4, &mhc2->XYZ2XYZmatrix[0][0])) goto Error;
+    }
+
+    if (!ReadDoublesAt(io, BaseOffset + OffsetRedTable, mhc2->CurveEntries, mhc2->RedCurve)) goto Error;
+    if (!ReadDoublesAt(io, BaseOffset + OffsetGreenTable, mhc2->CurveEntries, mhc2->GreenCurve)) goto Error;
+    if (!ReadDoublesAt(io, BaseOffset + OffsetBlueTable, mhc2->CurveEntries, mhc2->BlueCurve)) goto Error;
+
+    // Success
+    *nItems = 1;
+    return mhc2;
+
+Error:
+    Type_MHC2_Free(self, mhc2);
+    return NULL;
+
+    cmsUNUSED_PARAMETER(SizeOfTag);
+}
+
+
+
 // ********************************************************************************
 // Type support main routines
 // ********************************************************************************
@@ -5538,7 +5771,8 @@ static const _cmsTagTypeLinkedList SupportedTagTypes[] = {
 {TYPE_HANDLER(cmsSigProfileSequenceIdType,     ProfileSequenceId),  (_cmsTagTypeLinkedList*) &SupportedTagTypes[29] },
 {TYPE_HANDLER(cmsSigDictType,                  Dictionary),         (_cmsTagTypeLinkedList*) &SupportedTagTypes[30] },
 {TYPE_HANDLER(cmsSigcicpType,                  VideoSignal),        (_cmsTagTypeLinkedList*) &SupportedTagTypes[31] },
-{TYPE_HANDLER(cmsSigVcgtType,                  vcgt),                NULL }
+{TYPE_HANDLER(cmsSigVcgtType,                  vcgt),               (_cmsTagTypeLinkedList*) &SupportedTagTypes[32] },
+{TYPE_HANDLER(cmsSigMHC2Type,                  MHC2),                NULL }
 };
 
 
@@ -5734,7 +5968,8 @@ static _cmsTagLinkedList SupportedTags[] = {
     { cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, &SupportedTags[63]},
     { cmsSigcicpTag,                { 1, 1, { cmsSigcicpType},               NULL },   &SupportedTags[64]},
 
-    { cmsSigArgyllArtsTag,          { 9, 1, { cmsSigS15Fixed16ArrayType},    NULL}, NULL}
+    { cmsSigArgyllArtsTag,          { 9, 1, { cmsSigS15Fixed16ArrayType},    NULL}, &SupportedTags[65]},
+    { cmsSigMHC2Tag,                { 1, 1, { cmsSigMHC2Type },              NULL}, NULL}
 
 };
 
diff --git a/src/java.desktop/share/native/liblcms/cmsvirt.c b/src/java.desktop/share/native/liblcms/cmsvirt.c
index 6ce04796174..e8d18d4ca9f 100644
--- a/src/java.desktop/share/native/liblcms/cmsvirt.c
+++ b/src/java.desktop/share/native/liblcms/cmsvirt.c
@@ -435,10 +435,9 @@ cmsHPROFILE CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext ContextID,
 
     if (Limit < 0.0 || Limit > 400) {
 
-        cmsSignalError(ContextID, cmsERROR_RANGE, "InkLimiting: Limit should be between 0..400");
-        if (Limit < 0) Limit = 0;
+        cmsSignalError(ContextID, cmsERROR_RANGE, "InkLimiting: Limit should be between 1..400");
+        if (Limit < 1) Limit = 1;
         if (Limit > 400) Limit = 400;
-
     }
 
     hICC = cmsCreateProfilePlaceholder(ContextID);
@@ -701,6 +700,127 @@ cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfile(void)
     return cmsCreate_sRGBProfileTHR(NULL);
 }
 
+/**
+* Oklab colorspace profile (experimental)
+*
+* This virtual profile cannot be saved as an ICC file
+*/
+cmsHPROFILE cmsCreate_OkLabProfile(cmsContext ctx)
+{
+    cmsStage* XYZPCS = _cmsStageNormalizeFromXyzFloat(ctx);
+    cmsStage* PCSXYZ = _cmsStageNormalizeToXyzFloat(ctx);
+
+    const double M_D65_D50[] =
+    {
+       1.047886, 0.022919, -0.050216,
+       0.029582, 0.990484, -0.017079,
+      -0.009252, 0.015073,  0.751678
+    };
+
+    const double M_D50_D65[] =
+    {
+         0.955512609517083, -0.023073214184645,  0.063308961782107,
+        -0.028324949364887,  1.009942432477107,  0.021054814890112,
+         0.012328875695483, -0.020535835374141,  1.330713916450354
+    };
+
+    cmsStage* D65toD50 = cmsStageAllocMatrix(ctx, 3, 3, M_D65_D50, NULL);
+    cmsStage* D50toD65 = cmsStageAllocMatrix(ctx, 3, 3, M_D50_D65, NULL);
+
+    const double M_D65_LMS[] =
+    {
+        0.8189330101, 0.3618667424, -0.1288597137,
+        0.0329845436, 0.9293118715,  0.0361456387,
+        0.0482003018, 0.2643662691,  0.6338517070
+    };
+
+    const double M_LMS_D65[] =
+    {
+        1.227013851103521, -0.557799980651822,  0.281256148966468,
+       -0.040580178423281,  1.112256869616830, -0.071676678665601,
+       -0.076381284505707, -0.421481978418013,  1.586163220440795
+    };
+
+    cmsStage* D65toLMS = cmsStageAllocMatrix(ctx, 3, 3, M_D65_LMS, NULL);
+    cmsStage* LMStoD65 = cmsStageAllocMatrix(ctx, 3, 3, M_LMS_D65, NULL);
+
+    cmsToneCurve* CubeRoot = cmsBuildGamma(ctx, 1.0 / 3.0);
+    cmsToneCurve* Cube     = cmsBuildGamma(ctx,  3.0);
+
+    cmsToneCurve* Roots[3] = { CubeRoot, CubeRoot, CubeRoot };
+    cmsToneCurve* Cubes[3] = { Cube, Cube, Cube };
+
+    cmsStage* NonLinearityFw = cmsStageAllocToneCurves(ctx, 3, Roots);
+    cmsStage* NonLinearityRv = cmsStageAllocToneCurves(ctx, 3, Cubes);
+
+    const double M_LMSprime_OkLab[] =
+    {
+        0.2104542553,  0.7936177850, -0.0040720468,
+        1.9779984951, -2.4285922050,  0.4505937099,
+        0.0259040371,  0.7827717662, -0.8086757660
+    };
+
+    const double M_OkLab_LMSprime[] =
+    {
+        0.999999998450520,  0.396337792173768,  0.215803758060759,
+        1.000000008881761, -0.105561342323656, -0.063854174771706,
+        1.000000054672411, -0.089484182094966, -1.291485537864092
+    };
+
+    cmsStage* LMSprime_OkLab = cmsStageAllocMatrix(ctx, 3, 3, M_LMSprime_OkLab, NULL);
+    cmsStage* OkLab_LMSprime = cmsStageAllocMatrix(ctx, 3, 3, M_OkLab_LMSprime, NULL);
+
+    cmsPipeline* AToB = cmsPipelineAlloc(ctx, 3, 3);
+    cmsPipeline* BToA = cmsPipelineAlloc(ctx, 3, 3);
+
+    cmsHPROFILE hProfile = cmsCreateProfilePlaceholder(ctx);
+
+    cmsSetProfileVersion(hProfile, 4.4);
+
+    cmsSetDeviceClass(hProfile, cmsSigColorSpaceClass);
+    cmsSetColorSpace(hProfile, cmsSig3colorData);
+    cmsSetPCS(hProfile, cmsSigXYZData);
+
+    cmsSetHeaderRenderingIntent(hProfile, INTENT_RELATIVE_COLORIMETRIC);
+
+    /**
+    * Conversion PCS (XYZ/D50) to OkLab
+    */
+    if (!cmsPipelineInsertStage(BToA, cmsAT_END, PCSXYZ)) goto error;
+    if (!cmsPipelineInsertStage(BToA, cmsAT_END, D50toD65)) goto error;
+    if (!cmsPipelineInsertStage(BToA, cmsAT_END, D65toLMS)) goto error;
+    if (!cmsPipelineInsertStage(BToA, cmsAT_END, NonLinearityFw)) goto error;
+    if (!cmsPipelineInsertStage(BToA, cmsAT_END, LMSprime_OkLab)) goto error;
+
+    if (!cmsWriteTag(hProfile, cmsSigBToA0Tag, BToA)) goto error;
+
+    if (!cmsPipelineInsertStage(AToB, cmsAT_END, OkLab_LMSprime)) goto error;
+    if (!cmsPipelineInsertStage(AToB, cmsAT_END, NonLinearityRv)) goto error;
+    if (!cmsPipelineInsertStage(AToB, cmsAT_END, LMStoD65)) goto error;
+    if (!cmsPipelineInsertStage(AToB, cmsAT_END, D65toD50)) goto error;
+    if (!cmsPipelineInsertStage(AToB, cmsAT_END, XYZPCS)) goto error;
+
+    if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, AToB)) goto error;
+
+    cmsPipelineFree(BToA);
+    cmsPipelineFree(AToB);
+
+    cmsFreeToneCurve(CubeRoot);
+    cmsFreeToneCurve(Cube);
+
+    return hProfile;
+
+error:
+    cmsPipelineFree(BToA);
+    cmsPipelineFree(AToB);
+
+    cmsFreeToneCurve(CubeRoot);
+    cmsFreeToneCurve(Cube);
+    cmsCloseProfile(hProfile);
+
+    return NULL;
+
+}
 
 
 typedef struct {
@@ -1060,7 +1180,7 @@ cmsBool CheckOne(const cmsAllowedLUT* Tab, const cmsPipeline* Lut)
 
     for (n=0, mpe = Lut ->Elements; mpe != NULL; mpe = mpe ->Next, n++) {
 
-        if (n > Tab ->nTypes) return FALSE;
+        if (n >= Tab ->nTypes) return FALSE;
         if (cmsStageType(mpe) != Tab ->MpeTypes[n]) return FALSE;
     }
 
@@ -1091,9 +1211,9 @@ const cmsAllowedLUT* FindCombination(const cmsPipeline* Lut, cmsBool IsV4, cmsTa
 cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat64Number Version, cmsUInt32Number dwFlags)
 {
     cmsHPROFILE hProfile = NULL;
-        cmsUInt32Number FrmIn, FrmOut;
-        cmsInt32Number ChansIn, ChansOut;
-        int ColorSpaceBitsIn, ColorSpaceBitsOut;
+    cmsUInt32Number FrmIn, FrmOut;
+    cmsInt32Number ChansIn, ChansOut;
+    int ColorSpaceBitsIn, ColorSpaceBitsOut;
     _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
     cmsPipeline* LUT = NULL;
     cmsStage* mpe;
@@ -1104,6 +1224,9 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
 
     _cmsAssert(hTransform != NULL);
 
+    // Check if the pipeline holding is valid
+    if (xform -> Lut == NULL) return NULL;
+
     // Get the first mpe to check for named color
     mpe = cmsPipelineGetPtrToFirstStage(xform ->Lut);
 
diff --git a/src/java.desktop/share/native/liblcms/cmsxform.c b/src/java.desktop/share/native/liblcms/cmsxform.c
index 3f3ad28c6c4..86afd7202fd 100644
--- a/src/java.desktop/share/native/liblcms/cmsxform.c
+++ b/src/java.desktop/share/native/liblcms/cmsxform.c
@@ -943,7 +943,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
        }
 
     // Check whatever this is a true floating point transform
-    if (_cmsFormatterIsFloat(*OutputFormat)) {
+    if (_cmsFormatterIsFloat(*InputFormat) || _cmsFormatterIsFloat(*OutputFormat)) {
 
         // Get formatter function always return a valid union, but the contents of this union may be NULL.
         p ->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat,  cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
@@ -1018,6 +1018,19 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
         }
     }
 
+    /**
+    * Check consistency for alpha channel copy
+    */
+    if (*dwFlags & cmsFLAGS_COPY_ALPHA)
+    {
+        if (T_EXTRA(*InputFormat) != T_EXTRA(*OutputFormat))
+        {
+            cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Mismatched alpha channels");
+            cmsDeleteTransform(p);
+            return NULL;
+        }
+    }
+
     p ->InputFormat     = *InputFormat;
     p ->OutputFormat    = *OutputFormat;
     p ->dwOriginalFlags = *dwFlags;
diff --git a/src/java.desktop/share/native/liblcms/lcms2.h b/src/java.desktop/share/native/liblcms/lcms2.h
index d5b8c477f23..2d9a8b1248f 100644
--- a/src/java.desktop/share/native/liblcms/lcms2.h
+++ b/src/java.desktop/share/native/liblcms/lcms2.h
@@ -52,7 +52,7 @@
 //
 //---------------------------------------------------------------------------------
 //
-// Version 2.15
+// Version 2.16
 //
 
 #ifndef _lcms2_H
@@ -105,12 +105,15 @@
 
 #ifndef CMS_USE_CPP_API
 #   ifdef __cplusplus
+#       if __cplusplus >= 201703L
+#            define CMS_NO_REGISTER_KEYWORD 1
+#       endif
 extern "C" {
 #   endif
 #endif
 
 // Version/release
-#define LCMS_VERSION        2150
+#define LCMS_VERSION        2160
 
 // I will give the chance of redefining basic types for compilers that are not fully C99 compliant
 #ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
@@ -354,7 +357,8 @@ typedef enum {
     cmsSigUInt8ArrayType                    = 0x75693038,  // 'ui08'
     cmsSigVcgtType                          = 0x76636774,  // 'vcgt'
     cmsSigViewingConditionsType             = 0x76696577,  // 'view'
-    cmsSigXYZType                           = 0x58595A20   // 'XYZ '
+    cmsSigXYZType                           = 0x58595A20,  // 'XYZ '
+    cmsSigMHC2Type                          = 0x4D484332   // 'MHC2'
 
 
 } cmsTagTypeSignature;
@@ -432,7 +436,8 @@ typedef enum {
     cmsSigVcgtTag                           = 0x76636774,  // 'vcgt'
     cmsSigMetaTag                           = 0x6D657461,  // 'meta'
     cmsSigcicpTag                           = 0x63696370,  // 'cicp'
-    cmsSigArgyllArtsTag                     = 0x61727473   // 'arts'
+    cmsSigArgyllArtsTag                     = 0x61727473,  // 'arts'
+    cmsSigMHC2Tag                           = 0x4D484332   // 'MHC2'
 
 } cmsTagSignature;
 
@@ -977,6 +982,7 @@ typedef void* cmsHTRANSFORM;
 #define TYPE_RGB_DBL          (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(0))
 #define TYPE_BGR_DBL          (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(0)|DOSWAP_SH(1))
 #define TYPE_CMYK_DBL         (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(0))
+#define TYPE_OKLAB_DBL        (FLOAT_SH(1)|COLORSPACE_SH(PT_MCH3)|CHANNELS_SH(3)|BYTES_SH(0))
 
 // IEEE 754-2008 "half"
 #define TYPE_GRAY_HALF_FLT    (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(2))
@@ -1077,6 +1083,19 @@ typedef struct {
 
 } cmsVideoSignalType;
 
+typedef struct {
+    cmsUInt32Number   CurveEntries;
+    cmsFloat64Number* RedCurve;
+    cmsFloat64Number* GreenCurve;
+    cmsFloat64Number* BlueCurve;
+
+    cmsFloat64Number  MinLuminance;         // ST.2086 min luminance in nits
+    cmsFloat64Number  PeakLuminance;        // ST.2086 peak luminance in nits
+
+    cmsFloat64Number XYZ2XYZmatrix[3][4];
+
+} cmsMHC2Type;
+
 
 
 // Get LittleCMS version (for shared objects) -----------------------------------------------------------------------------
@@ -1249,7 +1268,8 @@ CMSAPI cmsBool           CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t
 CMSAPI cmsBool           CMSEXPORT cmsIsToneCurveDescending(const cmsToneCurve* t);
 CMSAPI cmsInt32Number    CMSEXPORT cmsGetToneCurveParametricType(const cmsToneCurve* t);
 CMSAPI cmsFloat64Number  CMSEXPORT cmsEstimateGamma(const cmsToneCurve* t, cmsFloat64Number Precision);
-CMSAPI cmsFloat64Number* CMSEXPORT cmsGetToneCurveParams(const cmsToneCurve* t);
+
+CMSAPI const cmsCurveSegment* CMSEXPORT cmsGetToneCurveSegment(cmsInt32Number n, const cmsToneCurve* t);
 
 // Tone curve tabular estimation
 CMSAPI cmsUInt32Number         CMSEXPORT cmsGetToneCurveEstimatedTableEntries(const cmsToneCurve* t);
@@ -1343,8 +1363,11 @@ CMSAPI cmsBool           CMSEXPORT cmsSliceSpaceFloat(cmsUInt32Number nInputs, c
 
 typedef struct _cms_MLU_struct cmsMLU;
 
-#define  cmsNoLanguage "\0\0"
-#define  cmsNoCountry  "\0\0"
+#define  cmsNoLanguage    "\0\0"
+#define  cmsNoCountry     "\0\0"
+
+// Special language/country to retrieve unicode field for description in V2 profiles. Use with care.
+#define  cmsV2Unicode     "\xff\xff"
 
 CMSAPI cmsMLU*           CMSEXPORT cmsMLUalloc(cmsContext ContextID, cmsUInt32Number nItems);
 CMSAPI void              CMSEXPORT cmsMLUfree(cmsMLU* mlu);
@@ -1356,6 +1379,9 @@ CMSAPI cmsBool           CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu,
 CMSAPI cmsBool           CMSEXPORT cmsMLUsetWide(cmsMLU* mlu,
                                                   const char LanguageCode[3], const char CountryCode[3],
                                                   const wchar_t* WideString);
+CMSAPI cmsBool           CMSEXPORT cmsMLUsetUTF8(cmsMLU* mlu,
+                                                  const char LanguageCode[3], const char CountryCode[3],
+                                                  const char* UTF8String);
 
 CMSAPI cmsUInt32Number   CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
                                                   const char LanguageCode[3], const char CountryCode[3],
@@ -1364,6 +1390,10 @@ CMSAPI cmsUInt32Number   CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
 CMSAPI cmsUInt32Number   CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu,
                                                  const char LanguageCode[3], const char CountryCode[3],
                                                  wchar_t* Buffer, cmsUInt32Number BufferSize);
+CMSAPI cmsUInt32Number   CMSEXPORT cmsMLUgetUTF8(const cmsMLU* mlu,
+                                                 const char LanguageCode[3], const char CountryCode[3],
+                                                 char* Buffer, cmsUInt32Number BufferSize);
+
 
 CMSAPI cmsBool           CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu,
                                                          const char LanguageCode[3], const char CountryCode[3],
@@ -1588,6 +1618,10 @@ CMSAPI cmsUInt32Number   CMSEXPORT cmsGetProfileInfoASCII(cmsHPROFILE hProfile,
                                                             const char LanguageCode[3], const char CountryCode[3],
                                                             char* Buffer, cmsUInt32Number BufferSize);
 
+CMSAPI cmsUInt32Number  CMSEXPORT cmsGetProfileInfoUTF8(cmsHPROFILE hProfile, cmsInfoType Info,
+                                                            const char LanguageCode[3], const char CountryCode[3],
+                                                            char* Buffer, cmsUInt32Number BufferSize);
+
 // IO handlers ----------------------------------------------------------------------------------------------------------
 
 typedef struct _cms_io_handler cmsIOHANDLER;
@@ -1650,6 +1684,9 @@ CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateInkLimitingDeviceLinkTHR(cmsContext C
 
 CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateInkLimitingDeviceLink(cmsColorSpaceSignature ColorSpace, cmsFloat64Number Limit);
 
+CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateDeviceLinkFromCubeFile(const char* cFileName);
+
+CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateDeviceLinkFromCubeFileTHR(cmsContext ContextID, const char* cFileName);
 
 CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateLab2ProfileTHR(cmsContext ContextID, const cmsCIExyY* WhitePoint);
 CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateLab2Profile(const cmsCIExyY* WhitePoint);
@@ -1662,6 +1699,8 @@ CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateXYZProfile(void);
 CMSAPI cmsHPROFILE      CMSEXPORT cmsCreate_sRGBProfileTHR(cmsContext ContextID);
 CMSAPI cmsHPROFILE      CMSEXPORT cmsCreate_sRGBProfile(void);
 
+CMSAPI cmsHPROFILE      CMSEXPORT cmsCreate_OkLabProfile(cmsContext ctx);
+
 CMSAPI cmsHPROFILE      CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID,
                                                              cmsUInt32Number nLUTPoints,
                                                              cmsFloat64Number Bright,
diff --git a/src/java.desktop/share/native/liblcms/lcms2_internal.h b/src/java.desktop/share/native/liblcms/lcms2_internal.h
index 4c29a6c0218..75973edad0d 100644
--- a/src/java.desktop/share/native/liblcms/lcms2_internal.h
+++ b/src/java.desktop/share/native/liblcms/lcms2_internal.h
@@ -288,6 +288,7 @@ typedef CRITICAL_SECTION _cmsMutex;
 #ifdef _MSC_VER
 #    if (_MSC_VER >= 1800)
 #          pragma warning(disable : 26135)
+#          pragma warning(disable : 4127)
 #    endif
 #endif
 
@@ -545,7 +546,7 @@ struct _cmsContext_struct {
     struct _cmsContext_struct* Next;  // Points to next context in the new style
     _cmsSubAllocator* MemPool;        // The memory pool that stores context data
 
-    void* chunks[MemoryClientMax];    // array of pointers to client chunks. Memory itself is hold in the suballocator.
+    void* chunks[MemoryClientMax];    // array of pointers to client chunks. Memory itself is held in the suballocator.
                                       // If NULL, then it reverts to global Context0
 
     _cmsMemPluginChunkType DefaultMemoryManager;  // The allocators used for creating the context itself. Cannot be overridden
@@ -839,6 +840,9 @@ typedef struct _cms_iccprofile_struct {
     // Creation time
     struct tm                Created;
 
+    // Color management module identification
+    cmsUInt32Number          CMM;
+
     // Only most important items found in ICC profiles
     cmsUInt32Number          Version;
     cmsProfileClassSignature DeviceClass;
@@ -846,6 +850,7 @@ typedef struct _cms_iccprofile_struct {
     cmsColorSpaceSignature   PCS;
     cmsUInt32Number          RenderingIntent;
 
+    cmsPlatformSignature     platform;
     cmsUInt32Number          flags;
     cmsUInt32Number          manufacturer, model;
     cmsUInt64Number          attributes;
diff --git a/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java b/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java
index 31764c74948..d785823ea8e 100644
--- a/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java
+++ b/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2024, 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,8 +26,12 @@
 
 import java.awt.RenderingHints;
 import static java.awt.RenderingHints.*;
+import static java.util.concurrent.TimeUnit.SECONDS;
 import java.awt.color.ColorSpace;
 import java.awt.image.*;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 
@@ -214,6 +218,72 @@ protected Object lazilyLoadGTKIcon(String longname) {
         return img;
     }
 
+    private static volatile Boolean shouldDisableSystemTray = null;
+
+    /**
+     * There is an issue displaying the xembed icons in appIndicators
+     * area with certain Gnome Shell versions.
+     * To avoid any loss of quality of service, we are disabling
+     * SystemTray support in such cases.
+     *
+     * @return true if system tray should be disabled
+     */
+    public boolean shouldDisableSystemTray() {
+        Boolean result = shouldDisableSystemTray;
+        if (result == null) {
+            synchronized (GTK_LOCK) {
+                result = shouldDisableSystemTray;
+                if (result == null) {
+                    if ("gnome".equals(getDesktop())) {
+                        @SuppressWarnings("removal")
+                        Integer gnomeShellMajorVersion =
+                                AccessController
+                                        .doPrivileged((PrivilegedAction)
+                                                this::getGnomeShellMajorVersion);
+
+                        if (gnomeShellMajorVersion == null
+                                || gnomeShellMajorVersion < 45) {
+
+                            return shouldDisableSystemTray = true;
+                        }
+                    }
+                    shouldDisableSystemTray = result = false;
+                }
+            }
+        }
+        return result;
+    }
+
+    private Integer getGnomeShellMajorVersion() {
+        try {
+            Process process =
+                new ProcessBuilder("/usr/bin/gnome-shell", "--version")
+                        .start();
+            try (InputStreamReader isr = new InputStreamReader(process.getInputStream());
+                 BufferedReader reader = new BufferedReader(isr)) {
+
+                if (process.waitFor(2, SECONDS) &&  process.exitValue() == 0) {
+                    String line = reader.readLine();
+                    if (line != null) {
+                        String[] versionComponents = line
+                                .replaceAll("[^\\d.]", "")
+                                .split("\\.");
+
+                        if (versionComponents.length >= 1) {
+                            return Integer.parseInt(versionComponents[0]);
+                        }
+                    }
+                }
+            }
+        } catch (IOException
+                 | InterruptedException
+                 | IllegalThreadStateException
+                 | NumberFormatException ignored) {
+        }
+
+        return null;
+    }
+
     /**
      * Returns a BufferedImage which contains the Gtk icon requested.  If no
      * such icon exists or an error occurs loading the icon the result will
diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XSystemTrayPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XSystemTrayPeer.java
index 1a9d040616e..cdbb74ddac1 100644
--- a/src/java.desktop/unix/classes/sun/awt/X11/XSystemTrayPeer.java
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XSystemTrayPeer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2024, 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
@@ -30,6 +30,7 @@
 import sun.awt.SunToolkit;
 import sun.awt.AppContext;
 import sun.awt.AWTAccessor;
+import sun.awt.UNIXToolkit;
 import sun.util.logging.PlatformLogger;
 
 public class XSystemTrayPeer implements SystemTrayPeer, XMSelectionListener {
@@ -48,22 +49,32 @@ public class XSystemTrayPeer implements SystemTrayPeer, XMSelectionListener {
     private static final XAtom _NET_SYSTEM_TRAY_OPCODE = XAtom.get("_NET_SYSTEM_TRAY_OPCODE");
     private static final XAtom _NET_WM_ICON = XAtom.get("_NET_WM_ICON");
     private static final long SYSTEM_TRAY_REQUEST_DOCK = 0;
+    private final boolean shouldDisableSystemTray;
 
     XSystemTrayPeer(SystemTray target) {
         this.target = target;
         peerInstance = this;
 
-        selection.addSelectionListener(this);
+        UNIXToolkit tk = (UNIXToolkit)Toolkit.getDefaultToolkit();
+        shouldDisableSystemTray = tk.shouldDisableSystemTray();
 
-        long selection_owner = selection.getOwner(SCREEN);
-        available = (selection_owner != XConstants.None);
+        if (!shouldDisableSystemTray) {
+            selection.addSelectionListener(this);
 
-        if (log.isLoggable(PlatformLogger.Level.FINE)) {
-            log.fine(" check if system tray is available. selection owner: " + selection_owner);
+            long selection_owner = selection.getOwner(SCREEN);
+            available = (selection_owner != XConstants.None);
+
+            if (log.isLoggable(PlatformLogger.Level.FINE)) {
+                log.fine(" check if system tray is available. selection owner: " + selection_owner);
+            }
         }
     }
 
     public void ownerChanged(int screen, XMSelection sel, long newOwner, long data, long timestamp) {
+        if (shouldDisableSystemTray) {
+            return;
+        }
+
         if (screen != SCREEN) {
             return;
         }
@@ -77,6 +88,10 @@ public void ownerChanged(int screen, XMSelection sel, long newOwner, long data,
     }
 
     public void ownerDeath(int screen, XMSelection sel, long deadOwner) {
+        if (shouldDisableSystemTray) {
+            return;
+        }
+
         if (screen != SCREEN) {
             return;
         }
diff --git a/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java b/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java
index 02527d4f207..4644a2e5f46 100644
--- a/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java
+++ b/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2024, 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
@@ -28,20 +28,41 @@
 import java.awt.GraphicsEnvironment;
 import java.awt.Toolkit;
 
+import sun.awt.windows.WToolkit;
+
 public class PlatformGraphicsInfo {
 
+    private static final boolean hasDisplays;
+
+    static {
+        loadAWTLibrary();
+        hasDisplays = hasDisplays0();
+    }
+
+    @SuppressWarnings("removal")
+    private static void loadAWTLibrary() {
+        java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction() {
+                public Void run() {
+                    System.loadLibrary("awt");
+                    return null;
+                }
+            });
+    }
+
+    private static native boolean hasDisplays0();
+
     public static GraphicsEnvironment createGE() {
         return new Win32GraphicsEnvironment();
     }
 
     public static Toolkit createToolkit() {
-        return new sun.awt.windows.WToolkit();
+        return new WToolkit();
     }
 
     public static boolean getDefaultHeadlessProperty() {
-        // On Windows, we assume we can always create headful apps.
-        // Here is where we can add code that would actually check.
-        return false;
+        // If we don't find usable displays, we run headless.
+        return !hasDisplays;
     }
 
     /*
@@ -54,5 +75,4 @@ public static String getDefaultHeadlessMessage() {
             "\nThe application does not have desktop access,\n" +
             "but this program performed an operation which requires it.";
     }
-
 }
diff --git a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java
index 04b3f7b77d7..cb7ab363cdf 100644
--- a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java
+++ b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, 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
@@ -60,7 +60,8 @@ public final class Win32GraphicsEnvironment extends SunGraphicsEnvironment {
         WToolkit.loadLibraries();
         // setup flags before initializing native layer
         WindowsFlags.initFlags();
-        initDisplayWrapper();
+
+        initDisplay();
 
         // Install correct surface manager factory.
         SurfaceManagerFactory.setInstance(new WindowsSurfaceManagerFactory());
@@ -82,20 +83,12 @@ public final class Win32GraphicsEnvironment extends SunGraphicsEnvironment {
     }
 
     /**
-     * Initializes native components of the graphics environment.  This
+     * Initializes native components of the graphics environment. This
      * includes everything from the native GraphicsDevice elements to
      * the DirectX rendering layer.
      */
     private static native void initDisplay();
 
-    private static boolean displayInitialized;      // = false;
-    public static void initDisplayWrapper() {
-        if (!displayInitialized) {
-            displayInitialized = true;
-            initDisplay();
-        }
-    }
-
     public Win32GraphicsEnvironment() {
     }
 
diff --git a/src/java.desktop/windows/native/libawt/windows/Devices.cpp b/src/java.desktop/windows/native/libawt/windows/Devices.cpp
index 9738bd057e1..abf459c9149 100644
--- a/src/java.desktop/windows/native/libawt/windows/Devices.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/Devices.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2024, 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
@@ -85,60 +85,75 @@
 #include "Trace.h"
 #include "D3DPipelineManager.h"
 
+typedef struct {
+    int monitorCounter;
+    int monitorLimit;
+    HMONITOR* hmpMonitors;
+} MonitorData;
 
-/* Some helper functions (from awt_MMStub.h/cpp) */
 
-int g_nMonitorCounter;
-int g_nMonitorLimit;
-HMONITOR* g_hmpMonitors;
+// Only monitors where CreateDC does not fail are valid
+static BOOL IsValidMonitor(HMONITOR hMon)
+{
+    MONITORINFOEX mieInfo;
+    memset((void*)(&mieInfo), 0, sizeof(MONITORINFOEX));
+    mieInfo.cbSize = sizeof(MONITORINFOEX);
+    if (!::GetMonitorInfo(hMon, (LPMONITORINFOEX)(&mieInfo))) {
+        J2dTraceLn1(J2D_TRACE_INFO, "Devices::IsValidMonitor: GetMonitorInfo failed for monitor with handle %p", hMon);
+        return FALSE;
+    }
+
+    HDC hDC = CreateDC(mieInfo.szDevice, NULL, NULL, NULL);
+    if (NULL == hDC) {
+        J2dTraceLn2(J2D_TRACE_INFO, "Devices::IsValidMonitor: CreateDC failed for monitor with handle %p, device: %S", hMon, mieInfo.szDevice);
+        return FALSE;
+    }
+
+    ::DeleteDC(hDC);
+    return TRUE;
+}
 
 // Callback for CountMonitors below
-BOOL WINAPI clb_fCountMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lP)
+static BOOL WINAPI clb_fCountMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lpMonitorCounter)
 {
-    g_nMonitorCounter ++;
+    if (IsValidMonitor(hMon)) {
+        (*((int *)lpMonitorCounter))++;
+    }
+
     return TRUE;
 }
 
 int WINAPI CountMonitors(void)
 {
-    g_nMonitorCounter = 0;
-    ::EnumDisplayMonitors(NULL, NULL, clb_fCountMonitors, 0L);
-    return g_nMonitorCounter;
-
+    int monitorCounter = 0;
+    ::EnumDisplayMonitors(NULL, NULL, clb_fCountMonitors, (LPARAM)&monitorCounter);
+    return monitorCounter;
 }
 
 // Callback for CollectMonitors below
-BOOL WINAPI clb_fCollectMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lP)
+static BOOL WINAPI clb_fCollectMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lpMonitorData)
 {
-
-    if ((g_nMonitorCounter < g_nMonitorLimit) && (NULL != g_hmpMonitors)) {
-        g_hmpMonitors[g_nMonitorCounter] = hMon;
-        g_nMonitorCounter ++;
+    MonitorData* pMonitorData = (MonitorData *)lpMonitorData;
+    if ((pMonitorData->monitorCounter < pMonitorData->monitorLimit) && (IsValidMonitor(hMon))) {
+        pMonitorData->hmpMonitors[pMonitorData->monitorCounter] = hMon;
+        pMonitorData->monitorCounter++;
     }
 
     return TRUE;
 }
 
-int WINAPI CollectMonitors(HMONITOR* hmpMonitors, int nNum)
+static int WINAPI CollectMonitors(HMONITOR* hmpMonitors, int nNum)
 {
-    int retCode = 0;
-
     if (NULL != hmpMonitors) {
-
-        g_nMonitorCounter   = 0;
-        g_nMonitorLimit     = nNum;
-        g_hmpMonitors       = hmpMonitors;
-
-        ::EnumDisplayMonitors(NULL, NULL, clb_fCollectMonitors, 0L);
-
-        retCode             = g_nMonitorCounter;
-
-        g_nMonitorCounter   = 0;
-        g_nMonitorLimit     = 0;
-        g_hmpMonitors       = NULL;
-
+        MonitorData monitorData;
+        monitorData.monitorCounter = 0;
+        monitorData.monitorLimit = nNum;
+        monitorData.hmpMonitors = hmpMonitors;
+        ::EnumDisplayMonitors(NULL, NULL, clb_fCollectMonitors, (LPARAM)&monitorData);
+        return monitorData.monitorCounter;
+    } else {
+        return 0;
     }
-    return retCode;
 }
 
 BOOL WINAPI MonitorBounds(HMONITOR hmMonitor, RECT* rpBounds)
diff --git a/src/java.desktop/windows/native/libawt/windows/Devices.h b/src/java.desktop/windows/native/libawt/windows/Devices.h
index 108ae7c963f..0972ef1414e 100644
--- a/src/java.desktop/windows/native/libawt/windows/Devices.h
+++ b/src/java.desktop/windows/native/libawt/windows/Devices.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2024, 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
@@ -74,4 +74,6 @@ static CriticalSection          arrayLock;
 
 BOOL WINAPI MonitorBounds (HMONITOR, RECT*);
 
-#endif _DEVICES_H_
+int WINAPI CountMonitors (void);
+
+#endif // _DEVICES_H_
diff --git a/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp b/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp
index 97a496ff74c..b9064c531de 100644
--- a/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp
@@ -52,6 +52,7 @@ typedef HRESULT(__stdcall *PFNCLOSETHEMEDATA)(HTHEME hTheme);
 typedef HRESULT(__stdcall *PFNDRAWTHEMEBACKGROUND)(HTHEME hTheme, HDC hdc,
         int iPartId, int iStateId, const RECT *pRect,  const RECT *pClipRect);
 
+typedef HTHEME(__stdcall *PFNOPENTHEMEDATA)(HWND hwnd, LPCWSTR pszClassList);
 typedef HTHEME(__stdcall *PFNOPENTHEMEDATAFORDPI)(HWND hwnd, LPCWSTR pszClassList, UINT dpi);
 
 typedef HRESULT (__stdcall *PFNDRAWTHEMETEXT)(HTHEME hTheme, HDC hdc,
@@ -96,6 +97,7 @@ typedef HRESULT (__stdcall *PFNGETTHEMETRANSITIONDURATION)
                 (HTHEME hTheme, int iPartId, int iStateIdFrom, int iStateIdTo,
                  int iPropId, DWORD *pdwDuration);
 
+static PFNOPENTHEMEDATA OpenThemeDataFunc = NULL;
 static PFNOPENTHEMEDATAFORDPI OpenThemeDataForDpiFunc = NULL;
 static PFNDRAWTHEMEBACKGROUND DrawThemeBackgroundFunc = NULL;
 static PFNCLOSETHEMEDATA CloseThemeDataFunc = NULL;
@@ -115,13 +117,17 @@ static PFNISTHEMEBACKGROUNDPARTIALLYTRANSPARENT
                                IsThemeBackgroundPartiallyTransparentFunc = NULL;
 static PFNGETTHEMETRANSITIONDURATION GetThemeTransitionDurationFunc = NULL;
 
+constexpr unsigned int defaultDPI = 96;
 
-BOOL InitThemes() {
+
+static BOOL InitThemes() {
     static HMODULE hModThemes = NULL;
     hModThemes = JDK_LoadSystemLibrary("UXTHEME.DLL");
     DTRACE_PRINTLN1("InitThemes hModThemes = %x\n", hModThemes);
     if(hModThemes) {
         DTRACE_PRINTLN("Loaded UxTheme.dll\n");
+        OpenThemeDataFunc = (PFNOPENTHEMEDATA)GetProcAddress(hModThemes,
+                                                         "OpenThemeData");
         OpenThemeDataForDpiFunc = (PFNOPENTHEMEDATAFORDPI)GetProcAddress(
                                    hModThemes, "OpenThemeDataForDpi");
         DrawThemeBackgroundFunc = (PFNDRAWTHEMEBACKGROUND)GetProcAddress(
@@ -158,7 +164,7 @@ BOOL InitThemes() {
             (PFNGETTHEMETRANSITIONDURATION)GetProcAddress(hModThemes,
                                         "GetThemeTransitionDuration");
 
-        if(OpenThemeDataForDpiFunc
+        if((OpenThemeDataForDpiFunc || OpenThemeDataFunc)
            && DrawThemeBackgroundFunc
            && CloseThemeDataFunc
            && DrawThemeTextFunc
@@ -179,10 +185,12 @@ BOOL InitThemes() {
               DTRACE_PRINTLN("Loaded function pointers.\n");
               // We need to make sure we can load the Theme.
               // Use the default DPI value of 96 on windows.
-              constexpr unsigned int defaultDPI = 96;
-              HTHEME hTheme = OpenThemeDataForDpiFunc (
-                              AwtToolkit::GetInstance().GetHWnd(),
-                              L"Button", defaultDPI);
+              HTHEME hTheme = OpenThemeDataForDpiFunc
+                              ? OpenThemeDataForDpiFunc(AwtToolkit::GetInstance().GetHWnd(),
+                                                        L"Button", defaultDPI)
+                              : OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(),
+                                                  L"Button");
+
               if(hTheme) {
                   DTRACE_PRINTLN("Loaded Theme data.\n");
                   CloseThemeDataFunc(hTheme);
@@ -252,11 +260,13 @@ JNIEXPORT jlong JNICALL Java_sun_awt_windows_ThemeReader_openTheme
         JNU_ThrowOutOfMemoryError(env, 0);
         return 0;
     }
+
     // We need to open the Theme on a Window that will stick around.
     // The best one for that purpose is the Toolkit window.
-    HTHEME htheme = OpenThemeDataForDpiFunc(
-                    AwtToolkit::GetInstance().GetHWnd(),
-                    str, dpi);
+    HTHEME htheme = OpenThemeDataForDpiFunc
+                    ? OpenThemeDataForDpiFunc(AwtToolkit::GetInstance().GetHWnd(), str, dpi)
+                    : OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(), str);
+
     JNU_ReleaseStringPlatformChars(env, widget, str);
     return (jlong) htheme;
 }
@@ -436,9 +446,14 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground
 
     rect.left = 0;
     rect.top = 0;
-    rect.bottom = rectBottom;
-    rect.right = rectRight;
 
+    if (OpenThemeDataForDpiFunc) {
+        rect.bottom = rectBottom;
+        rect.right = rectRight;
+    } else {
+        rect.bottom = h;
+        rect.right = w;
+    }
     ZeroMemory(pSrcBits,(BITS_PER_PIXEL>>3)*w*h);
 
     HRESULT hres = DrawThemeBackgroundFunc(hTheme, memDC, part, state, &rect, NULL);
@@ -461,6 +476,28 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground
     ReleaseDC(NULL,defaultDC);
 }
 
+static void rescale(SIZE *size) {
+    static int dpiX = -1;
+    static int dpiY = -1;
+
+    if (dpiX == -1 || dpiY == -1) {
+        HWND hWnd = ::GetDesktopWindow();
+        HDC hDC = ::GetDC(hWnd);
+        dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
+        dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
+        ::ReleaseDC(hWnd, hDC);
+    }
+
+    if (dpiX !=0 && dpiX != defaultDPI) {
+        float invScaleX = (float) defaultDPI / dpiX;
+        size->cx = (int) round(size->cx * invScaleX);
+    }
+    if (dpiY != 0 && dpiY != defaultDPI) {
+        float invScaleY = (float) defaultDPI / dpiY;
+        size->cy = (int) round(size->cy * invScaleY);
+    }
+}
+
 jobject newInsets(JNIEnv *env, jint top, jint left, jint bottom, jint right) {
     if (env->EnsureLocalCapacity(2) < 0) {
         return NULL;
@@ -752,6 +789,10 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPartSize
                 CHECK_NULL_RETURN(dimMID, NULL);
             }
 
+            if (!OpenThemeDataForDpiFunc) {
+                rescale(&size);
+            }
+
             jobject dimObj = env->NewObject(dimClassID, dimMID, size.cx, size.cy);
             if (safe_ExceptionOccurred(env)) {
                 env->ExceptionDescribe();
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_PlatformGraphicsInfo.cpp b/src/java.desktop/windows/native/libawt/windows/awt_PlatformGraphicsInfo.cpp
new file mode 100644
index 00000000000..638cd100b1f
--- /dev/null
+++ b/src/java.desktop/windows/native/libawt/windows/awt_PlatformGraphicsInfo.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2024 SAP SE. 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.
+ */
+
+#include 
+#include "Devices.h"
+
+/*
+ * Class:     sun_awt_PlatformGraphicsInfo
+ * Method:    hasDisplays0
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_sun_awt_PlatformGraphicsInfo_hasDisplays0(JNIEnv *env, jclass thisClass) {
+    return CountMonitors() > 0 ? JNI_TRUE : JNI_FALSE;
+}
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp b/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp
index 99ef4e95c94..817625c6d4c 100644
--- a/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2023, 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
@@ -262,7 +262,7 @@ LRESULT CALLBACK AwtTrayIcon::TrayWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam
                 }
             }
             break;
-        case WM_DPICHANGED:
+        case WM_DISPLAYCHANGE:
             // Set the flag to update icon images, see WmTaskbarCreated
             m_bDPIChanged = true;
             break;
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp
index 79e7b9d1050..6529298c34d 100644
--- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2024, 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
@@ -180,7 +180,9 @@ void AwtWin32GraphicsDevice::Initialize()
     }
     gpBitmapInfo->bmiHeader.biBitCount = 0;
     HDC hBMDC = this->GetDC();
+    VERIFY(hBMDC != NULL);
     HBITMAP hBM = ::CreateCompatibleBitmap(hBMDC, 1, 1);
+    VERIFY(hBM != NULL);
     VERIFY(::GetDIBits(hBMDC, hBM, 0, 1, NULL, gpBitmapInfo, DIB_RGB_COLORS));
 
     if (colorData->bitsperpixel > 8) {
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp
index bc0d6a939fa..92a7720fe78 100644
--- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2024, 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
@@ -35,10 +35,8 @@
 BOOL DWMIsCompositionEnabled();
 
 void initScreens(JNIEnv *env) {
-
     if (!Devices::UpdateInstance(env)) {
         JNU_ThrowInternalError(env, "Could not update the devices array.");
-        return;
     }
 }
 
diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java b/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java
index f71b1bb1400..b7cfa1ef132 100644
--- a/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java
+++ b/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2024, 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
@@ -120,17 +120,15 @@
 public final class Connection implements Runnable {
 
     private static final boolean debug = false;
-    private static final int dump = 0; // > 0 r, > 1 rw
-
 
     private final Thread worker;    // Initialized in constructor
 
-    private boolean v3 = true;       // Set in setV3()
+    private boolean v3 = true;     // Set in setV3()
 
     public final String host;  // used by LdapClient for generating exception messages
-                         // used by StartTlsResponse when creating an SSL socket
+                               // used by StartTlsResponse when creating an SSL socket
     public final int port;     // used by LdapClient for generating exception messages
-                         // used by StartTlsResponse when creating an SSL socket
+                               // used by StartTlsResponse when creating an SSL socket
 
     private boolean bound = false;   // Set in setBound()
 
@@ -319,30 +317,37 @@ private SocketFactory getSocketFactory(String socketFactoryName) throws Exceptio
     }
 
     private Socket createConnectionSocket(String host, int port, SocketFactory factory,
-                                          int connectTimeout) throws Exception {
+                                          int connectTimeout) throws IOException {
         Socket socket = null;
 
+        // if timeout is supplied, try to use unconnected socket for connecting with timeout
         if (connectTimeout > 0) {
-            // create unconnected socket and then connect it if timeout
-            // is supplied
-            InetSocketAddress endpoint =
-                    createInetSocketAddress(host, port);
-            // unconnected socket
-            socket = factory.createSocket();
-            // connect socket with a timeout
-            socket.connect(endpoint, connectTimeout);
             if (debug) {
-                System.err.println("Connection: creating socket with " +
-                        "a connect timeout");
+                System.err.println("Connection: creating socket with a connect timeout");
+            }
+            try {
+                // unconnected socket
+                socket = factory.createSocket();
+            } catch (IOException e) {
+                // unconnected socket is likely not supported by the SocketFactory
+                if (debug) {
+                    System.err.println("Connection: unconnected socket not supported by SocketFactory");
+                }
+            }
+            if (socket != null) {
+                InetSocketAddress endpoint = createInetSocketAddress(host, port);
+                // connect socket with a timeout
+                socket.connect(endpoint, connectTimeout);
             }
         }
+
+        // either no timeout was supplied or unconnected socket did not work
         if (socket == null) {
             // create connected socket
-            socket = factory.createSocket(host, port);
             if (debug) {
-                System.err.println("Connection: creating connected socket with" +
-                        " no connect timeout");
+                System.err.println("Connection: creating connected socket with no connect timeout");
             }
+            socket = factory.createSocket(host, port);
         }
         return socket;
     }
@@ -351,7 +356,7 @@ private Socket createConnectionSocket(String host, int port, SocketFactory facto
     // the SSL handshake following socket connection as part of the timeout.
     // So explicitly set a socket read timeout, trigger the SSL handshake,
     // then reset the timeout.
-    private void initialSSLHandshake(SSLSocket sslSocket , int connectTimeout) throws Exception {
+    private void initialSSLHandshake(SSLSocket sslSocket, int connectTimeout) throws Exception {
 
             if (!IS_HOSTNAME_VERIFICATION_DISABLED) {
                 SSLParameters param = sslSocket.getSSLParameters();
diff --git a/src/java.naming/share/classes/module-info.java b/src/java.naming/share/classes/module-info.java
index f7d0ace806d..09e1093c13a 100644
--- a/src/java.naming/share/classes/module-info.java
+++ b/src/java.naming/share/classes/module-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2024, 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
@@ -36,21 +36,33 @@
  * The following implementation specific environment properties are supported by the
  * default LDAP Naming Service Provider implementation in the JDK:
  * 
    + *
  • {@code java.naming.ldap.factory.socket}: + *
    The value of this environment property specifies the fully + * qualified class name of the socket factory used by the LDAP provider. + * This class must implement the {@link javax.net.SocketFactory} abstract class + * and provide an implementation of the static "getDefault()" method that + * returns an instance of the socket factory. By default the environment + * property is not set. + *
  • *
  • {@code com.sun.jndi.ldap.connect.timeout}: - *
    The value of this property is the string representation - * of an integer representing the connection timeout in - * milliseconds. If the LDAP provider cannot establish a - * connection within that period, it aborts the connection attempt. + *
    The value of this environment property is the string representation + * of an integer specifying the connection timeout in milliseconds. + * If the LDAP provider cannot establish a connection within that period, + * it aborts the connection attempt. * The integer should be greater than zero. An integer less than * or equal to zero means to use the network protocol's (i.e., TCP's) * timeout value. *
    If this property is not specified, the default is to wait * for the connection to be established or until the underlying * network times out. + *
    If a custom socket factory is provided via environment property + * {@code java.naming.ldap.factory.socket} and unconnected sockets + * are not supported, the specified timeout is ignored + * and the provider behaves as if no connection timeout was set. *
  • *
  • {@code com.sun.jndi.ldap.read.timeout}: *
    The value of this property is the string representation - * of an integer representing the read timeout in milliseconds + * of an integer specifying the read timeout in milliseconds * for LDAP operations. If the LDAP provider cannot get a LDAP * response within that period, it aborts the read attempt. The * integer should be greater than zero. An integer less than or diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ConnectionPool.java b/src/java.net.http/share/classes/jdk/internal/net/http/ConnectionPool.java index 6c31b8b87e4..a13aadd07c7 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ConnectionPool.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ConnectionPool.java @@ -103,14 +103,10 @@ public boolean equals(Object obj) { return false; } if (secure && destination != null) { - if (destination.getHostName() != null) { - if (!destination.getHostName().equalsIgnoreCase( - other.destination.getHostName())) { - return false; - } - } else { - if (other.destination.getHostName() != null) - return false; + String hostString = destination.getHostString(); + if (hostString == null || !hostString.equalsIgnoreCase( + other.destination.getHostString())) { + return false; } } return true; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java index 6bd9bad2da5..9f74a70d318 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java @@ -93,9 +93,7 @@ class Http2ClientImpl { */ CompletableFuture getConnectionFor(HttpRequestImpl req, Exchange exchange) { - URI uri = req.uri(); - InetSocketAddress proxy = req.proxy(); - String key = Http2Connection.keyFor(uri, proxy); + String key = Http2Connection.keyFor(req); synchronized (this) { Http2Connection connection = connections.get(key); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java index 59c88e9f099..1aa19eeb16d 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java @@ -402,7 +402,7 @@ private Http2Connection(HttpRequestImpl request, this(connection, h2client, 1, - keyFor(request.uri(), request.proxy())); + keyFor(request)); Log.logTrace("Connection send window size {0} ", windowController.connectionWindowSize()); @@ -534,15 +534,13 @@ static String keyFor(HttpConnection connection) { return keyString(isSecure, proxyAddr, addr.getHostString(), addr.getPort()); } - static String keyFor(URI uri, InetSocketAddress proxy) { - boolean isSecure = uri.getScheme().equalsIgnoreCase("https"); - - String host = uri.getHost(); - int port = uri.getPort(); - return keyString(isSecure, proxy, host, port); + static String keyFor(final HttpRequestImpl request) { + final InetSocketAddress targetAddr = request.getAddress(); + final InetSocketAddress proxy = request.proxy(); + final boolean secure = request.secure(); + return keyString(secure, proxy, targetAddr.getHostString(), targetAddr.getPort()); } - // Compute the key for an HttpConnection in the Http2ClientImpl pool: // The key string follows one of the three forms below: // {C,S}:H:host:port diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java index 1d2414c1a1a..c97a950c4eb 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java @@ -532,8 +532,8 @@ public int available() throws IOException { if (available != 0) return available; Iterator iterator = currentListItr; if (iterator != null && iterator.hasNext()) return 1; - if (buffers.isEmpty()) return 0; - return 1; + if (!buffers.isEmpty() && buffers.peek() != LAST_LIST ) return 1; + return available; } @Override diff --git a/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp b/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp index 5386e4afdd3..c16fd791e5b 100644 --- a/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp +++ b/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, 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 @@ -82,6 +82,22 @@ AccessBridgeJavaEntryPoints::~AccessBridgeJavaEntryPoints() { return (returnVal); \ } +#define EXCEPTION_CHECK_WITH_RELEASE(situationDescription, returnVal, js, stringBytes) \ + if (exception = jniEnv->ExceptionOccurred()) { \ + PrintDebugString("[ERROR]: *** Exception occured while doing: %s - call to GetStringLength; returning %d", situationDescription, returnVal); \ + jniEnv->ExceptionDescribe(); \ + jniEnv->ExceptionClear(); \ + jniEnv->ReleaseStringChars(js, stringBytes); \ + return (returnVal); \ + } \ + jniEnv->ReleaseStringChars(js, stringBytes); \ + if (exception = jniEnv->ExceptionOccurred()) { \ + PrintDebugString("[ERROR]: *** Exception occured while doing: %s - call to ReleaseStringChars; returning %d", situationDescription, returnVal); \ + jniEnv->ExceptionDescribe(); \ + jniEnv->ExceptionClear(); \ + return (returnVal); \ + } + #define EXCEPTION_CHECK_VOID(situationDescription) \ if (exception = jniEnv->ExceptionOccurred()) { \ PrintDebugString("[ERROR]: *** Exception occured while doing: %s", situationDescription); \ @@ -1215,9 +1231,7 @@ AccessBridgeJavaEntryPoints::getVirtualAccessibleName ( EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE); wcsncpy(name, stringBytes, nameSize - 1); length = jniEnv->GetStringLength(js); - EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleName", FALSE, js, stringBytes); jniEnv->CallVoidMethod ( accessBridgeObject, decrementReferenceMethod, js); @@ -1380,9 +1394,7 @@ AccessBridgeJavaEntryPoints::getTextAttributesInRange(const jobject accessibleCo length = jniEnv->GetStringLength(js); test_attributes.fullAttributesString[length < (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t)) ? length : (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleAttributesAtIndex", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE); @@ -1735,11 +1747,9 @@ AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE); wcsncpy(info->name, stringBytes, (sizeof(info->name) / sizeof(wchar_t))); length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleName", FALSE, js, stringBytes); info->name[length < (sizeof(info->name) / sizeof(wchar_t)) ? length : (sizeof(info->name) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE); @@ -1767,11 +1777,9 @@ AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE); wcsncpy(info->description, stringBytes, (sizeof(info->description) / sizeof(wchar_t))); length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleName", FALSE, js, stringBytes); info->description[length < (sizeof(info->description) / sizeof(wchar_t)) ? length : (sizeof(info->description) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE); @@ -1799,11 +1807,9 @@ AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, EXCEPTION_CHECK("Getting AccessibleRole - call to GetStringChars()", FALSE); wcsncpy(info->role, stringBytes, (sizeof(info->role) / sizeof(wchar_t))); length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleRole", FALSE, js, stringBytes); info->role[length < (sizeof(info->role) / sizeof(wchar_t)) ? length : (sizeof(info->role) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleRole - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleRole - call to ReleaseStringChars()", FALSE); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleRole - call to CallVoidMethod()", FALSE); @@ -1831,11 +1837,9 @@ AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to GetStringChars()", FALSE); wcsncpy(info->role_en_US, stringBytes, (sizeof(info->role_en_US) / sizeof(wchar_t))); length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleRole_en_US", FALSE, js, stringBytes); info->role_en_US[length < (sizeof(info->role_en_US) / sizeof(wchar_t)) ? length : (sizeof(info->role_en_US) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to ReleaseStringChars()", FALSE); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to CallVoidMethod()", FALSE); @@ -1862,11 +1866,9 @@ AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, EXCEPTION_CHECK("Getting AccessibleState - call to GetStringChars()", FALSE); wcsncpy(info->states, stringBytes, (sizeof(info->states) / sizeof(wchar_t))); length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleState", FALSE, js, stringBytes); info->states[length < (sizeof(info->states) / sizeof(wchar_t)) ? length : (sizeof(info->states) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleState - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleState - call to ReleaseStringChars()", FALSE); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleState - call to CallVoidMethod()", FALSE); @@ -1893,11 +1895,9 @@ AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, EXCEPTION_CHECK("Getting AccessibleState_en_US - call to GetStringChars()", FALSE); wcsncpy(info->states_en_US, stringBytes, (sizeof(info->states_en_US) / sizeof(wchar_t))); length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleState_en_US", FALSE, js, stringBytes); info->states_en_US[length < (sizeof(info->states_en_US) / sizeof(wchar_t)) ? length : (sizeof(info->states_en_US) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleState_en_US - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleState_en_US - call to ReleaseStringChars()", FALSE); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleState_en_US - call to CallVoidMethod()", FALSE); @@ -2809,11 +2809,9 @@ AccessBridgeJavaEntryPoints::getAccessibleRelationSet(jobject accessibleContext, EXCEPTION_CHECK("Getting AccessibleRelation key - call to GetStringChars()", FALSE); wcsncpy(relationSet->relations[i].key, stringBytes, (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t))); length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleRelation key", FALSE, js, stringBytes); relationSet->relations[i].key [length < (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t)) ? length : (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleRelation key - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleRelation key - call to ReleaseStringChars()", FALSE); // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleRelation key - call to CallVoidMethod()", FALSE); @@ -2915,9 +2913,7 @@ AccessBridgeJavaEntryPoints::getAccessibleHypertext(jobject accessibleContext, length = (sizeof(hypertext->links[i].text) / sizeof(wchar_t)) - 2; } hypertext->links[i].text[length] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleHyperlink text", FALSE, js, stringBytes); // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE); @@ -3052,9 +3048,7 @@ AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(const jobject accessibleC length = (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t)) - 2; } hypertext->links[bufIndex].text[length] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleHyperlink text", FALSE, js, stringBytes); // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE); @@ -3171,9 +3165,7 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleHyperlink(jobject hypertext, length = (sizeof(info->text) / sizeof(wchar_t)) - 2; } info->text[length] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleHyperlink text", FALSE, js, stringBytes); // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE); @@ -3300,9 +3292,7 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleIcons(jobject accessibleContext, length = (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t)) - 2; } icons->iconInfo[i].description[length] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleIcon description - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleIcon description - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleIcon description", FALSE, js, stringBytes); // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleIcon description - call to CallVoidMethod()", FALSE); @@ -3379,9 +3369,7 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleActions(jobject accessibleContext length = (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t)) - 2; } actions->actionInfo[i].name [length] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleAction name - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleAction name - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleAction name", FALSE, js, stringBytes); // jniEnv->CallVoidMethod(accessBridgeObject, // decrementReferenceMethod, js); //EXCEPTION_CHECK("Getting AccessibleAction name - call to CallVoidMethod()", FALSE); @@ -3561,9 +3549,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextItems(jobject accessibleContext, length = jniEnv->GetStringLength(js); textItems->word[length < (sizeof(textItems->word) / sizeof(wchar_t)) ? length : (sizeof(textItems->word) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleWordAtIndex", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallVoidMethod()", FALSE); @@ -3597,9 +3583,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextItems(jobject accessibleContext, } else { textItems->sentence[(sizeof(textItems->sentence) / sizeof(wchar_t))-2] = (wchar_t) 0; } - EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleSentenceAtIndex", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallVoidMethod()", FALSE); @@ -3673,9 +3657,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(jobject accessibleCo length = jniEnv->GetStringLength(js); selectionInfo->selectedText[length < (sizeof(selectionInfo->selectedText) / sizeof(wchar_t)) ? length : (sizeof(selectionInfo->selectedText) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleTextSelectedText", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallVoidMethod()", FALSE); @@ -3890,9 +3872,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(jobject accessibleConte length = jniEnv->GetStringLength(js); attributes->backgroundColor[length < (sizeof(attributes->backgroundColor) / sizeof(wchar_t)) ? length : (sizeof(attributes->backgroundColor) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting BackgroundColorFromAttributeSet", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -3927,9 +3907,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(jobject accessibleConte length = jniEnv->GetStringLength(js); attributes->foregroundColor[length < (sizeof(attributes->foregroundColor) / sizeof(wchar_t)) ? length : (sizeof(attributes->foregroundColor) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting ForegroundColorFromAttributeSet", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -3964,9 +3942,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(jobject accessibleConte length = jniEnv->GetStringLength(js); attributes->fontFamily[length < (sizeof(attributes->fontFamily) / sizeof(wchar_t)) ? length : (sizeof(attributes->fontFamily) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting FontFamilyFromAttributeSet", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE); @@ -4170,9 +4146,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(jobject accessibleConte length = jniEnv->GetStringLength(js); attributes->fullAttributesString[length < (sizeof(attributes->fullAttributesString) / sizeof(wchar_t)) ? length : (sizeof(attributes->fullAttributesString) / sizeof(wchar_t))-2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleAttributesAtIndex", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE); @@ -4413,9 +4387,7 @@ AccessBridgeJavaEntryPoints::getAccessibleTextRange(jobject accessibleContext, PrintDebugString("[INFO]: Accessible Text stringBytes length = %d", length); text[length < len ? length : len - 2] = (wchar_t) 0; wPrintDebugString(L"[INFO]: Accessible Text 'text' after null termination = %ls", text); - EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting AccessibleTextRange - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting AccessibleTextRange", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallVoidMethod()", FALSE); @@ -4458,9 +4430,7 @@ AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(jobject access wcsncpy(value, stringBytes, len); length = jniEnv->GetStringLength(js); value[length < len ? length : len - 2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting CurrentAccessibleValue", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallVoidMethod()", FALSE); @@ -4501,9 +4471,7 @@ AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(jobject access wcsncpy(value, stringBytes, len); length = jniEnv->GetStringLength(js); value[length < len ? length : len - 2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting MaximumAccessibleValue", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallVoidMethod()", FALSE); @@ -4544,9 +4512,7 @@ AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(jobject access wcsncpy(value, stringBytes, len); length = jniEnv->GetStringLength(js); value[length < len ? length : len - 2] = (wchar_t) 0; - EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to GetStringLength()", FALSE); - jniEnv->ReleaseStringChars(js, stringBytes); - EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to ReleaseStringChars()", FALSE); + EXCEPTION_CHECK_WITH_RELEASE("Getting MinimumAccessibleValue", FALSE, js, stringBytes); jniEnv->CallVoidMethod(accessBridgeObject, decrementReferenceMethod, js); EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallVoidMethod()", FALSE); diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java index 8a309549e3a..9e77ee726fb 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java @@ -261,10 +261,8 @@ protected void engineSetPadding(String padding) // no native padding support; use our own padding impl paddingObj = new PKCS5Padding(blockSize); padBuffer = new byte[blockSize]; - char[] tokenLabel = token.tokenInfo.label; // NSS requires block-sized updates in multi-part operations. - reqBlockUpdates = ((tokenLabel[0] == 'N' && tokenLabel[1] == 'S' - && tokenLabel[2] == 'S') ? true : false); + reqBlockUpdates = P11Util.isNSS(token); } } else { throw new NoSuchPaddingException("Unsupported padding " + padding); diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java index 39bd783dd25..d12244337a5 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java @@ -139,9 +139,7 @@ abstract class P11Key implements Key, Length { this.tokenObject = tokenObject; this.sensitive = sensitive; this.extractable = extractable; - char[] tokenLabel = this.token.tokenInfo.label; - isNSS = (tokenLabel[0] == 'N' && tokenLabel[1] == 'S' - && tokenLabel[2] == 'S'); + isNSS = P11Util.isNSS(this.token); boolean extractKeyInfo = (!DISABLE_NATIVE_KEYS_EXTRACTION && isNSS && extractable && !tokenObject); this.keyIDHolder = new NativeKeyHolder(this, keyID, session, @@ -395,8 +393,9 @@ static PrivateKey privateKey(Session session, long keyID, String algorithm, new CK_ATTRIBUTE(CKA_EXTRACTABLE), }); - boolean keySensitive = (attrs[0].getBoolean() || - attrs[1].getBoolean() || !attrs[2].getBoolean()); + boolean keySensitive = + (attrs[0].getBoolean() && P11Util.isNSS(session.token)) || + attrs[1].getBoolean() || !attrs[2].getBoolean(); switch (algorithm) { case "RSA": diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java index 262cfc062ad..cabee449346 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java @@ -44,6 +44,15 @@ private P11Util() { // empty } + static boolean isNSS(Token token) { + char[] tokenLabel = token.tokenInfo.label; + if (tokenLabel != null && tokenLabel.length >= 3) { + return (tokenLabel[0] == 'N' && tokenLabel[1] == 'S' + && tokenLabel[2] == 'S'); + } + return false; + } + static Provider getSunProvider() { Provider p = sun; if (p == null) { diff --git a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKey.java b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKey.java index fe0fac5f10a..801d2ad0b59 100644 --- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKey.java +++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKey.java @@ -75,10 +75,14 @@ protected void finalize() throws Throwable { protected final String algorithm; - protected CKey(String algorithm, NativeHandles handles, int keyLength) { + private final boolean isPublic; + + protected CKey(String algorithm, NativeHandles handles, int keyLength, + boolean isPublic) { this.algorithm = algorithm; this.handles = handles; this.keyLength = keyLength; + this.isPublic = isPublic; } // Native method to cleanup the key handle. @@ -101,6 +105,18 @@ public String getAlgorithm() { return algorithm; } + public String toString() { + String typeStr; + if (handles.hCryptKey != 0) { + typeStr = getKeyType(handles.hCryptKey) + ", container=" + + getContainerName(handles.hCryptProv); + } else { + typeStr = "CNG"; + } + return algorithm + " " + (isPublic ? "PublicKey" : "PrivateKey") + + " [size=" + keyLength + " bits, type=" + typeStr + "]"; + } + protected native static String getContainerName(long hCryptProv); protected native static String getKeyType(long hCryptKey); diff --git a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPrivateKey.java b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPrivateKey.java index 91a7775b8bd..c3882616615 100644 --- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPrivateKey.java +++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPrivateKey.java @@ -42,7 +42,7 @@ class CPrivateKey extends CKey implements PrivateKey { private static final long serialVersionUID = 8113152807912338063L; private CPrivateKey(String alg, NativeHandles handles, int keyLength) { - super(alg, handles, keyLength); + super(alg, handles, keyLength, false); } // Called by native code inside security.cpp @@ -65,16 +65,6 @@ public byte[] getEncoded() { return null; } - public String toString() { - if (handles.hCryptKey != 0) { - return algorithm + "PrivateKey [size=" + keyLength + " bits, type=" + - getKeyType(handles.hCryptKey) + ", container=" + - getContainerName(handles.hCryptProv) + "]"; - } else { - return algorithm + "PrivateKey [size=" + keyLength + " bits, type=CNG]"; - } - } - // This class is not serializable @java.io.Serial private void writeObject(java.io.ObjectOutputStream out) diff --git a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPublicKey.java b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPublicKey.java index efbd74c5bb8..7f02aa5c651 100644 --- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPublicKey.java +++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPublicKey.java @@ -113,9 +113,8 @@ public ECParameterSpec getParams() { } public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(algorithm).append("PublicKey [size=").append(keyLength) - .append("]\n ECPoint: ").append(getW()) + StringBuffer sb = new StringBuffer(super.toString()); + sb.append("\n ECPoint: ").append(getW()) .append("\n params: ").append(getParams()); return sb.toString(); } @@ -134,16 +133,8 @@ public static class CRSAPublicKey extends CPublicKey implements RSAPublicKey { } public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(algorithm).append("PublicKey [size=").append(keyLength) - .append(" bits, type="); - if (handles.hCryptKey != 0) { - sb.append(getKeyType(handles.hCryptKey)) - .append(", container=").append(getContainerName(handles.hCryptProv)); - } else { - sb.append("CNG"); - } - sb.append("]\n modulus: ").append(getModulus()) + StringBuffer sb = new StringBuffer(super.toString()); + sb.append("\n modulus: ").append(getModulus()) .append("\n public exponent: ").append(getPublicExponent()); return sb.toString(); } @@ -214,7 +205,7 @@ public static CPublicKey of( protected CPublicKey( String alg, NativeHandles handles, int keyLength) { - super(alg, handles, keyLength); + super(alg, handles, keyLength, true); } @Override diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/ArenaAllocator.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/ArenaAllocator.java index c4d56a22a53..8a8474a3be5 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/ArenaAllocator.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/ArenaAllocator.java @@ -1,3 +1,28 @@ +/* + * Copyright (c) 2021, 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 jdk.internal.foreign; import jdk.incubator.foreign.MemorySegment; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Table.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Table.java index 25f7e98f4f2..8ffeae0ab1a 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Table.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Table.java @@ -402,7 +402,6 @@ private Content toContent() { int tabIndex = 0; tablist.add(createTab(HtmlIds.forTab(id, tabIndex), activeTabStyle, true, defaultTab)); - table.put(HtmlAttr.ARIA_LABELLEDBY, HtmlIds.forTab(id, tabIndex).name()); for (Content tabLabel : tabMap.keySet()) { tabIndex++; if (tabs.contains(tabLabel)) { @@ -415,7 +414,8 @@ private Content toContent() { } HtmlTree tabpanel = new HtmlTree(TagName.DIV) .setId(HtmlIds.forTabPanel(id)) - .put(HtmlAttr.ROLE, "tabpanel"); + .put(HtmlAttr.ROLE, "tabpanel") + .put(HtmlAttr.ARIA_LABELLEDBY, HtmlIds.forTab(id, 0).name()); table.add(getTableBody()); tabpanel.add(table); main.add(tablist); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/script.js b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/script.js index 864989cf45f..73cd8faac91 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/script.js +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/script.js @@ -63,7 +63,7 @@ function show(tableId, selected, columns) { } function updateTabs(tableId, selected) { - document.querySelector('div#' + tableId +' .summary-table') + document.getElementById(tableId + '.tabpanel') .setAttribute('aria-labelledby', selected); document.querySelectorAll('button[id^="' + tableId + '"]') .forEach(function(tab, index) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveSettingEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveSettingEvent.java index a3ca39194e0..7610ea07797 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveSettingEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveSettingEvent.java @@ -37,13 +37,6 @@ @StackTrace(false) public final class ActiveSettingEvent extends AbstractJDKEvent { - public static final ThreadLocal EVENT = new ThreadLocal() { - @Override - protected ActiveSettingEvent initialValue() { - return new ActiveSettingEvent(); - } - }; - @Label("Event Id") public long id; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java index 3ef0948a8b3..585218c97fe 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java @@ -290,13 +290,13 @@ void writeActiveSettingEvent() { if (!type.isRegistered()) { return; } - ActiveSettingEvent event = ActiveSettingEvent.EVENT.get(); for (NamedControl nc : namedControls) { if (Utils.isSettingVisible(nc.control, type.hasEventHook())) { String value = nc.control.getLastValue(); if (value == null) { value = nc.control.getDefaultValue(); } + ActiveSettingEvent event = new ActiveSettingEvent(); event.id = type.getId(); event.name = nc.name; event.value = value; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java index 8358825b16e..a71f813ee21 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java @@ -144,7 +144,7 @@ public synchronized EventType register(Class handler.setRegistered(true); typeLibrary.addType(handler.getPlatformEventType()); if (jvm.isRecording()) { - settingsManager.setEventControl(handler.getEventControl()); + settingsManager.setEventControl(handler.getEventControl(), true); settingsManager.updateRetransform(Collections.singletonList((eventClass))); } setStaleMetadata(); @@ -199,8 +199,8 @@ private EventHandler makeHandler(Class event } - public synchronized void setSettings(List> list) { - settingsManager.setSettings(list); + public synchronized void setSettings(List> list, boolean writeSettingEvents) { + settingsManager.setSettings(list, writeSettingEvents); } synchronized void disableEvents() { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java index dfa9c962b31..6b1a4f0c879 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java @@ -256,7 +256,7 @@ synchronized long start(PlatformRecording recording) { currentChunk.setStartTime(startTime); } recording.setState(RecordingState.RUNNING); - updateSettings(); + updateSettings(false); recording.setStartTime(startTime); writeMetaEvents(); } else { @@ -275,7 +275,7 @@ synchronized long start(PlatformRecording recording) { startTime = Utils.epochNanosToInstant(startNanos); recording.setStartTime(startTime); recording.setState(RecordingState.RUNNING); - updateSettings(); + updateSettings(false); writeMetaEvents(); if (currentChunk != null) { finishChunk(currentChunk, startTime, recording); @@ -339,7 +339,7 @@ synchronized void stop(PlatformRecording recording) { } else { RepositoryChunk newChunk = null; RequestEngine.doChunkEnd(); - updateSettingsButIgnoreRecording(recording); + updateSettingsButIgnoreRecording(recording, false); String path = null; if (toDisk) { @@ -383,11 +383,11 @@ private void disableEvents() { MetadataRepository.getInstance().disableEvents(); } - void updateSettings() { - updateSettingsButIgnoreRecording(null); + void updateSettings(boolean writeSettingEvents) { + updateSettingsButIgnoreRecording(null, writeSettingEvents); } - void updateSettingsButIgnoreRecording(PlatformRecording ignoreMe) { + void updateSettingsButIgnoreRecording(PlatformRecording ignoreMe, boolean writeSettingEvents) { List recordings = getRunningRecordings(); List> list = new ArrayList<>(recordings.size()); for (PlatformRecording r : recordings) { @@ -395,7 +395,7 @@ void updateSettingsButIgnoreRecording(PlatformRecording ignoreMe) { list.add(r.getSettings()); } } - MetadataRepository.getInstance().setSettings(list); + MetadataRepository.getInstance().setSettings(list, writeSettingEvents); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java index 9ae3769b6e4..104e8bdbfdb 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java @@ -468,7 +468,7 @@ public void setSetting(String id, String value) { synchronized (recorder) { this.settings.put(id, value); if (getState() == RecordingState.RUNNING) { - recorder.updateSettings(); + recorder.updateSettings(true); } } } @@ -489,7 +489,7 @@ private void setSettings(Map settings, boolean update) { synchronized (recorder) { this.settings = new LinkedHashMap<>(settings); if (getState() == RecordingState.RUNNING && update) { - recorder.updateSettings(); + recorder.updateSettings(true); } } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/SettingsManager.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/SettingsManager.java index db239b980e5..3be5e8ef308 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/SettingsManager.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/SettingsManager.java @@ -130,7 +130,7 @@ public void finish() { private Map availableSettings = new LinkedHashMap<>(); - void setSettings(List> activeSettings) { + void setSettings(List> activeSettings, boolean writeSettingEvents) { // store settings so they are available if a new event class is loaded availableSettings = createSettingsMap(activeSettings); List eventControls = MetadataRepository.getInstance().getEventControls(); @@ -143,7 +143,7 @@ void setSettings(List> activeSettings) { Collections.sort(eventControls, (x,y) -> x.getEventType().getName().compareTo(y.getEventType().getName())); } for (EventControl ec : eventControls) { - setEventControl(ec); + setEventControl(ec, writeSettingEvents); } } if (JVM.getJVM().getAllowedToDoEventRetransforms()) { @@ -211,7 +211,7 @@ private Collection makeInternalSettings(Map rec return internals.values(); } - void setEventControl(EventControl ec) { + void setEventControl(EventControl ec, boolean writeSettingEvents) { InternalSetting is = getInternalSetting(ec); boolean shouldLog = Logger.shouldLog(LogTag.JFR_SETTING, LogLevel.INFO); if (shouldLog) { @@ -250,7 +250,9 @@ void setEventControl(EventControl ec) { } } } - ec.writeActiveSettingEvent(); + if (writeSettingEvents) { + ec.writeActiveSettingEvent(); + } if (shouldLog) { Logger.log(LogTag.JFR_SETTING, LogLevel.INFO, "}"); } diff --git a/src/jdk.jfr/share/conf/jfr/default.jfc b/src/jdk.jfr/share/conf/jfr/default.jfc index 9c265eba45a..aeab7991701 100644 --- a/src/jdk.jfr/share/conf/jfr/default.jfc +++ b/src/jdk.jfr/share/conf/jfr/default.jfc @@ -411,6 +411,10 @@ true + + true + + true @@ -864,10 +868,10 @@ - diff --git a/src/jdk.jfr/share/conf/jfr/profile.jfc b/src/jdk.jfr/share/conf/jfr/profile.jfc index dd2708d52a9..b4943a3f435 100644 --- a/src/jdk.jfr/share/conf/jfr/profile.jfc +++ b/src/jdk.jfr/share/conf/jfr/profile.jfc @@ -349,7 +349,7 @@ true 0 ms - true + true @@ -411,6 +411,10 @@ true + + true + + true @@ -864,10 +868,10 @@ - diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java index 8989a28ca1a..b1c0caef51b 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, 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 @@ -86,8 +86,9 @@ static final class DefaultExecutableImage implements ExecutableImage { private final Path home; private final List args; private final Set modules; + private final Platform platform; - DefaultExecutableImage(Path home, Set modules) { + DefaultExecutableImage(Path home, Set modules, Platform p) { Objects.requireNonNull(home); if (!Files.exists(home)) { throw new IllegalArgumentException("Invalid image home"); @@ -95,6 +96,7 @@ static final class DefaultExecutableImage implements ExecutableImage { this.home = home; this.modules = Collections.unmodifiableSet(modules); this.args = createArgs(home); + this.platform = p; } private static List createArgs(Path home) { @@ -127,13 +129,18 @@ public void storeLaunchArgs(List args) { throw new UncheckedIOException(ex); } } + + @Override + public Platform getTargetPlatform() { + return platform; + } } private final Path root; private final Map launchers; private final Path mdir; private final Set modules = new HashSet<>(); - private Platform targetPlatform; + private Platform platform; /** * Default image builder constructor. @@ -148,6 +155,11 @@ public DefaultImageBuilder(Path root, Map launchers) throws IOEx Files.createDirectories(mdir); } + @Override + public Platform getTargetPlatform() { + return platform; + } + @Override public void storeFiles(ResourcePool files) { try { @@ -158,7 +170,7 @@ public void storeFiles(ResourcePool files) { if (value == null) { throw new PluginException("ModuleTarget attribute is missing for java.base module"); } - this.targetPlatform = Platform.toPlatform(value); + this.platform = Platform.parsePlatform(value); checkResourcePool(files); @@ -474,7 +486,7 @@ private String nativeDir(String filename) { } private boolean isWindows() { - return targetPlatform == Platform.WINDOWS; + return platform.os() == Platform.OperatingSystem.WINDOWS; } /** @@ -509,7 +521,7 @@ private void setReadOnly(Path file) { @Override public ExecutableImage getExecutableImage() { - return new DefaultExecutableImage(root, modules); + return new DefaultExecutableImage(root, modules, platform); } // This is experimental, we should get rid-off the scripts in a near future @@ -551,7 +563,10 @@ public static ExecutableImage getExecutableImage(Path root) { Path binDir = root.resolve(BIN_DIRNAME); if (Files.exists(binDir.resolve("java")) || Files.exists(binDir.resolve("java.exe"))) { - return new DefaultExecutableImage(root, retrieveModules(root)); + // It may be possible to extract the platform info from the given image. + // --post-process-path is a hidden option and pass unknown platform for now. + // --generate-cds-archive plugin cannot be used with --post-process-path option. + return new DefaultExecutableImage(root, retrieveModules(root), Platform.UNKNOWN); } return null; } diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java index 9ebc6211fc3..32440d5ba7f 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, 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 @@ -28,6 +28,7 @@ import java.util.Properties; import jdk.tools.jlink.internal.ExecutableImage; +import jdk.tools.jlink.internal.Platform; import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.plugin.ResourcePool; @@ -74,4 +75,13 @@ public default void storeFiles(ResourcePool content) { * @throws PluginException */ public ExecutableImage getExecutableImage(); + + /** + * Gets the platform of the image. + * + * @return {@code Platform} object representing the platform of the image + */ + public default Platform getTargetPlatform() { + return Platform.UNKNOWN; + } } diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ExecutableImage.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ExecutableImage.java index 1e788e0ce1d..6169cb8e44a 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ExecutableImage.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ExecutableImage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, 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 @@ -61,4 +61,11 @@ public interface ExecutableImage { * @param args Additional arguments */ public void storeLaunchArgs(List args); + + /** + * The Platform of the image. + * + * @return Platform + */ + public Platform getTargetPlatform(); } diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Platform.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Platform.java index c3ea6fb1647..a08678455c6 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Platform.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Platform.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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,48 +24,112 @@ */ package jdk.tools.jlink.internal; -import jdk.tools.jlink.plugin.ResourcePoolModule; - import java.util.Locale; /** * Supported platforms */ -public enum Platform { - WINDOWS, - LINUX, - MACOS, - AIX, - UNKNOWN; +public record Platform(OperatingSystem os, Architecture arch) { - /** - * Returns the {@code Platform} derived from the target platform - * in the {@code ModuleTarget} attribute. + public enum OperatingSystem { + WINDOWS, + LINUX, + MACOS, + AIX, + UNKNOWN; + } + + public enum Architecture { + X86, + x64, + ARM, + AARCH64, + UNKNOWN; + } + + public static final Platform UNKNOWN = new Platform(OperatingSystem.UNKNOWN, Architecture.UNKNOWN); + + /* + * Returns the {@code Platform} based on the platformString of the form -. */ - public static Platform toPlatform(String targetPlatform) { + public static Platform parsePlatform(String platformString) { String osName; - int index = targetPlatform.indexOf("-"); + String archName; + int index = platformString.indexOf("-"); if (index < 0) { - osName = targetPlatform; + osName = platformString; + archName = "UNKNOWN"; } else { - osName = targetPlatform.substring(0, index); + osName = platformString.substring(0, index); + archName = platformString.substring(index + 1); } + OperatingSystem os; try { - return Platform.valueOf(osName.toUpperCase(Locale.ENGLISH)); + os = OperatingSystem.valueOf(osName.toUpperCase(Locale.ENGLISH)); } catch (IllegalArgumentException e) { - return Platform.UNKNOWN; + os = OperatingSystem.UNKNOWN; } + Architecture arch = toArch(archName); + return new Platform(os, arch); } /** - * Returns the {@code Platform} to which the given module is target to. + * @return true is it's a 64-bit platform */ - public static Platform getTargetPlatform(ResourcePoolModule module) { - String targetPlatform = module.targetPlatform(); - if (targetPlatform != null) { - return toPlatform(targetPlatform); - } else { - return Platform.UNKNOWN; - } + public boolean is64Bit() { + return (arch() == Platform.Architecture.x64 || + arch() == Platform.Architecture.AARCH64); + } + + /** + * Returns the runtime {@code Platform}. + */ + public static Platform runtime() { + return new Platform(runtimeOS(), runtimeArch()); + } + + /** + * Returns a {@code String} representation of a {@code Platform} in the format of - + */ + @Override + public String toString() { + return os.toString().toLowerCase() + "-" + arch.toString().toLowerCase(); + } + + /** + * Returns the runtime {@code Platform.OperatingSystem}. + */ + private static OperatingSystem runtimeOS() { + String osName = System.getProperty("os.name").substring(0, 3).toLowerCase(); + OperatingSystem os = switch (osName) { + case "win" -> OperatingSystem.WINDOWS; + case "lin" -> OperatingSystem.LINUX; + case "mac" -> OperatingSystem.MACOS; + case "aix" -> OperatingSystem.AIX; + default -> OperatingSystem.UNKNOWN; + }; + return os; + } + + /** + * Returns the runtime {@code Platform.Architechrure}. + */ + private static Architecture runtimeArch() { + String archName = System.getProperty("os.arch"); + return toArch(archName); + } + + /** + * Returns the {@code Platform.Architecture} based on the archName. + */ + private static Architecture toArch(String archName) { + Architecture arch = switch (archName) { + case "x86" -> Architecture.X86; + case "amd64", "x86_64" -> Architecture.x64; + case "arm" -> Architecture.ARM; + case "aarch64" -> Architecture.AARCH64; + default -> Architecture.UNKNOWN; + }; + return arch; } } diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/CDSPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/CDSPlugin.java new file mode 100644 index 00000000000..a1bee72c255 --- /dev/null +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/CDSPlugin.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2021, 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 jdk.tools.jlink.internal.plugins; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; + +import jdk.tools.jlink.internal.ExecutableImage; +import jdk.tools.jlink.internal.Platform; +import jdk.tools.jlink.internal.PostProcessor; +import jdk.tools.jlink.plugin.PluginException; +import jdk.tools.jlink.plugin.ResourcePool; +import jdk.tools.jlink.plugin.ResourcePoolBuilder; + +/** + * + * CDS plugin + */ +public final class CDSPlugin extends AbstractPlugin implements PostProcessor { + private static final String NAME = "generate-cds-archive"; + private Platform targetPlatform; + private Platform runtimePlatform; + + public CDSPlugin() { + super(NAME); + } + + + private String javaExecutableName() { + if (targetPlatform.os() == Platform.OperatingSystem.WINDOWS) { + return "java.exe"; + } else { + return "java"; + } + } + + private void generateCDSArchive(ExecutableImage image, boolean noCoops) { + List javaCmd = new ArrayList(); + Path javaPath = image.getHome().resolve("bin").resolve(javaExecutableName()); + if (!Files.exists(javaPath)) { + throw new PluginException("Cannot find java executable at: " + javaPath.toString()); + } + javaCmd.add(javaPath.toString()); + javaCmd.add("-Xshare:dump"); + String archiveMsg = "CDS"; + if (noCoops) { + javaCmd.add("-XX:-UseCompressedOops"); + archiveMsg += "-NOCOOPS"; + } + ProcessBuilder builder = new ProcessBuilder(javaCmd); + int status = -1; + try { + Process p = builder.inheritIO().start(); + status = p.waitFor(); + } catch (InterruptedException | IOException e) { + throw new PluginException(e); + } + + if (status != 0) { + throw new PluginException("Failed creating " + archiveMsg + " archive!"); + } + } + + @Override + public List process(ExecutableImage image) { + targetPlatform = image.getTargetPlatform(); + runtimePlatform = Platform.runtime(); + + if (!targetPlatform.equals(runtimePlatform)) { + throw new PluginException("Cannot generate CDS archives: target image platform " + + targetPlatform.toString() + " is different from runtime platform " + + runtimePlatform.toString()); + } + + Path classListPath = image.getHome().resolve("lib").resolve("classlist"); + if (Files.exists(classListPath)) { + generateCDSArchive(image,false); + + if (targetPlatform.is64Bit()) { + generateCDSArchive(image,true); + } + System.out.println("Created CDS archive successfully"); + } else { + throw new PluginException("Cannot generate CDS archives: classlist not found: " + + classListPath.toString()); + } + return null; + } + + @Override + public Category getType() { + return Category.PROCESSOR; + } + + @Override + public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) { + return in; + } +} diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java index cdd0167eb6e..a9cc357787a 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, 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 @@ -245,8 +245,9 @@ private ResourcePoolEntry handleJvmCfgFile(ResourcePoolEntry orig, } private static String[] jvmlibs(ResourcePoolModule module) { - Platform platform = Platform.getTargetPlatform(module); - switch (platform) { + String targetPlatform = module.targetPlatform(); + Platform platform = Platform.parsePlatform(targetPlatform); + switch (platform.os()) { case WINDOWS: return new String[] { "jvm.dll" }; case MACOS: diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties index d49dd1d38bd..958c43c2ca4 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2021, 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 @@ -137,6 +137,13 @@ exclude-jmod-section.usage=\ \ Specify a JMOD section to exclude.\n\ \ Where is \"man\" or \"headers\". + +generate-cds-archive.description=\ +CDS plugin: generate cds archives if the runtime image supports CDS feature.\n\ + +generate-cds-archive.usage=\ +\ --generate-cds-archive Generate CDS archives if the runtime image supports CDS feature. + generate-jli-classes.argument=@filename generate-jli-classes.description=\ diff --git a/src/jdk.jlink/share/classes/module-info.java b/src/jdk.jlink/share/classes/module-info.java index 3d097772e77..d2db4c5f9e4 100644 --- a/src/jdk.jlink/share/classes/module-info.java +++ b/src/jdk.jlink/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, 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 @@ -76,6 +76,7 @@ jdk.tools.jlink.internal.plugins.AddOptionsPlugin, jdk.tools.jlink.internal.plugins.VendorBugURLPlugin, jdk.tools.jlink.internal.plugins.VendorVMBugURLPlugin, - jdk.tools.jlink.internal.plugins.VendorVersionPlugin; + jdk.tools.jlink.internal.plugins.VendorVersionPlugin, + jdk.tools.jlink.internal.plugins.CDSPlugin; } diff --git a/test/failure_handler/src/share/conf/mac.properties b/test/failure_handler/src/share/conf/mac.properties index df68fc29efc..bc90ff81d8c 100644 --- a/test/failure_handler/src/share/conf/mac.properties +++ b/test/failure_handler/src/share/conf/mac.properties @@ -103,7 +103,7 @@ system.sysctl.args=-a process.ps.app=ps process.ps.args=-Meo pid,pcpu,cputime,start,pmem,vsz,rss,state,wchan,user,args process.top.app=top -process.top.args=-l 1 +process.top.args=-l 2 memory.vmstat.app=vm_stat memory.vmstat.args=-c 3 3 diff --git a/test/hotspot/gtest/runtime/test_os.cpp b/test/hotspot/gtest/runtime/test_os.cpp index 017f4c10875..0c9de336196 100644 --- a/test/hotspot/gtest/runtime/test_os.cpp +++ b/test/hotspot/gtest/runtime/test_os.cpp @@ -500,7 +500,9 @@ struct NUMASwitcher { // ...re-reserve the middle stripes. This should work unless release silently failed. address p2 = (address)os::attempt_reserve_memory_at((char*)p_middle_stripes, middle_stripe_len); + ASSERT_EQ(p2, p_middle_stripes); + PRINT_MAPPINGS("C"); // Clean up. Release all mappings. @@ -544,26 +546,29 @@ TEST_VM(os, release_bad_ranges) { TEST_VM(os, release_one_mapping_multi_commits) { // Test that we can release an area consisting of interleaved // committed and uncommitted regions: - const size_t stripe_len = 4 * M; - const int num_stripes = 4; + const size_t stripe_len = os::vm_allocation_granularity(); + const int num_stripes = 6; const size_t total_range_len = stripe_len * num_stripes; // reserve address space... address p = reserve_one_commit_multiple(num_stripes, stripe_len); - ASSERT_NE(p, (address)NULL); PRINT_MAPPINGS("A"); + ASSERT_NE(p, (address)nullptr); - // .. release it... - ASSERT_TRUE(os::release_memory((char*)p, total_range_len)); + // // make things even more difficult by trying to reserve at the border of the region + address border = p + num_stripes * stripe_len; + address p2 = (address)os::attempt_reserve_memory_at((char*)border, stripe_len); PRINT_MAPPINGS("B"); - // re-reserve it. This should work unless release failed. - address p2 = (address)os::attempt_reserve_memory_at((char*)p, total_range_len); - ASSERT_EQ(p2, p); - PRINT_MAPPINGS("C"); + ASSERT_TRUE(p2 == nullptr || p2 == border); ASSERT_TRUE(os::release_memory((char*)p, total_range_len)); - PRINT_MAPPINGS("D"); + PRINT_MAPPINGS("C"); + + if (p2 != nullptr) { + ASSERT_TRUE(os::release_memory((char*)p2, stripe_len)); + PRINT_MAPPINGS("D"); + } } static void test_show_mappings(address start, size_t size) { diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 68c9ae5d4c8..029be404306 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -148,6 +148,7 @@ vmTestbase/nsk/jvmti/AttachOnDemand/attach045/TestDescription.java 8202971 gener vmTestbase/nsk/jvmti/scenarios/jni_interception/JI05/ji05t001/TestDescription.java 8219652 aix-ppc64 vmTestbase/nsk/jvmti/scenarios/jni_interception/JI06/ji06t001/TestDescription.java 8219652 aix-ppc64 vmTestbase/nsk/jvmti/SetJNIFunctionTable/setjniftab001/TestDescription.java 8219652 aix-ppc64 +vmTestbase/nsk/jvmti/scenarios/capability/CM03/cm03t001/TestDescription.java 8073470 linux-all vmTestbase/gc/lock/jni/jnilock002/TestDescription.java 8192647 generic-all diff --git a/test/hotspot/jtreg/TEST.ROOT b/test/hotspot/jtreg/TEST.ROOT index 48e0cca9021..f6e6209cd6b 100644 --- a/test/hotspot/jtreg/TEST.ROOT +++ b/test/hotspot/jtreg/TEST.ROOT @@ -32,7 +32,8 @@ # intermittent: flaky test, known to fail intermittently # randomness: test uses randomness, test cases differ from run to run # cgroups: test uses cgroups -keys=stress headful intermittent randomness cgroups +# external-dep: test requires external dependencies to work +keys=stress headful intermittent randomness cgroups external-dep groups=TEST.groups TEST.quick-groups diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups index 31059064825..0973fb52cf8 100644 --- a/test/hotspot/jtreg/TEST.groups +++ b/test/hotspot/jtreg/TEST.groups @@ -21,6 +21,11 @@ # questions. # +# All tests + +all = \ + :hotspot_all + hotspot_all = \ / @@ -28,6 +33,8 @@ hotspot_all_no_apps = \ / \ -applications +# Component test groups + hotspot_compiler = \ compiler @@ -216,6 +223,7 @@ tier2_compiler = \ -:hotspot_slow_compiler tier3_compiler = \ + applications/ctw/modules \ compiler/c2/ \ compiler/ciReplay/ \ compiler/compilercontrol/ \ diff --git a/test/hotspot/jtreg/applications/jcstress/JcstressRunner.java b/test/hotspot/jtreg/applications/jcstress/JcstressRunner.java index e5d3df3dc0f..37ce9e7df70 100644 --- a/test/hotspot/jtreg/applications/jcstress/JcstressRunner.java +++ b/test/hotspot/jtreg/applications/jcstress/JcstressRunner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -42,11 +42,15 @@ * jcstress tests wrapper */ @Artifact(organization = "org.openjdk.jcstress", name = "jcstress-tests-all", - revision = "0.5", extension = "jar", unpack = false) + revision = "0.16", extension = "jar", unpack = false) public class JcstressRunner { public static final String MAIN_CLASS = "org.openjdk.jcstress.Main"; + // Allow to configure jcstress mode parameter. + // Test mode preset: sanity, quick, default, tough, stress. + public static final String MODE_PROPERTY = "jcstress.mode"; + public static Path pathToArtifact() { Map artifacts; try { @@ -55,7 +59,7 @@ public static Path pathToArtifact() { throw new Error("TESTBUG: Can not resolve artifacts for " + JcstressRunner.class.getName(), e); } - return artifacts.get("org.openjdk.jcstress.jcstress-tests-all-0.5") + return artifacts.get("org.openjdk.jcstress.jcstress-tests-all-0.16") .toAbsolutePath(); } @@ -104,11 +108,29 @@ private static String[] getCmd(String[] args) { extraFlags.add("--jvmArgs"); extraFlags.add("-Djava.io.tmpdir=" + System.getProperty("user.dir")); + + // The "default" preset might take days for some tests + // so use quick testing by default. + String mode = "quick"; for (String jvmArg : Utils.getTestJavaOpts()) { + if(jvmArg.startsWith("-D" + MODE_PROPERTY)) { + String[] pair = jvmArg.split("=", 2); + mode = pair[1]; + continue; + } extraFlags.add("--jvmArgs"); extraFlags.add(jvmArg); } + extraFlags.add("-m"); + extraFlags.add(mode); + + extraFlags.add("-sc"); + extraFlags.add("false"); + + extraFlags.add("-af"); + extraFlags.add("GLOBAL"); + String[] result = new String[extraFlags.size() + args.length]; extraFlags.toArray(result); System.arraycopy(args, 0, result, extraFlags.size(), args.length); diff --git a/test/hotspot/jtreg/applications/jcstress/TestGenerator.java b/test/hotspot/jtreg/applications/jcstress/TestGenerator.java index fc7a95f1e7c..0f5bccfad7e 100644 --- a/test/hotspot/jtreg/applications/jcstress/TestGenerator.java +++ b/test/hotspot/jtreg/applications/jcstress/TestGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -96,6 +96,7 @@ public class TestGenerator { public static String DESC_FORMAT = "\n" + "/**\n" + " * @test %1$s\n" + + " * @key external-dep\n" + " * @library /test/lib /\n" + " * @run driver/timeout=21600 " + JcstressRunner.class.getName() // verbose output @@ -122,7 +123,7 @@ public static void main(String[] args) throws IOException { BufferedReader reader = Files.newBufferedReader(output); reader.lines() - .skip(4) // skip first 4 lines: name, -{80}, revision and empty line + .filter(s -> s.startsWith("org.openjdk.jcstress.tests")) .map(s -> s.split("\\.")[4]) // group by the package name following "org.openjdk.jcstress.tests." .distinct() .filter(s -> !s.startsWith("sample")) // skip sample test diff --git a/test/hotspot/jtreg/applications/jcstress/accessAtomic.java b/test/hotspot/jtreg/applications/jcstress/accessAtomic.java index cfeb8ff0ea7..45311747023 100644 --- a/test/hotspot/jtreg/applications/jcstress/accessAtomic.java +++ b/test/hotspot/jtreg/applications/jcstress/accessAtomic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test accessAtomic + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.accessAtomic\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/acqrel.java b/test/hotspot/jtreg/applications/jcstress/acqrel.java index 0dd102221b5..8313278053e 100644 --- a/test/hotspot/jtreg/applications/jcstress/acqrel.java +++ b/test/hotspot/jtreg/applications/jcstress/acqrel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test acqrel + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.acqrel\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/atomicity.java b/test/hotspot/jtreg/applications/jcstress/atomicity.java index c6c4263aeb0..abffd4fb3dd 100644 --- a/test/hotspot/jtreg/applications/jcstress/atomicity.java +++ b/test/hotspot/jtreg/applications/jcstress/atomicity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test atomicity + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.atomicity\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/atomics.java b/test/hotspot/jtreg/applications/jcstress/atomics.java index 3527fad666d..449b051efa6 100644 --- a/test/hotspot/jtreg/applications/jcstress/atomics.java +++ b/test/hotspot/jtreg/applications/jcstress/atomics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test atomics + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.atomics\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/causality.java b/test/hotspot/jtreg/applications/jcstress/causality.java index 05ca0dc654a..8cda7d61ade 100644 --- a/test/hotspot/jtreg/applications/jcstress/causality.java +++ b/test/hotspot/jtreg/applications/jcstress/causality.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test causality + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.causality\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/coherence.java b/test/hotspot/jtreg/applications/jcstress/coherence.java index f8368834ac4..c2630c2dd66 100644 --- a/test/hotspot/jtreg/applications/jcstress/coherence.java +++ b/test/hotspot/jtreg/applications/jcstress/coherence.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test coherence + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.coherence\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/collections.java b/test/hotspot/jtreg/applications/jcstress/collections.java new file mode 100644 index 00000000000..b1363b25168 --- /dev/null +++ b/test/hotspot/jtreg/applications/jcstress/collections.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017, 2024, 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. + */ + +/* DO NOT MODIFY THIS FILE. GENERATED BY applications.jcstress.TestGenerator */ + +/** + * @test collections + * @key external-dep + * @library /test/lib / + * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.collections\. + */ + diff --git a/test/hotspot/jtreg/applications/jcstress/copy.java b/test/hotspot/jtreg/applications/jcstress/copy.java index b291dbe7cde..a2d0d6f099f 100644 --- a/test/hotspot/jtreg/applications/jcstress/copy.java +++ b/test/hotspot/jtreg/applications/jcstress/copy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test copy + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.copy\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/countdownlatch.java b/test/hotspot/jtreg/applications/jcstress/countdownlatch.java index 290ec80cc8c..cee4f917c6f 100644 --- a/test/hotspot/jtreg/applications/jcstress/countdownlatch.java +++ b/test/hotspot/jtreg/applications/jcstress/countdownlatch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test countdownlatch + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.countdownlatch\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/defaultValues.java b/test/hotspot/jtreg/applications/jcstress/defaultValues.java index c86529491b9..8fce07d8063 100644 --- a/test/hotspot/jtreg/applications/jcstress/defaultValues.java +++ b/test/hotspot/jtreg/applications/jcstress/defaultValues.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test defaultValues + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.defaultValues\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/executors.java b/test/hotspot/jtreg/applications/jcstress/executors.java index b29bbb6507c..f2f50978404 100644 --- a/test/hotspot/jtreg/applications/jcstress/executors.java +++ b/test/hotspot/jtreg/applications/jcstress/executors.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test executors + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.executors\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/fences.java b/test/hotspot/jtreg/applications/jcstress/fences.java index 5bca0257717..d2925a0a101 100644 --- a/test/hotspot/jtreg/applications/jcstress/fences.java +++ b/test/hotspot/jtreg/applications/jcstress/fences.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test fences + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.fences\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/future.java b/test/hotspot/jtreg/applications/jcstress/future.java index eea5b7de64c..5bc760fe2f5 100644 --- a/test/hotspot/jtreg/applications/jcstress/future.java +++ b/test/hotspot/jtreg/applications/jcstress/future.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test future + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.future\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/init.java b/test/hotspot/jtreg/applications/jcstress/init.java index 625037b8f94..087956881d3 100644 --- a/test/hotspot/jtreg/applications/jcstress/init.java +++ b/test/hotspot/jtreg/applications/jcstress/init.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test init + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.init\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/initClass.java b/test/hotspot/jtreg/applications/jcstress/initClass.java index 5a0e70f19ac..5b936ce46cd 100644 --- a/test/hotspot/jtreg/applications/jcstress/initClass.java +++ b/test/hotspot/jtreg/applications/jcstress/initClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test initClass + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.initClass\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/initLen.java b/test/hotspot/jtreg/applications/jcstress/initLen.java index 4cb040bf878..01ef04b8a13 100644 --- a/test/hotspot/jtreg/applications/jcstress/initLen.java +++ b/test/hotspot/jtreg/applications/jcstress/initLen.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test initLen + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.initLen\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/interrupt.java b/test/hotspot/jtreg/applications/jcstress/interrupt.java index 8e4d2ad0fba..1a9ecc357d4 100644 --- a/test/hotspot/jtreg/applications/jcstress/interrupt.java +++ b/test/hotspot/jtreg/applications/jcstress/interrupt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test interrupt + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.interrupt\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/locks.java b/test/hotspot/jtreg/applications/jcstress/locks.java index 7450e295094..e3e11633323 100644 --- a/test/hotspot/jtreg/applications/jcstress/locks.java +++ b/test/hotspot/jtreg/applications/jcstress/locks.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test locks + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.locks\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/memeffects.java b/test/hotspot/jtreg/applications/jcstress/memeffects.java index d4e1b0e26ce..6be6d180939 100644 --- a/test/hotspot/jtreg/applications/jcstress/memeffects.java +++ b/test/hotspot/jtreg/applications/jcstress/memeffects.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test memeffects + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.memeffects\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/mxbeans.java b/test/hotspot/jtreg/applications/jcstress/mxbeans.java new file mode 100644 index 00000000000..4714b335bdd --- /dev/null +++ b/test/hotspot/jtreg/applications/jcstress/mxbeans.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017, 2024, 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. + */ + +/* DO NOT MODIFY THIS FILE. GENERATED BY applications.jcstress.TestGenerator */ + +/** + * @test mxbeans + * @key external-dep + * @library /test/lib / + * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.mxbeans\. + */ + diff --git a/test/hotspot/jtreg/applications/jcstress/oota.java b/test/hotspot/jtreg/applications/jcstress/oota.java new file mode 100644 index 00000000000..6c21e76a7e9 --- /dev/null +++ b/test/hotspot/jtreg/applications/jcstress/oota.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017, 2024, 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. + */ + +/* DO NOT MODIFY THIS FILE. GENERATED BY applications.jcstress.TestGenerator */ + +/** + * @test oota + * @key external-dep + * @library /test/lib / + * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.oota\. + */ + diff --git a/test/hotspot/jtreg/applications/jcstress/seqcst.java b/test/hotspot/jtreg/applications/jcstress/seqcst.java index 7b0bae61855..def96932d7e 100644 --- a/test/hotspot/jtreg/applications/jcstress/seqcst.java +++ b/test/hotspot/jtreg/applications/jcstress/seqcst.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test seqcst + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.seqcst\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/singletons.java b/test/hotspot/jtreg/applications/jcstress/singletons.java index 1ddaaff4c68..9714dc0ea1d 100644 --- a/test/hotspot/jtreg/applications/jcstress/singletons.java +++ b/test/hotspot/jtreg/applications/jcstress/singletons.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test singletons + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.singletons\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/strings.java b/test/hotspot/jtreg/applications/jcstress/strings.java index 76ed85ab65f..caacea9bcc7 100644 --- a/test/hotspot/jtreg/applications/jcstress/strings.java +++ b/test/hotspot/jtreg/applications/jcstress/strings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test strings + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.strings\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/tearing.java b/test/hotspot/jtreg/applications/jcstress/tearing.java index 3b9c96351c1..a55d43964b7 100644 --- a/test/hotspot/jtreg/applications/jcstress/tearing.java +++ b/test/hotspot/jtreg/applications/jcstress/tearing.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test tearing + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.tearing\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/threadlocal.java b/test/hotspot/jtreg/applications/jcstress/threadlocal.java index 4abc459224f..9103b90594a 100644 --- a/test/hotspot/jtreg/applications/jcstress/threadlocal.java +++ b/test/hotspot/jtreg/applications/jcstress/threadlocal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test threadlocal + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.threadlocal\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/unsafe.java b/test/hotspot/jtreg/applications/jcstress/unsafe.java index 2983d4e8e04..8be919b0c3b 100644 --- a/test/hotspot/jtreg/applications/jcstress/unsafe.java +++ b/test/hotspot/jtreg/applications/jcstress/unsafe.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test unsafe + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.unsafe\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/varhandles.java b/test/hotspot/jtreg/applications/jcstress/varhandles.java index 389714c32a8..af9b4271157 100644 --- a/test/hotspot/jtreg/applications/jcstress/varhandles.java +++ b/test/hotspot/jtreg/applications/jcstress/varhandles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test varhandles + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.varhandles\. */ diff --git a/test/hotspot/jtreg/applications/jcstress/volatiles.java b/test/hotspot/jtreg/applications/jcstress/volatiles.java index 085289fad24..2f1f015b8d5 100644 --- a/test/hotspot/jtreg/applications/jcstress/volatiles.java +++ b/test/hotspot/jtreg/applications/jcstress/volatiles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,6 +25,7 @@ /** * @test volatiles + * @key external-dep * @library /test/lib / * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.volatiles\. */ diff --git a/test/hotspot/jtreg/applications/scimark/Scimark.java b/test/hotspot/jtreg/applications/scimark/Scimark.java index 8aab97aa2bc..24691939dd6 100644 --- a/test/hotspot/jtreg/applications/scimark/Scimark.java +++ b/test/hotspot/jtreg/applications/scimark/Scimark.java @@ -23,6 +23,7 @@ /* * @test + * @key external-dep * @library /test/lib * @run driver Scimark */ diff --git a/test/hotspot/jtreg/compiler/c2/TestTopCastIIOnUndetectedDeadPath.java b/test/hotspot/jtreg/compiler/c2/TestTopCastIIOnUndetectedDeadPath.java new file mode 100644 index 00000000000..1b95e13d4f7 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestTopCastIIOnUndetectedDeadPath.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 8319372 + * @summary CastII because of condition guarding it becomes top + * @requires vm.compiler2.enabled + * @run main/othervm -Xcomp -XX:CompileOnly=TestTopCastIIOnUndetectedDeadPath::test -XX:CompileCommand=quiet -XX:-TieredCompilation + * -XX:+UnlockDiagnosticVMOptions -XX:StressSeed=426264791 -XX:+StressIGVN TestTopCastIIOnUndetectedDeadPath + * @run main/othervm -Xcomp -XX:CompileOnly=TestTopCastIIOnUndetectedDeadPath::test -XX:CompileCommand=quiet -XX:-TieredCompilation + * -XX:+UnlockDiagnosticVMOptions -XX:+StressIGVN TestTopCastIIOnUndetectedDeadPath + */ + +public class TestTopCastIIOnUndetectedDeadPath { + static class X { + static void m(int[] a) { + + } + } + + static int array[] = new int[10]; + + static void test(int val) { + for (int i = 1; i < 10; ++i) { + for (int j = i; j < 10; ++j) { + if (i == 0 && j != 0) { + X.m(array); + } + array[j - 1] = val; + } + } + } + + public static void main(String[] arg) { + test(42); + } +} diff --git a/test/hotspot/jtreg/compiler/c2/TestTopCastIIOnUndetectedDeadPath2.java b/test/hotspot/jtreg/compiler/c2/TestTopCastIIOnUndetectedDeadPath2.java new file mode 100644 index 00000000000..98121b3b754 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestTopCastIIOnUndetectedDeadPath2.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 8319372 + * @summary CastII because of condition guarding it becomes top + * @requires vm.compiler2.enabled + * @run main/othervm -XX:CompileCommand=quiet -XX:CompileCommand=compileonly,TestTopCastIIOnUndetectedDeadPath2::test -XX:-TieredCompilation + * -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+StressIGVN -XX:StressSeed=256120824 TestTopCastIIOnUndetectedDeadPath2 + * @run main/othervm -XX:CompileCommand=quiet -XX:CompileCommand=compileonly,TestTopCastIIOnUndetectedDeadPath2::test -XX:-TieredCompilation + * -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+StressIGVN TestTopCastIIOnUndetectedDeadPath2 + */ + +public class TestTopCastIIOnUndetectedDeadPath2 { + static int array[] = new int[100]; + + static int test() { + int res = 0; + for (int i = 1; i < 100; ++i) { + try { + res = array[i - 1]; + int x = (42 % i); + } catch (ArithmeticException e) { + } + } + return res; + } + + public static void main(String[] args) { + for (int i = 0; i < 10_000; i++) { + test(); + } + } +} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersMapping.java b/test/hotspot/jtreg/compiler/c2/TestTopCastIIOnUndetectedDeadPath3.java similarity index 51% rename from test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersMapping.java rename to test/hotspot/jtreg/compiler/c2/TestTopCastIIOnUndetectedDeadPath3.java index 0fa2ad0b14c..86f26b22295 100644 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersMapping.java +++ b/test/hotspot/jtreg/compiler/c2/TestTopCastIIOnUndetectedDeadPath3.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,30 +21,38 @@ * questions. */ -import org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification; - -import java.net.http.HttpResponse.BodySubscribers; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.concurrent.Flow.Subscriber; +/* + * @test + * @bug 8319372 + * @summary CastII because of condition guarding it becomes top + * @run main/othervm -Xcomp -XX:CompileOnly=TestTopCastIIOnUndetectedDeadPath3::* -XX:-TieredCompilation TestTopCastIIOnUndetectedDeadPath3 + */ -/* See TckDriver.java for more information */ -public class BodySubscribersMapping - extends FlowSubscriberBlackboxVerification> { +public class TestTopCastIIOnUndetectedDeadPath3 { - public BodySubscribersMapping() { - super(new TestEnvironment(450L)); + static long test() { + int x = 6, y = 5; + int[] iArr = new int[200]; + for (int i = 129; i > 5; i -= 2) { // OSR compiled + try { + y = iArr[i - 1]; + x = iArr[i + 1]; + x = 1 / i; + } catch (ArithmeticException a_e) { + } + } + Foo.empty(); + return x + y; } - @Override - public Subscriber> createFlowSubscriber() { - return BodySubscribers.mapping(BodySubscribers.ofByteArray(), - bytes -> bytes.length); + public static void main(String[] strArr) { + new TestTopCastIIOnUndetectedDeadPath3(); + for (int i = 0; i < 2000; i++) { + test(); + } } +} - @Override - public List createElement(int element) { - return S.listOfBuffersFromBufferOfNBytes(element % 17); - } +class Foo { + public static void empty() {} } diff --git a/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java b/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java index f47331a6d80..e2b7605a5d8 100644 --- a/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java +++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, BELLSOFT. All rights reserved. + * Copyright (c) 2024, BELLSOFT. 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,10 +89,9 @@ static void runVM(boolean bigCodeHeap) throws Exception { "-Xbatch", "-XX:+TieredCompilation", "-XX:+SegmentedCodeCache", - "-XX:CompileOnly=" + className + "::main", "-XX:ReservedCodeCacheSize=" + (bigCodeHeap ? "256M" : "200M"), "-XX:+UnlockDiagnosticVMOptions", - "-XX:+PrintAssembly", + "-XX:CompileCommand=option," + className + "::main,bool,PrintAssembly,true", className}; ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(procArgs); diff --git a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java index 68313ca2cac..260c8ddcc3e 100644 --- a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java +++ b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java @@ -72,7 +72,7 @@ public abstract class CiReplayBase { "-XX:+PreferInterpreterNativeStubs", REPLAY_FILE_OPTION}; private static final String[] REPLAY_OPTIONS = new String[]{DISABLE_COREDUMP_ON_CRASH, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:TypeProfileLevel=222", - "-XX:+ReplayCompiles", REPLAY_FILE_OPTION}; + "-XX:+ReplayCompiles"}; protected final Optional runServer; private static int dummy; @@ -124,7 +124,7 @@ public void runTest(boolean needCoreDump, String... args) { public abstract void testAction(); - private static void remove(String item) { + public static void remove(String item) { File toDelete = new File(item); toDelete.delete(); if (Platform.isWindows()) { @@ -138,7 +138,7 @@ private static void removeFromCurrentDirectoryStartingWith(String prefix) { .forEach(File::delete); } - public static void cleanup() { + public void cleanup() { removeFromCurrentDirectoryStartingWith("core"); removeFromCurrentDirectoryStartingWith("replay"); removeFromCurrentDirectoryStartingWith(HS_ERR_NAME); @@ -146,6 +146,10 @@ public static void cleanup() { remove(REPLAY_FILE_NAME); } + public String getReplayFileName() { + return REPLAY_FILE_NAME; + } + public boolean generateReplay(boolean needCoreDump, String... vmopts) { OutputAnalyzer crashOut; String crashOutputString; @@ -156,13 +160,13 @@ public boolean generateReplay(boolean needCoreDump, String... vmopts) { options.add(needCoreDump ? ENABLE_COREDUMP_ON_CRASH : DISABLE_COREDUMP_ON_CRASH); if (needCoreDump) { // CiReplayBase$TestMain needs to be quoted because of shell eval - options.add("-XX:CompileOnly='" + TestMain.class.getName() + "::test'"); + options.add("-XX:CompileOnly='" + TestMain.class.getName() + "::" + getTestMethod() + "'"); options.add("'" + TestMain.class.getName() + "'"); crashOut = ProcessTools.executeProcess( CoreUtils.addCoreUlimitCommand( ProcessTools.createTestJvm(options.toArray(new String[0])))); } else { - options.add("-XX:CompileOnly=" + TestMain.class.getName() + "::test"); + options.add("-XX:CompileOnly=" + TestMain.class.getName() + "::" + getTestMethod()); options.add(TestMain.class.getName()); crashOut = ProcessTools.executeProcess(ProcessTools.createTestJvm(options)); } @@ -186,6 +190,14 @@ public boolean generateReplay(boolean needCoreDump, String... vmopts) { return true; } + public String getTestClass() { + return TestMain.class.getName(); + } + + public String getTestMethod() { + return "test"; + } + public void commonTests() { positiveTest(); if (Platform.isTieredSupported()) { @@ -197,6 +209,7 @@ public int startTest(String... additionalVmOpts) { try { List allAdditionalOpts = new ArrayList<>(); allAdditionalOpts.addAll(Arrays.asList(REPLAY_OPTIONS)); + allAdditionalOpts.add("-XX:ReplayDataFile=" + getReplayFileName()); allAdditionalOpts.addAll(Arrays.asList(additionalVmOpts)); OutputAnalyzer oa = ProcessTools.executeProcess(getTestJvmCommandlineWithPrefix( RUN_SHELL_ZERO_LIMIT, allAdditionalOpts.toArray(new String[0]))); diff --git a/test/hotspot/jtreg/compiler/ciReplay/DumpReplayBase.java b/test/hotspot/jtreg/compiler/ciReplay/DumpReplayBase.java new file mode 100644 index 00000000000..4d783993578 --- /dev/null +++ b/test/hotspot/jtreg/compiler/ciReplay/DumpReplayBase.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2021, 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 compiler.ciReplay; + +import jdk.test.lib.Asserts; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public abstract class DumpReplayBase extends CiReplayBase { + + private static final String DUMP_REPLAY_PATTERN = "replay_pid"; + private List replayFiles; + private String replayFileName; + + @Override + public void runTest(boolean needCoreDump, String... args) { + throw new RuntimeException("use runTests(String...)"); + } + + public void runTest(String... args) { + if (generateReplay(args)) { + testAction(); + cleanup(); + } else { + throw new Error("Host is not configured to generate cores"); + } + } + + @Override + public void cleanup() { + replayFiles.forEach(f -> remove(f.getName())); + } + + @Override + public String getReplayFileName() { + Asserts.assertEQ(replayFiles.size(), 1, "Test should only dump 1 replay file when trying to replay compile"); + return replayFileName; + } + + public boolean generateReplay(String... vmopts) { + OutputAnalyzer oa; + try { + List options = new ArrayList<>(Arrays.asList(vmopts)); + options.add("-XX:CompileCommand=option," + getTestClass() + "::" + getTestMethod() + ",bool,DumpReplay,true"); + options.add("-XX:+IgnoreUnrecognizedVMOptions"); + options.add("-XX:TypeProfileLevel=222"); + options.add("-XX:CompileCommand=compileonly," + getTestClass() + "::" + getTestMethod()); + options.add("-Xbatch"); + options.add(getTestClass()); + oa = ProcessTools.executeProcess(ProcessTools.createTestJvm(options)); + Asserts.assertEquals(oa.getExitValue(), 0, "Crash JVM exits gracefully"); + replayFiles = Files.list(Paths.get(".")) + .map(Path::toFile) + .filter(f -> f.getName().startsWith(DUMP_REPLAY_PATTERN)).collect(Collectors.toList()); + Asserts.assertFalse(replayFiles.isEmpty(), "Did not find a replay file starting with " + DUMP_REPLAY_PATTERN); + replayFileName = replayFiles.get(0).getName(); + } catch (Throwable t) { + throw new Error("Can't create replay: " + t, t); + } + return true; + } + + public int getCompileIdFromFile(String replayFileName) { + Pattern p = Pattern.compile("replay_pid.*_compid([0-9]+)\\.log"); + Matcher matcher = p.matcher(replayFileName); + if (matcher.find()) { + try { + return Integer.parseInt(matcher.group(1)); + } catch (NumberFormatException e) { + throw new RuntimeException("Could not parse compile id from filename \"" + replayFileName + "\""); + } + } else { + throw new RuntimeException("Could not find compile id in filename \"" + replayFileName + "\""); + } + } + + public List getReplayFiles() { + return replayFiles; + } +} diff --git a/test/hotspot/jtreg/compiler/ciReplay/TestInliningProtectionDomain.java b/test/hotspot/jtreg/compiler/ciReplay/TestInliningProtectionDomain.java new file mode 100644 index 00000000000..140a95be872 --- /dev/null +++ b/test/hotspot/jtreg/compiler/ciReplay/TestInliningProtectionDomain.java @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2021, 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 8275868 + * @library / /test/lib + * @summary Testing that ciReplay inlining does not fail with unresolved signature classes. + * @requires vm.flightRecorder != true & vm.compMode != "Xint" & vm.compMode != "Xcomp" & vm.debug == true & vm.compiler2.enabled + * @modules java.base/jdk.internal.misc + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * compiler.ciReplay.TestInliningProtectionDomain + */ + +package compiler.ciReplay; + +import jdk.test.lib.Asserts; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class TestInliningProtectionDomain extends DumpReplayBase { + public static final String LOG_FILE_NORMAL = "hotspot_normal.log"; + public static final String LOG_FILE_REPLAY = "hotspot_replay.log"; + private final String[] commandLineReplay; + + private final String className; + + public static void main(String[] args) { + new TestInliningProtectionDomain("ProtectionDomainTestCompiledBefore", true); + new TestInliningProtectionDomain("ProtectionDomainTestNoOtherCompilationPublic", false); + new TestInliningProtectionDomain("ProtectionDomainTestNoOtherCompilationPrivate", false); + new TestInliningProtectionDomain("ProtectionDomainTestNoOtherCompilationPrivateString", false); + } + + public TestInliningProtectionDomain(String className, boolean compileBar) { + this.className = className; + List commandLineNormal = new ArrayList<>(List.of("-XX:LogFile=" + LOG_FILE_NORMAL + "", "-XX:+LogCompilation", "-XX:-TieredCompilation", + "-XX:CompileCommand=exclude," + getTestClass() + "::main", + "-XX:CompileCommand=option," + getTestClass() + "::test,bool,PrintInlining,true")); + if (compileBar) { + commandLineNormal.add("-XX:CompileCommand=compileonly," + getTestClass() + "::bar"); + } + commandLineReplay = new String[] + {"-XX:LogFile=" + LOG_FILE_REPLAY + "", "-XX:+LogCompilation", + "-XX:CompileCommand=option," + getTestClass() + "::test,bool,PrintInlining,true"}; + runTest(commandLineNormal.toArray(new String[0])); + } + + @Override + public void testAction() { + positiveTest(commandLineReplay); + String klass = "compiler.ciReplay." + className; + String entryString = klass + " " + "test"; + boolean inlineFails = className.equals("ProtectionDomainTestNoOtherCompilationPrivate"); + int inlineeCount = inlineFails ? 1 : 5; + + List inlineesNormal = parseLogFile(LOG_FILE_NORMAL, entryString, "compile_id='" + getCompileIdFromFile(getReplayFileName()), inlineeCount); + List inlineesReplay = parseLogFile(LOG_FILE_REPLAY, entryString, "test ()V", inlineeCount); + verifyLists(inlineesNormal, inlineesReplay, inlineeCount); + + if (inlineFails) { + Asserts.assertTrue(compare(inlineesNormal.get(0), "compiler.ciReplay.ProtectionDomainTestNoOtherCompilationPrivate", + "bar", inlineesNormal.get(0).isUnloadedSignatureClasses())); + Asserts.assertTrue(compare(inlineesReplay.get(0), "compiler.ciReplay.ProtectionDomainTestNoOtherCompilationPrivate", + "bar", inlineesReplay.get(0).isDisallowedByReplay())); + } else { + Asserts.assertTrue(compare(inlineesNormal.get(4), "compiler.ciReplay.InliningBar", "bar2", inlineesNormal.get(4).isNormalInline())); + Asserts.assertTrue(compare(inlineesReplay.get(4), "compiler.ciReplay.InliningBar", "bar2", inlineesReplay.get(4).isForcedByReplay())); + } + remove(LOG_FILE_NORMAL); + remove(LOG_FILE_REPLAY); + } + + private void verifyLists(List inlineesNormal, List inlineesReplay, int expectedSize) { + if (!inlineesNormal.equals(inlineesReplay)) { + System.err.println("Normal entries:"); + inlineesNormal.forEach(System.err::println); + System.err.println("Replay entries:"); + inlineesReplay.forEach(System.err::println); + Asserts.fail("different inlining decision in normal run vs. replay run"); + } + Asserts.assertEQ(expectedSize, inlineesNormal.size(), "unexpected number of inlinees found"); + } + + public static boolean compare(Entry e, String klass, String method, boolean kind) { + return e.klass.equals(klass) && e.method.equals(method) && kind; + } + + public static List parseLogFile(String logFile, String rootMethod, String nmethodMatch, int inlineeCount) { + String nmethodStart = " inlinees = new ArrayList<>(); + int foundLines = 0; + try (var br = Files.newBufferedReader(Paths.get(logFile))) { + String line; + boolean nmethodLine = false; + boolean inlinineLine = false; + while ((line = br.readLine()) != null) { + if (nmethodLine) { + // Ignore other entries which could be in between nmethod entry and inlining statements + if (line.startsWith(" ")) { + inlinineLine = true; + Pattern p = Pattern.compile("(\\S+)::(\\S+).*bytes\\)\s+(.*)"); + Matcher matcher = p.matcher(line); + Asserts.assertTrue(matcher.find(), "must find inlinee method"); + inlinees.add(new Entry(matcher.group(1), matcher.group(2), matcher.group(3).trim())); + foundLines++; + } else if (inlinineLine) { + Asserts.assertEQ(foundLines, inlineeCount, "did not find all inlinees"); + return inlinees; + } + } else { + nmethodLine = line.startsWith(nmethodStart) && line.contains(nmethodMatch); + if (nmethodLine) { + Asserts.assertTrue(line.contains(rootMethod), "should only dump inline information for " + rootMethod); + } + } + } + } catch (IOException e) { + throw new Error("Failed to read " + logFile + " data: " + e, e); + } + Asserts.fail("Should have found inlinees"); + return inlinees; + } + + + @Override + public String getTestClass() { + return "compiler.ciReplay." + className; + } + + static class Entry { + String klass; + String method; + String reason; + + public Entry(String klass, String method, String reason) { + this.klass = klass; + this.method = method; + this.reason = reason; + } + + public boolean isNormalInline() { + return reason.equals("inline (hot)"); + } + + public boolean isForcedByReplay() { + return reason.equals("force inline by ciReplay"); + } + + public boolean isDisallowedByReplay() { + return reason.equals("disallowed by ciReplay"); + } + + public boolean isUnloadedSignatureClasses() { + return reason.equals("unloaded signature classes"); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof Entry)) { + return false; + } + + Entry e = (Entry)other; + return klass.equals(e.klass) && method.equals(e.method); + } + } +} + +class ProtectionDomainTestCompiledBefore { + public static void main(String[] args) { + for (int i = 0; i < 10000; i++) { + bar(); // Ensure that bar() was compiled + } + for (int i = 0; i < 10000; i++) { + test(); + } + } + + public static void test() { + bar(); + } + + // Integer should be resolved for the protection domain of this class because the separate compilation of bar() in + // the normal run will resolve all classes in the signature. Inlining succeeds. + private static Integer bar() { + InliningFoo.foo(); + return null; + } +} + +class ProtectionDomainTestNoOtherCompilationPublic { + public static void main(String[] args) { + for (int i = 0; i < 10000; i++) { + test(); + } + } + + public static void test() { + bar(); // Not compiled before separately + } + + // Integer should be resolved for the protection domain of this class because getDeclaredMethods is called in normal run + // when validating main() method. In this process, all public methods of this class are visited and its signature classes + // are resolved. Inlining of bar() succeeds. + public static Integer bar() { + InliningFoo.foo(); + return null; + } +} + +class ProtectionDomainTestNoOtherCompilationPrivate { + public static void main(String[] args) { + for (int i = 0; i < 10000; i++) { + test(); + } + } + + public static void test() { + bar(); // Not compiled before separately + } + + // Integer should be unresolved for the protection domain of this class even though getDeclaredMethods is called in normal + // run when validating main() method. In this process, only public methods of this class are visited and its signature + // classes are resolved. Since this method is private, the signature classes are not resolved for this protection domain. + // Inlining of bar() should fail in normal run with "unresolved signature classes". Therefore, replay compilation should + // also not inline bar(). + private static Integer bar() { + InliningFoo.foo(); + return null; + } +} + +class ProtectionDomainTestNoOtherCompilationPrivateString { + public static void main(String[] args) { + for (int i = 0; i < 10000; i++) { + test(); + } + } + + public static void test() { + bar(); // Not compiled before separately + } + + // Integer should be resovled for the protection domain of this class because getDeclaredMethods is called in normal run + // when validating main() method. In this process, public methods of this class are visited and its signature classes + // are resolved. bar() is private and not visited in this process (i.e. no resolution of String). But since main() + // has String[] as parameter, the String class will be resolved for this protection domain. Inlining of bar() succeeds. + private static String bar() { + InliningFoo.foo(); + return null; + } +} + +class InliningFoo { + public static void foo() { + foo2(); + } + + private static void foo2() { + InliningBar.bar(); + } +} + + +class InliningBar { + public static void bar() { + bar2(); + } + + private static void bar2() {} +} diff --git a/test/hotspot/jtreg/compiler/ciReplay/TestNoClassFile.java b/test/hotspot/jtreg/compiler/ciReplay/TestNoClassFile.java new file mode 100644 index 00000000000..0459cf0afd1 --- /dev/null +++ b/test/hotspot/jtreg/compiler/ciReplay/TestNoClassFile.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021, 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 8276227 + * @library / /test/lib + * @summary Testing that ciReplay works if we do not find the class files to replay compile. + * @requires vm.flightRecorder != true & vm.compMode != "Xint" & vm.compMode != "Xcomp" & vm.debug == true & vm.compiler2.enabled + * @modules java.base/jdk.internal.misc + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * compiler.ciReplay.TestNoClassFile + */ + +package compiler.ciReplay; + +public class TestNoClassFile extends DumpReplayBase { + + public static void main(String[] args) { + new TestNoClassFile().runTest(TIERED_DISABLED_VM_OPTION); + } + + @Override + public void testAction() { + // Override classpath such that we do not find any class files for replay compilation. Should exit gracefully. + positiveTest("-cp foo", "-XX:+ReplayIgnoreInitErrors"); + } + + @Override + public String getTestClass() { + return NoClassFileMain.class.getName(); + } + +} + +class NoClassFileMain { + public static void main(String[] args) { + for (int i = 0; i < 10000; i++) { + test(); + } + } + public static void test() { + NoClassFileHelper.bar(); + } +} + +class NoClassFileHelper { + public static int bar() { + return 3; + } +} diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/DigestSanityTestBase.java b/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/DigestSanityTestBase.java index 3b894e4e64a..c5826479024 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/DigestSanityTestBase.java +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/DigestSanityTestBase.java @@ -54,7 +54,7 @@ public class DigestSanityTestBase { private static final int MSG_SIZE = 1024; private static final int OFFSET = 0; private static final int ITERATIONS = 10000; - private static final int WARMUP_ITERATIONS = 1; + private static final int WARMUP_ITERATIONS = WHITE_BOX.getIntxVMFlag("Tier4InvocationThreshold").intValue() + 50; private static final String PROVIDER = "SUN"; private final BooleanSupplier predicate; diff --git a/test/hotspot/jtreg/compiler/loopopts/TestRemixAddressExpressionsWithIrreducibleLoop.java b/test/hotspot/jtreg/compiler/loopopts/TestRemixAddressExpressionsWithIrreducibleLoop.java new file mode 100644 index 00000000000..ff7be96007d --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/TestRemixAddressExpressionsWithIrreducibleLoop.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024, 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 8326638 + * @summary Test handling of irreducible loops in PhaseIdealLoop::remix_address_expressions. + * @run main/othervm -XX:-TieredCompilation -Xbatch + * -XX:CompileCommand=compileonly,TestRemixAddressExpressionsWithIrreducibleLoop::test + * TestRemixAddressExpressionsWithIrreducibleLoop + */ + +public class TestRemixAddressExpressionsWithIrreducibleLoop { + + public static void main(String[] args) { + test("4"); + } + + public static void test(String arg) { + for (int i = 0; i < 100_000; ++i) { + int j = 0; + while (true) { + boolean tmp = "1\ufff0".startsWith(arg, 2 - arg.length()); + if (j++ > 100) + break; + } + loop: + while (i >= 100) { + for (int i2 = 0; i2 < 1; i2 = 1) + if (j > 300) + break loop; + j++; + } + } + } +} diff --git a/test/hotspot/jtreg/compiler/tiered/LevelTransitionTest.java b/test/hotspot/jtreg/compiler/tiered/LevelTransitionTest.java index b18b304a9bc..336c9eb5cb1 100644 --- a/test/hotspot/jtreg/compiler/tiered/LevelTransitionTest.java +++ b/test/hotspot/jtreg/compiler/tiered/LevelTransitionTest.java @@ -204,7 +204,8 @@ private ExtendedTestCase(String methodName) { } private static class CompileMethodHolder { - private final int iter = 10; + // Make sure that loop backedge is never taken to prevent unexpected OSR compilations. + private final int iter = 1; private int field = 42; /** diff --git a/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java b/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java index 8350087ae78..6b817d7255c 100644 --- a/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java +++ b/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java @@ -37,6 +37,7 @@ * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar whitebox.jar jdk.test.whitebox.WhiteBox * @run main/othervm -Xbootclasspath/a:whitebox.jar -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI TestMemoryAwareness */ +import java.util.function.Consumer; import jdk.test.lib.containers.docker.Common; import jdk.test.lib.containers.docker.DockerRunOptions; import jdk.test.lib.containers.docker.DockerTestUtils; @@ -96,7 +97,9 @@ public static void main(String[] args) throws Exception { true /* additional cgroup fs mounts */ ); testOSMXBeanIgnoresMemLimitExceedingPhysicalMemory(); + testOSMXBeanIgnoresSwapLimitExceedingPhysical(); testMetricsExceedingPhysicalMemory(); + testMetricsSwapExceedingPhysical(); testContainerMemExceedsPhysical(); } finally { if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { @@ -183,6 +186,13 @@ private static void testOperatingSystemMXBeanAwareness(String memoryAllocation, private static void testOperatingSystemMXBeanAwareness(String memoryAllocation, String expectedMemory, String swapAllocation, String expectedSwap, boolean addCgroupMounts) throws Exception { + Consumer noOp = o -> {}; + testOperatingSystemMXBeanAwareness(memoryAllocation, expectedMemory, swapAllocation, expectedSwap, false, noOp); + } + + private static void testOperatingSystemMXBeanAwareness(String memoryAllocation, String expectedMemory, + String swapAllocation, String expectedSwap, boolean addCgroupMounts, + Consumer additionalMatch) throws Exception { Common.logNewTestCase("Check OperatingSystemMXBean"); @@ -191,6 +201,7 @@ private static void testOperatingSystemMXBeanAwareness(String memoryAllocation, "--memory", memoryAllocation, "--memory-swap", swapAllocation ) + .addJavaOpts("-esa") // CheckOperatingSystemMXBean uses Metrics (jdk.internal.platform) for // diagnostics .addJavaOpts("--add-exports") @@ -228,9 +239,9 @@ private static void testOperatingSystemMXBeanAwareness(String memoryAllocation, } catch(RuntimeException ex) { out.shouldMatch("OperatingSystemMXBean\\.getFreeSwapSpaceSize: 0"); } + additionalMatch.accept(out); } - // JDK-8292541: Ensure OperatingSystemMXBean ignores container memory limits above the host's physical memory. private static void testOSMXBeanIgnoresMemLimitExceedingPhysicalMemory() throws Exception { @@ -239,6 +250,35 @@ private static void testOSMXBeanIgnoresMemLimitExceedingPhysicalMemory() testOperatingSystemMXBeanAwareness(badMem, hostMaxMem, badMem, hostMaxMem); } + private static void testOSMXBeanIgnoresSwapLimitExceedingPhysical() + throws Exception { + long totalSwap = wb.hostPhysicalSwap() + wb.hostPhysicalMemory(); + String expectedSwap = Long.valueOf(totalSwap).toString(); + String hostMaxMem = getHostMaxMemory(); + String badMem = hostMaxMem + "0"; + final String badSwap = expectedSwap + "0"; + testOperatingSystemMXBeanAwareness(badMem, hostMaxMem, badSwap, expectedSwap, false, o -> { + o.shouldNotContain("Metrics.getMemoryAndSwapLimit() == " + badSwap); + }); + } + + private static void testMetricsSwapExceedingPhysical() + throws Exception { + Common.logNewTestCase("Metrics ignore container swap memory limit exceeding physical"); + long totalSwap = wb.hostPhysicalSwap() + wb.hostPhysicalMemory(); + String expectedSwap = Long.valueOf(totalSwap).toString(); + final String badSwap = expectedSwap + "0"; + String badMem = getHostMaxMemory() + "0"; + DockerRunOptions opts = Common.newOpts(imageName) + .addJavaOpts("-XshowSettings:system") + .addDockerOpts("--memory", badMem) + .addDockerOpts("--memory-swap", badSwap); + + OutputAnalyzer out = DockerTestUtils.dockerRunJava(opts); + out.shouldContain("Memory Limit: Unlimited"); + out.shouldContain("Memory & Swap Limit: Unlimited"); + } + // JDK-8292541: Ensure Metrics ignores container memory limits above the host's physical memory. private static void testMetricsExceedingPhysicalMemory() throws Exception { diff --git a/test/hotspot/jtreg/gc/epsilon/TestEnoughUnusedSpace.java b/test/hotspot/jtreg/gc/epsilon/TestEnoughUnusedSpace.java new file mode 100644 index 00000000000..2578b3fb2e0 --- /dev/null +++ b/test/hotspot/jtreg/gc/epsilon/TestEnoughUnusedSpace.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024, 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 gc.epsilon; + +/** + * @test TestEnoughUnusedSpace + * @requires vm.gc.Epsilon + * @summary Epsilon should allocates object successfully if it has enough space. + * @run main/othervm -Xms64M -Xmx128M -XX:+UnlockExperimentalVMOptions + * -XX:+UseEpsilonGC gc.epsilon.TestEnoughUnusedSpace + */ + +public class TestEnoughUnusedSpace { + static volatile Object arr; + + public static void main(String[] args) { + // Create an array about 90M. It should be created successfully + // instead of throwing OOME, because 90M is smaller than 128M. + arr = new byte[90 * 1024 * 1024]; + } +} diff --git a/test/hotspot/jtreg/gc/shenandoah/compiler/TestUnsafeLoadStoreMergedHeapStableTests.java b/test/hotspot/jtreg/gc/shenandoah/compiler/TestUnsafeLoadStoreMergedHeapStableTests.java new file mode 100644 index 00000000000..e7f9c777ef8 --- /dev/null +++ b/test/hotspot/jtreg/gc/shenandoah/compiler/TestUnsafeLoadStoreMergedHeapStableTests.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2024, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 8325372 + * @summary fusion of heap stable test causes GetAndSet node to be removed + * @requires vm.gc.Shenandoah + * @modules java.base/jdk.internal.misc:+open + * + * @run main/othervm -XX:+UseShenandoahGC -XX:-BackgroundCompilation TestUnsafeLoadStoreMergedHeapStableTests + */ + +import jdk.internal.misc.Unsafe; + +import java.lang.reflect.Field; + +public class TestUnsafeLoadStoreMergedHeapStableTests { + + static final jdk.internal.misc.Unsafe UNSAFE = Unsafe.getUnsafe(); + static long F_OFFSET; + + static class A { + Object f; + } + + static { + try { + Field fField = A.class.getDeclaredField("f"); + F_OFFSET = UNSAFE.objectFieldOffset(fField); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + static Object testHelper(boolean flag, Object o, long offset, Object x) { + if (flag) { + return UNSAFE.getAndSetObject(o, offset, x); + } + return null; + } + + static Object field; + + + static Object test1(boolean flag, Object o, long offset) { + return testHelper(flag, null, offset, field); + } + + static Object test2(Object o, long offset) { + return UNSAFE.getAndSetObject(o, offset, field); + } + + static public void main(String[] args) { + A a = new A(); + for (int i = 0; i < 20_000; i++) { + testHelper(true, a, F_OFFSET, null); + test1(false, a, F_OFFSET); + test2(a, F_OFFSET); + } + } +} diff --git a/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java b/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java index 32147e86d17..27256facaf6 100644 --- a/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java +++ b/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java @@ -377,10 +377,8 @@ public static void main(String[] args) { forceDeduplication(ageThreshold, FullGC); - if (!waitForDeduplication(dupString3, baseString)) { - if (getValue(dupString3) != getValue(internedString)) { - throw new RuntimeException("String 3 doesn't match either"); - } + if (!waitForDeduplication(dupString3, internedString)) { + throw new RuntimeException("Deduplication has not occurred for string 3"); } if (afterInternedValue != getValue(dupString2)) { diff --git a/test/hotspot/jtreg/gtest/GTestResultParser.java b/test/hotspot/jtreg/gtest/GTestResultParser.java index c30ea63e654..ffa98bf29f2 100644 --- a/test/hotspot/jtreg/gtest/GTestResultParser.java +++ b/test/hotspot/jtreg/gtest/GTestResultParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, 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 @@ -57,7 +57,10 @@ public GTestResultParser(Path file) { testCase = xmlReader.getAttributeValue("", "name"); break; case "failure": - failedTests.add(testSuite + "::" + testCase); + String failedStr = testSuite + "::" + testCase; + if (!failedTests.contains(failedStr)) { + failedTests.add(failedStr); + } break; default: // ignore diff --git a/test/hotspot/jtreg/gtest/NativeHeapTrimmerGtest.java b/test/hotspot/jtreg/gtest/NativeHeapTrimmerGtest.java index 7aa3dd8a322..259ed5b5146 100644 --- a/test/hotspot/jtreg/gtest/NativeHeapTrimmerGtest.java +++ b/test/hotspot/jtreg/gtest/NativeHeapTrimmerGtest.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2023 Red Hat, Inc. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,5 +28,5 @@ * @library /test/lib * @modules java.base/jdk.internal.misc * java.xml - * @run main/native GTestWrapper --gtest_filter=os.trim* -Xlog:trimnative -XX:+UnlockExperimentalVMOptions -XX:TrimNativeHeapInterval=100 + * @run main/native GTestWrapper --gtest_filter=os.trim* -Xlog:trimnative -XX:TrimNativeHeapInterval=100 */ diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/BadNativeStackInErrorHandlingTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/BadNativeStackInErrorHandlingTest.java index 64faeada1eb..a51a891b031 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/BadNativeStackInErrorHandlingTest.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/BadNativeStackInErrorHandlingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -35,6 +35,7 @@ * @bug 8194652 * @summary Printing native stack shows an "error occurred during error reporting". * @modules java.base/jdk.internal.misc + * @requires vm.flagless * @requires vm.debug * @requires vm.flavor != "zero" * @library /test/lib diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileOverwriteTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileOverwriteTest.java index c9b9e433e18..ea8e944aebb 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileOverwriteTest.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileOverwriteTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, SAP. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -30,6 +30,7 @@ * in the error file name) * @library /test/lib * @modules java.base/jdk.internal.misc + * @requires vm.flagless * @requires (vm.debug == true) * @run driver ErrorFileOverwriteTest */ diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileRedirectTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileRedirectTest.java index 154d5cf0e12..3c32c6f8141 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileRedirectTest.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileRedirectTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, SAP. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,6 +29,7 @@ * @summary Test ErrorFileToStderr and ErrorFileToStdout * @library /test/lib * @modules java.base/jdk.internal.misc + * @requires vm.flagless * @requires (vm.debug == true) * @run driver ErrorFileRedirectTest */ diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/MachCodeFramesInErrorFile.java b/test/hotspot/jtreg/runtime/ErrorHandling/MachCodeFramesInErrorFile.java index 0095c835d2d..1e91c2529f5 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/MachCodeFramesInErrorFile.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/MachCodeFramesInErrorFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, 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,7 @@ /* * @test * @bug 8272586 + * @requires vm.flagless * @requires vm.compiler2.enabled * @summary Test that abstract machine code is dumped for the top frames in a hs-err log * @library /test/lib diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/NestedThreadsListHandleInErrorHandlingTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/NestedThreadsListHandleInErrorHandlingTest.java index d21c8a04ab6..c897de4fa45 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/NestedThreadsListHandleInErrorHandlingTest.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/NestedThreadsListHandleInErrorHandlingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -33,6 +33,7 @@ /* * @test + * @requires vm.flagless * @requires (vm.debug == true) * @bug 8167108 * @summary Nested ThreadsListHandle info should be in error handling output. diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/ProblematicFrameTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/ProblematicFrameTest.java index 0f0b48bedec..dc54b09156c 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/ProblematicFrameTest.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/ProblematicFrameTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, 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 @@ -30,6 +30,7 @@ * java.compiler * java.management * jdk.internal.jvmstat/sun.jvmstat.monitor + * @requires vm.flagless * @run driver ProblematicFrameTest */ diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/SafeFetchInErrorHandlingTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/SafeFetchInErrorHandlingTest.java index 8f3419d88e8..241d41878fe 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/SafeFetchInErrorHandlingTest.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/SafeFetchInErrorHandlingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -36,6 +36,7 @@ * @summary SafeFetch32 and SafeFetchN do not work in error handling * @modules java.base/jdk.internal.misc * @library /test/lib + * @requires vm.flagless * @requires vm.debug * @requires vm.flavor != "zero" * @author Thomas Stuefe (SAP) diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java index 7790d069ac3..8fa7fd5c6be 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, 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 @@ * @bug 8065896 * @summary Synchronous signals during error reporting may terminate or hang VM process * @library /test/lib + * @requires vm.flagless * @requires vm.debug * @requires os.family != "windows" * @author Thomas Stuefe (SAP) diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/ShowRegistersOnAssertTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/ShowRegistersOnAssertTest.java index f0e44564a0e..098818e6676 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/ShowRegistersOnAssertTest.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/ShowRegistersOnAssertTest.java @@ -27,6 +27,7 @@ * @bug 8191101 * @summary Show Registers on assert/guarantee * @library /test/lib + * @requires vm.flagless * @requires (vm.debug == true) & (os.family == "linux") * @author Thomas Stuefe (SAP) * @modules java.base/jdk.internal.misc diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TestCrashOnOutOfMemoryError.java b/test/hotspot/jtreg/runtime/ErrorHandling/TestCrashOnOutOfMemoryError.java index 3ef7c868462..2b33f4ffb53 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/TestCrashOnOutOfMemoryError.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestCrashOnOutOfMemoryError.java @@ -26,6 +26,7 @@ * @summary Test using -XX:+CrashOnOutOfMemoryError * @modules java.base/jdk.internal.misc * @library /test/lib + * @requires vm.flagless * @run driver TestCrashOnOutOfMemoryError * @bug 8138745 */ diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TestExitOnOutOfMemoryError.java b/test/hotspot/jtreg/runtime/ErrorHandling/TestExitOnOutOfMemoryError.java index 2159442c08c..e56ed4a1b03 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/TestExitOnOutOfMemoryError.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestExitOnOutOfMemoryError.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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,6 +26,7 @@ * @summary Test using -XX:ExitOnOutOfMemoryError * @modules java.base/jdk.internal.misc * @library /test/lib + * @requires vm.flagless * @run driver TestExitOnOutOfMemoryError * @bug 8138745 */ diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TestGZippedHeapDumpOnOutOfMemoryError.java b/test/hotspot/jtreg/runtime/ErrorHandling/TestGZippedHeapDumpOnOutOfMemoryError.java index 40f6a6e4705..a2a0154f0b3 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/TestGZippedHeapDumpOnOutOfMemoryError.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestGZippedHeapDumpOnOutOfMemoryError.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 SAP SE. All rights reserved. + * Copyright (c) 2023, 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 @@ -32,6 +33,7 @@ * @test * @summary Test verifies that -XX:HeapDumpGzipLevel=1 works * @library /test/lib + * @requires vm.flagless * @run driver/timeout=240 TestGZippedHeapDumpOnOutOfMemoryError run 1 */ diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpOnOutOfMemoryError.java b/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpOnOutOfMemoryError.java index d5293cde704..9324adbb2e0 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpOnOutOfMemoryError.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpOnOutOfMemoryError.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,6 +25,7 @@ * @test TestHeapDumpOnOutOfMemoryError * @summary Test verifies that -XX:HeapDumpOnOutOfMemoryError dumps heap when OutOfMemory is thrown in heap * @library /test/lib + * @requires vm.flagless * @run driver TestHeapDumpOnOutOfMemoryError run heap */ @@ -32,6 +33,7 @@ * @test TestHeapDumpOnOutOfMemoryError * @summary Test verifies that -XX:HeapDumpOnOutOfMemoryError dumps heap when OutOfMemory is thrown in metaspace. * @library /test/lib + * @requires vm.flagless * @run driver/timeout=240 TestHeapDumpOnOutOfMemoryError run metaspace */ diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpPath.java b/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpPath.java index b1c4dc0c357..0cc6dbc765f 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpPath.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,6 +25,7 @@ * @test TestHeapDumpPath * @summary Test verifies that -XX:HeapDumpPath= supports directory as a parameter. * @library /test/lib + * @requires vm.flagless * @run driver TestHeapDumpPath */ diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TestOnError.java b/test/hotspot/jtreg/runtime/ErrorHandling/TestOnError.java index 776d1c9dfe7..00475f8bdd7 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/TestOnError.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestOnError.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ * @summary Test using -XX:OnError= * @modules java.base/jdk.internal.misc * @library /test/lib + * @requires vm.flagless * @requires vm.debug * @run driver TestOnError */ diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TestOnOutOfMemoryError.java b/test/hotspot/jtreg/runtime/ErrorHandling/TestOnOutOfMemoryError.java index 6d72bd59b6d..fe3c5c34f80 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/TestOnOutOfMemoryError.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestOnOutOfMemoryError.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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,6 +26,7 @@ * @summary Test using single and multiple -XX:OnOutOfMemoryError= * @modules java.base/jdk.internal.misc * @library /test/lib + * @requires vm.flagless * @run driver TestOnOutOfMemoryError * @bug 8078470 8177522 */ diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/ThreadsListHandleInErrorHandlingTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/ThreadsListHandleInErrorHandlingTest.java index 5ab7ad6c1b4..968337984e1 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/ThreadsListHandleInErrorHandlingTest.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/ThreadsListHandleInErrorHandlingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -38,6 +38,7 @@ * @summary ThreadsListHandle info should be in error handling output. * @modules java.base/jdk.internal.misc * @library /test/lib + * @requires vm.flagless * @run driver ThreadsListHandleInErrorHandlingTest */ diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TimeoutInErrorHandlingTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/TimeoutInErrorHandlingTest.java index 3aba36e1880..5111a229dbc 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/TimeoutInErrorHandlingTest.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/TimeoutInErrorHandlingTest.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2023, Red Hat, Inc. and/or its affiliates. - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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,6 +41,7 @@ * @summary Hanging Error Reporting steps may lead to torn error logs * @modules java.base/jdk.internal.misc * @library /test/lib + * @requires vm.flagless * @requires (vm.debug == true) & (os.family != "windows") * @run driver TimeoutInErrorHandlingTest * @author Thomas Stuefe (SAP) @@ -52,6 +53,7 @@ * @summary Error handling step timeouts should never be blocked by OnError etc. * @modules java.base/jdk.internal.misc * @library /test/lib + * @requires vm.flagless * @requires (vm.debug == true) & (os.family != "windows") * @run driver TimeoutInErrorHandlingTest with-on-error */ diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/VeryEarlyAssertTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/VeryEarlyAssertTest.java index 09b5c045684..4395775c872 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/VeryEarlyAssertTest.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/VeryEarlyAssertTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, SAP. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,6 +29,7 @@ * @summary No hs-err file if fatal error is raised during dynamic initialization. * @library /test/lib * @modules java.base/jdk.internal.misc + * @requires vm.flagless * @requires (vm.debug == true) * @requires os.family == "linux" * @run driver VeryEarlyAssertTest @@ -49,8 +50,7 @@ public class VeryEarlyAssertTest { public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-version"); + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-version"); Map env = pb.environment(); env.put("HOTSPOT_FATAL_ERROR_DURING_DYNAMIC_INITIALIZATION", "1"); diff --git a/test/hotspot/jtreg/runtime/Monitor/MonitorUnlinkBatchTest.java b/test/hotspot/jtreg/runtime/Monitor/MonitorUnlinkBatchTest.java new file mode 100644 index 00000000000..03cca277a28 --- /dev/null +++ b/test/hotspot/jtreg/runtime/Monitor/MonitorUnlinkBatchTest.java @@ -0,0 +1,178 @@ +/* + * Copyright Amazon.com Inc. 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 jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/* + * @test id=defaults + * @bug 8319048 + * @summary Test the MonitorUnlinkBatch options + * @library /test/lib + * @run driver MonitorUnlinkBatchTest defaults + */ + +/* + * @test id=legal + * @library /test/lib + * @run driver MonitorUnlinkBatchTest legal + */ + +/* + * @test id=illegal + * @library /test/lib + * @run driver MonitorUnlinkBatchTest illegal + */ + +/* + * @test id=aggressive + * @library /test/lib + * @run driver MonitorUnlinkBatchTest aggressive + */ + +/* + * @test id=lazy + * @library /test/lib + * @run driver MonitorUnlinkBatchTest lazy + */ + + +public class MonitorUnlinkBatchTest { + + public static class Test { + // Inflate a lot of monitors, so that threshold heuristics definitely fires + private static final int MONITORS = 10_000; + + // Use a handful of threads to inflate the monitors, to eat the cost of + // wait(1) calls. This can be larger than available parallelism, since threads + // would be time-waiting. + private static final int THREADS = 16; + + private static Thread[] threads; + private static Object[] monitors; + + public static void main(String... args) throws Exception { + monitors = new Object[MONITORS]; + threads = new Thread[THREADS]; + + for (int t = 0; t < THREADS; t++) { + int monStart = t * MONITORS / THREADS; + int monEnd = (t + 1) * MONITORS / THREADS; + threads[t] = new Thread(() -> { + for (int m = monStart; m < monEnd; m++) { + Object o = new Object(); + synchronized (o) { + try { + o.wait(1); + } catch (InterruptedException e) { + } + } + monitors[m] = o; + } + }); + threads[t].start(); + } + + for (Thread t : threads) { + t.join(); + } + + try { + Thread.sleep(10_000); + } catch (InterruptedException ie) { + } + } + } + + public static void main(String[] args) throws Exception { + if (args.length < 1) { + throw new IllegalArgumentException("Expect the test label"); + } + + String test = args[0]; + switch (test) { + case "defaults": + test(""); + break; + + case "legal": + // Legal, even if not useful settings + test("", + "-XX:MonitorDeflationMax=100000", + "-XX:MonitorUnlinkBatch=100001" + ); + break; + + case "illegal": + // Quick tests that should fail on JVM flags verification. + test("outside the allowed range", + "-XX:MonitorUnlinkBatch=-1" + ); + test("outside the allowed range", + "-XX:MonitorUnlinkBatch=0" + ); + break; + + case "aggressive": + // The smallest batch possible. + test("", + "-XX:MonitorUnlinkBatch=1" + ); + break; + + case "lazy": + // The largest batch possible. + test("", + "-XX:MonitorDeflationMax=1000000", + "-XX:MonitorUnlinkBatch=1000000" + ); + break; + + default: + throw new IllegalArgumentException("Unknown test: " + test); + } + } + + public static void test(String msg, String... args) throws Exception { + List opts = new ArrayList<>(); + opts.add("-Xmx128M"); + opts.add("-XX:+UnlockDiagnosticVMOptions"); + opts.add("-XX:GuaranteedAsyncDeflationInterval=100"); + opts.addAll(Arrays.asList(args)); + opts.add("MonitorUnlinkBatchTest$Test"); + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(opts); + OutputAnalyzer oa = new OutputAnalyzer(pb.start()); + if (msg.isEmpty()) { + oa.shouldHaveExitValue(0); + } else { + oa.shouldNotHaveExitValue(0); + oa.shouldContain(msg); + } + } + +} diff --git a/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java b/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java index f5ec01e43a6..261ec205d39 100644 --- a/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java +++ b/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java @@ -27,6 +27,7 @@ * @bug 8303215 8312182 * @summary On THP=always systems, we prevent THPs from forming within thread stacks * @library /test/lib + * @requires vm.flagless * @requires os.family == "linux" * @requires vm.debug * @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" @@ -40,6 +41,7 @@ * @bug 8303215 8312182 * @summary On THP=always systems, we prevent THPs from forming within thread stacks (negative test) * @library /test/lib + * @requires vm.flagless * @requires os.family == "linux" * @requires vm.debug * @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" diff --git a/test/hotspot/jtreg/runtime/os/TestHugePageDetection.java b/test/hotspot/jtreg/runtime/os/TestHugePageDetection.java index 2dac98000f5..80d7df080d0 100644 --- a/test/hotspot/jtreg/runtime/os/TestHugePageDetection.java +++ b/test/hotspot/jtreg/runtime/os/TestHugePageDetection.java @@ -26,6 +26,7 @@ * @test * @summary Test that the JVM detects the OS hugepage/THP settings correctly. * @library /test/lib + * @requires vm.flagless * @requires os.family == "linux" * @modules java.base/jdk.internal.misc * java.management diff --git a/test/hotspot/jtreg/runtime/os/TestTrimNative.java b/test/hotspot/jtreg/runtime/os/TestTrimNative.java index f1aed48b88e..3c64f008e3a 100644 --- a/test/hotspot/jtreg/runtime/os/TestTrimNative.java +++ b/test/hotspot/jtreg/runtime/os/TestTrimNative.java @@ -1,7 +1,7 @@ /* * Copyright (c) 2023 SAP SE. All rights reserved. - * Copyright (c) 2023 Red Hat, Inc. All rights reserved. - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Red Hat, Inc. All rights reserved. + * Copyright (c) 2023, 2024, 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,6 +26,7 @@ /* * @test id=trimNative + * @requires vm.flagless * @requires (os.family=="linux") & !vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib @@ -36,6 +37,7 @@ /* * @test id=trimNativeStrict + * @requires vm.flagless * @requires (os.family=="linux") & !vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib @@ -47,6 +49,7 @@ /* * @test id=trimNativeHighInterval * @summary High interval trimming should not even kick in for short program runtimes + * @requires vm.flagless * @requires (os.family=="linux") & !vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib @@ -58,6 +61,7 @@ /* * @test id=trimNativeLowInterval * @summary Very low (sub-second) interval, nothing should explode + * @requires vm.flagless * @requires (os.family=="linux") & !vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib @@ -69,6 +73,7 @@ /* * @test id=trimNativeLowIntervalStrict * @summary Very low (sub-second) interval, nothing should explode (stricter test, manual mode) + * @requires vm.flagless * @requires (os.family=="linux") & !vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib @@ -80,6 +85,7 @@ /* * @test id=testOffByDefault * @summary Test that trimming is disabled by default + * @requires vm.flagless * @requires (os.family=="linux") & !vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib @@ -91,6 +97,7 @@ /* * @test id=testOffExplicit * @summary Test that trimming can be disabled explicitly + * @requires vm.flagless * @requires (os.family=="linux") & !vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib @@ -102,6 +109,7 @@ /* * @test id=testOffOnNonCompliantPlatforms * @summary Test that trimming is correctly reported as unavailable if unavailable + * @requires vm.flagless * @requires (os.family!="linux") | vm.musl * @modules java.base/jdk.internal.misc * @library /test/lib @@ -270,7 +278,7 @@ public static void main(String[] args) throws Exception { long trimInterval = 500; // twice per second long ms1 = System.currentTimeMillis(); OutputAnalyzer output = runTestWithOptions( - new String[] { "-XX:+UnlockExperimentalVMOptions", "-XX:TrimNativeHeapInterval=" + trimInterval }, + new String[] { "-XX:TrimNativeHeapInterval=" + trimInterval }, new String[] { TestTrimNative.Tester.class.getName(), "5000" } ); long ms2 = System.currentTimeMillis(); @@ -285,7 +293,7 @@ public static void main(String[] args) throws Exception { case "trimNativeHighInterval": { OutputAnalyzer output = runTestWithOptions( - new String[] { "-XX:+UnlockExperimentalVMOptions", "-XX:TrimNativeHeapInterval=" + Integer.MAX_VALUE }, + new String[] { "-XX:TrimNativeHeapInterval=" + Integer.MAX_VALUE }, new String[] { TestTrimNative.Tester.class.getName(), "5000" } ); checkExpectedLogMessages(output, true, Integer.MAX_VALUE); @@ -297,7 +305,7 @@ public static void main(String[] args) throws Exception { case "trimNativeLowIntervalStrict": { long ms1 = System.currentTimeMillis(); OutputAnalyzer output = runTestWithOptions( - new String[] { "-XX:+UnlockExperimentalVMOptions", "-XX:TrimNativeHeapInterval=1" }, + new String[] { "-XX:TrimNativeHeapInterval=1" }, new String[] { TestTrimNative.Tester.class.getName(), "0" } ); long ms2 = System.currentTimeMillis(); @@ -308,7 +316,7 @@ public static void main(String[] args) throws Exception { case "testOffOnNonCompliantPlatforms": { OutputAnalyzer output = runTestWithOptions( - new String[] { "-XX:+UnlockExperimentalVMOptions", "-XX:TrimNativeHeapInterval=1" }, + new String[] { "-XX:TrimNativeHeapInterval=1" }, new String[] { "-version" } ); checkExpectedLogMessages(output, false, 0); @@ -319,7 +327,7 @@ public static void main(String[] args) throws Exception { case "testOffExplicit": { OutputAnalyzer output = runTestWithOptions( - new String[] { "-XX:+UnlockExperimentalVMOptions", "-XX:TrimNativeHeapInterval=0" }, + new String[] { "-XX:TrimNativeHeapInterval=0" }, new String[] { "-version" } ); checkExpectedLogMessages(output, false, 0); diff --git a/test/hotspot/jtreg/serviceability/attach/ShMemLongName.java b/test/hotspot/jtreg/serviceability/attach/ShMemLongName.java index bd491a1628b..bf90dd9a08c 100644 --- a/test/hotspot/jtreg/serviceability/attach/ShMemLongName.java +++ b/test/hotspot/jtreg/serviceability/attach/ShMemLongName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -95,7 +95,6 @@ private static void log(String s) { private static ProcessBuilder getTarget(String shmemName) throws IOException { log("starting target with shmem name: '" + shmemName + "'..."); return ProcessTools.createJavaProcessBuilder( - "-Xdebug", "-Xrunjdwp:transport=" + transport + ",server=y,suspend=n,address=" + shmemName, "ShMemLongName$Target"); } diff --git a/test/hotspot/jtreg/serviceability/jdwp/AllModulesCommandTest.java b/test/hotspot/jtreg/serviceability/jdwp/AllModulesCommandTest.java index dc6c05338ea..3c799f6e54d 100644 --- a/test/hotspot/jtreg/serviceability/jdwp/AllModulesCommandTest.java +++ b/test/hotspot/jtreg/serviceability/jdwp/AllModulesCommandTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, 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 @@ -82,7 +82,7 @@ private void doJdwp() throws Exception { try { // Establish JDWP socket connection channel = new JdwpChannel(); - channel.connect(); + channel.connect(launcher.getJdwpPort()); // Send out ALLMODULES JDWP command // and verify the reply JdwpAllModulesReply reply = new JdwpAllModulesCmd().send(channel); diff --git a/test/hotspot/jtreg/serviceability/jdwp/DebuggeeLauncher.java b/test/hotspot/jtreg/serviceability/jdwp/DebuggeeLauncher.java index 259c9ac0f6c..5c3d01ec2dc 100644 --- a/test/hotspot/jtreg/serviceability/jdwp/DebuggeeLauncher.java +++ b/test/hotspot/jtreg/serviceability/jdwp/DebuggeeLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, 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 @@ -21,11 +21,9 @@ * questions. */ -import java.io.IOException; -import java.net.ServerSocket; import java.util.StringTokenizer; import jdk.test.lib.JDKToolFinder; -import jdk.test.lib.Utils; +import jdk.test.lib.JDWP; import static jdk.test.lib.Asserts.assertFalse; /** @@ -55,7 +53,7 @@ public interface Listener { void onDebuggeeError(String line); } - private static int jdwpPort = -1; + private int jdwpPort = -1; private static final String CLS_DIR = System.getProperty("test.classes", "").trim(); private static final String DEBUGGEE = "AllModulesCommandTestDebuggee"; private Process p; @@ -117,30 +115,19 @@ public void terminateDebuggee() { * @return the JDWP options to start the debuggee with */ private static String getJdwpOptions() { - return "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=" + getJdwpPort(); + return "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0"; } /** - * Find an available port for the JDWP session + * Gets JDWP port debuggee is listening on. * * @return JDWP port */ - public static int getJdwpPort() { - if (jdwpPort == -1) { - jdwpPort = findFreePort(); - assertFalse(jdwpPort == -1, "Can not find vailbale port for JDWP"); - } + public int getJdwpPort() { + assertFalse(jdwpPort == -1, "JDWP port is not detected"); return jdwpPort; } - private static int findFreePort() { - try (ServerSocket socket = new ServerSocket(0)) { - return socket.getLocalPort(); - } catch (IOException e) { - } - return -1; - } - @Override public void onStringRead(StreamHandler handler, String line) { if (handler.equals(errorHandler)) { @@ -152,6 +139,12 @@ public void onStringRead(StreamHandler handler, String line) { } private void processDebuggeeOutput(String line) { + if (jdwpPort == -1) { + JDWP.ListenAddress addr = JDWP.parseListenAddress(line); + if (addr != null) { + jdwpPort = Integer.parseInt(addr.address()); + } + } StringTokenizer st = new StringTokenizer(line); String token = st.nextToken(); switch (token) { diff --git a/test/hotspot/jtreg/serviceability/jdwp/JdwpChannel.java b/test/hotspot/jtreg/serviceability/jdwp/JdwpChannel.java index d2e780c802f..ca27fc52e1e 100644 --- a/test/hotspot/jtreg/serviceability/jdwp/JdwpChannel.java +++ b/test/hotspot/jtreg/serviceability/jdwp/JdwpChannel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, 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 @@ -33,8 +33,8 @@ public class JdwpChannel { private Socket sock; - public void connect() throws IOException { - sock = new Socket("localhost", DebuggeeLauncher.getJdwpPort()); + public void connect(int jdwpPort) throws IOException { + sock = new Socket("localhost", jdwpPort); handshake(); } diff --git a/test/hotspot/jtreg/serviceability/sa/TestJmapCoreMetaspace.java b/test/hotspot/jtreg/serviceability/sa/TestJmapCoreMetaspace.java index 3dd060be231..b8e00e53848 100644 --- a/test/hotspot/jtreg/serviceability/sa/TestJmapCoreMetaspace.java +++ b/test/hotspot/jtreg/serviceability/sa/TestJmapCoreMetaspace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -23,7 +23,7 @@ /** * @test TestJmapCoreMetaspace - * @summary Test verifies that jhsdb jmap could generate heap dump from core when metspace is full + * @summary Test verifies that jhsdb jmap could generate heap dump from core when metaspace is full * @requires vm.hasSA * @library /test/lib * @run driver/timeout=480 TestJmapCore run metaspace diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/CircularListHigh/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/CircularListHigh/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/CircularListHigh/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/CircularListLow/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/CircularListLow/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/CircularListLow/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/DoubleArrayHigh/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/DoubleArrayHigh/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/DoubleArrayHigh/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/DoubleArrayLow/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/DoubleArrayLow/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/DoubleArrayLow/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/FloatArrayHigh/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/FloatArrayHigh/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/FloatArrayHigh/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/FloatArrayLow/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/FloatArrayLow/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/FloatArrayLow/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/LinearListHigh/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/LinearListHigh/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/LinearListHigh/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/LinearListLow/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/LinearListLow/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/LinearListLow/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/NonbranchyTreeHigh/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/NonbranchyTreeHigh/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/NonbranchyTreeHigh/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/NonbranchyTreeLow/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/NonbranchyTreeLow/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/NonbranchyTreeLow/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/ObjectArrayHigh/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/ObjectArrayHigh/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/ObjectArrayHigh/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/ObjectArrayLow/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/ObjectArrayLow/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/ObjectArrayLow/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/gc/vector/SimpleGC/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/vector/SimpleGC/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/gc/vector/SimpleGC/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/AttachingConnector/attach/attach001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/AttachingConnector/attach/attach001.java index b893fca06f4..8203095e3fc 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/AttachingConnector/attach/attach001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/AttachingConnector/attach/attach001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, 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 @@ -34,6 +34,7 @@ import java.util.List; import java.util.Map; +import jdk.test.lib.JDWP; import nsk.share.*; import nsk.share.jpda.*; import nsk.share.jdi.*; @@ -69,9 +70,6 @@ public static int run(String argv[], PrintStream out) { } private int runIt(String argv[], PrintStream out) { - String port; - String listenPort; - Process proc; ArgumentHandler argHandler = new ArgumentHandler(argv); // pass if "com.sun.jdi.SocketAttach" is not implemented @@ -96,19 +94,17 @@ private int runIt(String argv[], PrintStream out) { long timeout = argHandler.getWaitTime() * 60 * 1000; attempts = (int)(timeout / delay); - port = argHandler.getTransportPort(); - listenPort = argHandler.getTransportPort(); - String java = argHandler.getLaunchExecPath() + " " + argHandler.getLaunchOptions(); - String cmd = java + - " -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,address=" + - listenPort + " " + DEBUGEE_CLASS; + String cmd = java + + " -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,address=0" + + " " + DEBUGEE_CLASS; Binder binder = new Binder(argHandler, log); log.display("command: " + cmd); Debugee debugee = binder.startLocalDebugee(cmd); - debugee.redirectOutput(log); + JDWP.ListenAddress listenAddress = debugee.redirectOutputAndDetectListeningAddress(log); + String port = listenAddress.address(); if ((vm = attachTarget(argHandler.getTestHost(), port)) == null) { log.complain("TEST: Unable to attach the debugee VM"); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/AttachingConnector/attach/attach004/TestDriver.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/AttachingConnector/attach/attach004/TestDriver.java index 07d78e47096..1860b612829 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/AttachingConnector/attach/attach004/TestDriver.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/AttachingConnector/attach/attach004/TestDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -92,7 +92,6 @@ private static Process startDebuggee(String[] jdiArgs, String transport, String Collections.addAll(cmd, Utils.prependTestJavaOpts( "-cp", Utils.TEST_CLASS_PATH, - "-Xdebug", "-agentlib:jdwp=transport=" + transport + ",server=y,suspend=" + suspend, "-Dmy.little.cookie=" + ProcessHandle.current().pid(), debuggeeClass.getName())); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/AttachingConnector/attachnosuspend/attachnosuspend001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/AttachingConnector/attachnosuspend/attachnosuspend001.java index a3c5a27178a..e5bd791b1ed 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/AttachingConnector/attachnosuspend/attachnosuspend001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/AttachingConnector/attachnosuspend/attachnosuspend001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2021, 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 @@ -34,6 +34,7 @@ import java.util.List; import java.util.Map; +import jdk.test.lib.JDWP; import nsk.share.*; import nsk.share.jpda.*; import nsk.share.jdi.*; @@ -69,9 +70,6 @@ public static int run(String argv[], PrintStream out) { } private int runIt(String argv[], PrintStream out) { - String port; - String listenPort; - Process proc; ArgumentHandler argHandler = new ArgumentHandler(argv); // pass if "com.sun.jdi.SocketAttach" is not implemented @@ -96,19 +94,17 @@ private int runIt(String argv[], PrintStream out) { long timeout = argHandler.getWaitTime() * 60 * 1000; attempts = (int)(timeout / delay); - port = argHandler.getTransportPort(); - listenPort = argHandler.getTransportPort(); - String java = argHandler.getLaunchExecPath() + " " + argHandler.getLaunchOptions(); - String cmd = java + - " -Xdebug -Xnoagent -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=" + - listenPort + " " + DEBUGEE_CLASS; + String cmd = java + + " -Xdebug -Xnoagent -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0" + + " " + DEBUGEE_CLASS; Binder binder = new Binder(argHandler, log); log.display("command: " + cmd); Debugee debugee = binder.startLocalDebugee(cmd); - debugee.redirectOutput(log); + JDWP.ListenAddress listenAddress = debugee.redirectOutputAndDetectListeningAddress(log); + String port = listenAddress.address(); if ((vm = attachTarget(argHandler.getTestHost(), port)) == null) { log.complain("TEST: Unable to attach the debugee VM"); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem001/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem001/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem001/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem002/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem002/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem002/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem003/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem003/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem003/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem004/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem004/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem004/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem005/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem005/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem005/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem006/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem006/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem006/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem007/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem007/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem007/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem008/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem008/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem008/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem009/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem009/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem009/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem010/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem010/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem010/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem011/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem011/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem011/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem012/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem012/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem012/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem013/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem013/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem013/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem014/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem014/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem014/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem015/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem015/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem015/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem016/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem016/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem016/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem017/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem017/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem017/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem018/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem018/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem018/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem019/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem019/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem019/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem020/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem020/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem020/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem021/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem021/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem021/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem022/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem022/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem022/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem023/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem023/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem023/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem024/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem024/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem024/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem025/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem025/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem025/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem026/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem026/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem026/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem027/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem027/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem027/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem028/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem028/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem028/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem029/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem029/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem029/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem030/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem030/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem030/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem031/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem031/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem031/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem032/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem032/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem032/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem033/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem033/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem033/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem034/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem034/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem034/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem035/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem035/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem035/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem036/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem036/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/lowmem/lowmem036/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/IORedirector.java b/test/hotspot/jtreg/vmTestbase/nsk/share/IORedirector.java index ea5076b24fa..19a58780a95 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/IORedirector.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/IORedirector.java @@ -24,6 +24,9 @@ package nsk.share; import java.io.*; +import java.util.LinkedList; +import java.util.List; +import java.util.function.Consumer; /** * This class implements a thread transfering bytes from @@ -31,13 +34,7 @@ */ public class IORedirector extends Thread { private BufferedReader bin = null; - private PrintStream pout = null; - private Log log = null; - - /** - * Few symbols to precede every text line being redirected. - */ - private String prefix = ""; + private List> processors = new LinkedList<>(); /** * Input and output streams must be specified. @@ -54,10 +51,16 @@ private IORedirector() { * @see #IORedirector(BufferedReader,Log,String) */ @Deprecated - public IORedirector(InputStream in, OutputStream out) { + public IORedirector(InputStream in, OutputStream out, String prefix) { this(); bin = new BufferedReader(new InputStreamReader(in)); - pout = new PrintStream(out); + PrintStream pout = new PrintStream(out); + addProcessor(s -> { + synchronized (pout) { + pout.println(prefix + s); + pout.flush(); + } + }); } /** @@ -67,16 +70,16 @@ public IORedirector(InputStream in, OutputStream out) { */ public IORedirector(BufferedReader in, Log log, String prefix) { this(); - this.prefix = prefix; this.bin = in; - this.log = log; + addProcessor(s -> log.println(prefix + s)); } - /** - * Set the prefix for redirected messages; - */ - public void setPrefix(String prefix) { - this.prefix = prefix; + public void addProcessor(Consumer lineProcessor) { + processors.add(lineProcessor); + } + + private void processLine(String line) { + processors.stream().forEach(processor -> processor.accept(line)); } private boolean cancelled = false; @@ -104,39 +107,20 @@ public void cancel () { */ public void run () { started = true; - String logPrefix = "IORedirector-" + prefix; - if (bin == null || (pout == null && log == null)) + if (bin == null || processors.isEmpty()) { return; + } try { while (!cancelled) { String line = bin.readLine(); if (line == null) break; //EOF - String message = prefix + line; - if (log != null) { - // It's synchronized and auto-flushed: - log.println(message); - } else if (pout != null) { - synchronized (pout) { - pout.println(message); - pout.flush(); - } - } + processLine(line); } } catch (IOException e) { // e.printStackTrace(log.getOutStream()); String msg = "# WARNING: Caught IOException while redirecting output stream:\n\t" + e; - if (log != null) { - log.println(msg); - } else if (pout != null) { - synchronized (pout) { - pout.println(msg); - pout.flush(); - } - } else { - System.err.println(msg); - System.err.flush(); - } + processLine(msg); }; stopped = true; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java index f5cfd11c56e..675cbbdfa2e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeBinder.java @@ -328,8 +328,6 @@ public String[] makeCommandLineArgs(String classToExecute, String transportAddre args.add(classPath); */ - args.add("-Xdebug"); - String server; if (argumentHandler.isAttachingConnector()) { server = "y"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeProcess.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeProcess.java index d10f3281799..10733307679 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeProcess.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeProcess.java @@ -23,9 +23,11 @@ package nsk.share.jpda; +import jdk.test.lib.JDWP; import nsk.share.*; import java.io.*; import java.net.*; +import java.util.function.Consumer; /** * This class is used to control debugee VM process. @@ -302,8 +304,7 @@ final public InputStream getStderr () { /** * Start thread redirecting the debugee's stdout to the - * given out stream. If the debugee's stdout - * was already redirected, the TestBug exception is thrown. + * given out stream. * * @deprecated Use redirectStdout(Log, String) instead. */ @@ -312,9 +313,7 @@ public void redirectStdout(OutputStream out) { if (stdoutRedirector != null) { return; } -// throw new TestBug("Debugee's stdout is already redirected"); - stdoutRedirector = new IORedirector(getOutPipe(),out); - stdoutRedirector.setPrefix(DEBUGEE_STDOUT_LOG_PREFIX); + stdoutRedirector = new IORedirector(getOutPipe(), out, DEBUGEE_STDOUT_LOG_PREFIX); stdoutRedirector.setName("IORedirector for stdout"); stdoutRedirector.setDaemon(true); stdoutRedirector.start(); @@ -322,16 +321,20 @@ public void redirectStdout(OutputStream out) { /** * Start thread redirecting the debugee's stdout to the - * given Log. If the debugee's stdout - * was already redirected, the TestBug exception is thrown. + * given Log. */ public void redirectStdout(Log log, String prefix) { + redirectStdout(log, prefix, null); + } + + private void redirectStdout(Log log, String prefix, Consumer stdoutProcessor) { if (stdoutRedirector != null) { -// stdoutRedirector.setPrefix(prefix); return; -// throw new TestBug("the debugee's stdout is already redirected"); } stdoutRedirector = new IORedirector(new BufferedReader(new InputStreamReader(getOutPipe())), log, prefix); + if (stdoutProcessor != null) { + stdoutRedirector.addProcessor(stdoutProcessor); + } stdoutRedirector.setName("IORedirector for stdout"); stdoutRedirector.setDaemon(true); stdoutRedirector.start(); @@ -339,8 +342,7 @@ public void redirectStdout(Log log, String prefix) { /** * Start thread redirecting the debugee's stderr to the - * given err stream. If the debugee's stderr - * was already redirected, the TestBug exception is thrown. + * given err stream. * * @deprecated Use redirectStderr(Log, String) instead. */ @@ -349,9 +351,7 @@ public void redirectStderr(OutputStream err) { if (stderrRedirector != null) { return; } -// throw new TestBug("Debugee's stderr is already redirected"); - stderrRedirector = new IORedirector(getErrPipe(),err); - stderrRedirector.setPrefix(DEBUGEE_STDERR_LOG_PREFIX); + stderrRedirector = new IORedirector(getErrPipe(), err, DEBUGEE_STDERR_LOG_PREFIX); stdoutRedirector.setName("IORedirector for stderr"); stderrRedirector.setDaemon(true); stderrRedirector.start(); @@ -359,14 +359,11 @@ public void redirectStderr(OutputStream err) { /** * Start thread redirecting the debugee's stderr to the - * given Log. If the debugee's stderr - * was already redirected, the TestBug exception is thrown. + * given Log. */ public void redirectStderr(Log log, String prefix) { if (stderrRedirector != null) { -// stderrRedirector.setPrefix(prefix); return; -// throw new TestBug("Debugee's stderr is already redirected"); } stderrRedirector = new IORedirector(new BufferedReader(new InputStreamReader(getErrPipe())), log, prefix); stdoutRedirector.setName("IORedirector for stderr"); @@ -377,13 +374,50 @@ public void redirectStderr(Log log, String prefix) { /** * Start thread redirecting the debugee's stdout/stderr to the * given Log using standard prefixes. - * If the debugee's stdout/stderr were already redirected, - * the TestBug exception is thrown. */ public void redirectOutput(Log log) { - redirectStdout(log, "debugee.stdout> "); - redirectStderr(log, "debugee.stderr> "); + redirectStdout(log, DEBUGEE_STDOUT_LOG_PREFIX); + redirectStderr(log, DEBUGEE_STDERR_LOG_PREFIX); + } + + /** + * Starts redirecting of the debugee's stdout/stderr to the + * given Log using standard prefixes + * and detects listening address from the debuggee stdout. + */ + public JDWP.ListenAddress redirectOutputAndDetectListeningAddress(Log log) { + JDWP.ListenAddress listenAddress[] = new JDWP.ListenAddress[1]; + Consumer stdoutProcessor = line -> { + JDWP.ListenAddress addr = JDWP.parseListenAddress(line); + if (addr != null) { + synchronized (listenAddress) { + listenAddress[0] = addr; + listenAddress.notifyAll(); + } + } + }; + + redirectStdout(log, DEBUGEE_STDOUT_LOG_PREFIX, stdoutProcessor); + redirectStderr(log, DEBUGEE_STDERR_LOG_PREFIX); + + synchronized (listenAddress) { + while (!terminated() && listenAddress[0] == null) { + try { + listenAddress.wait(500); + } catch (InterruptedException e) { + // ignore + } + } + } + if (terminated()) { + throw new Failure("Failed to detect debuggee listening port"); + } + + log.display("Debuggee is listening on port " + listenAddress[0].address()); + + return listenAddress[0]; } + // --------------------------------------------------- // /** diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp0mr30st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp0mr30st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp0mr30st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp0mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp0mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp0mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr0st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr0st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr0st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr30st0t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr30st0t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr30st0t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr70st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr70st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr70st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp30mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp70mr30st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp70mr30st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp70mr30st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp70mr30st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp70mr30st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp0rp70mr30st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp0mr30st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp0mr30st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp0mr30st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp0mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp0mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp0mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr0st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr0st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr0st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr30st0t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr30st0t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr30st0t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr70st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr70st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr70st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp30mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp70mr30st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp70mr30st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp70mr30st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp70mr30st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp70mr30st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp10rp70mr30st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp0mr30st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp0mr30st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp0mr30st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp0mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp0mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp0mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr0st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr0st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr0st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr30st0t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr30st0t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr30st0t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr70st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr70st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr70st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp30mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp70mr30st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp70mr30st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp70mr30st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp70mr30st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp70mr30st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp30yp25rp70mr30st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp0mr30st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp0mr30st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp0mr30st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp0mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp0mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp0mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr0st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr0st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr0st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr30st0t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr30st0t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr30st0t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr70st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr70st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr70st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp30mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp70mr30st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp70mr30st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp70mr30st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp70mr30st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp70mr30st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp0rp70mr30st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp0mr30st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp0mr30st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp0mr30st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp0mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp0mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp0mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr0st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr0st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr0st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr30st0t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr30st0t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr30st0t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr70st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr70st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr70st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr70st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr70st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp30mr70st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp70mr30st0/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp70mr30st0/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp70mr30st0/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp70mr30st300t1/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp70mr30st300t1/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp50yp10rp70mr30st300t1/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp60yp0rp30mr0st300/TEST.properties b/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp60yp0rp30mr0st300/TEST.properties deleted file mode 100644 index 04b22a107ac..00000000000 --- a/test/hotspot/jtreg/vmTestbase/vm/gc/concurrent/lp60yp0rp30mr0st300/TEST.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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. -# -exclusiveAccess.dirs=. diff --git a/test/jaxp/TEST.groups b/test/jaxp/TEST.groups index 0b67ed428b9..f8cb73c4393 100644 --- a/test/jaxp/TEST.groups +++ b/test/jaxp/TEST.groups @@ -20,6 +20,14 @@ # questions. # +# All tests + +all = \ + :jaxp_all + +jaxp_all = \ + / + # Tiered testing definitions # No jaxp tests are tier 1. @@ -34,6 +42,3 @@ tier3 = # No tier 4 tests. tier4 = - -jaxp_all = \ - javax/xml/jaxp diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 069ba66c962..fda4c400b9e 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -182,7 +182,7 @@ java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowRetaining.java 6829264 java/awt/datatransfer/DragImage/MultiResolutionDragImageTest.java 8080982 generic-all java/awt/datatransfer/SystemFlavorMap/AddFlavorTest.java 8079268 linux-all java/awt/Toolkit/RealSync/Test.java 6849383 linux-all -java/awt/LightweightComponent/LightweightEventTest/LightweightEventTest.java 8159252 windows-all +java/awt/LightweightComponent/LightweightEventTest/LightweightEventTest.java 8159252,8324782 windows-all,macosx-all java/awt/EventDispatchThread/HandleExceptionOnEDT/HandleExceptionOnEDT.java 8203047 macosx-all java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.java 8073636 macosx-all java/awt/FullScreen/FullScreenInsets/FullScreenInsets.java 7019055,8266245 windows-all,linux-all,macosx-all @@ -492,8 +492,8 @@ java/awt/event/KeyEvent/DeadKey/deadKeyMacOSX.java 8233568 macosx-all java/awt/Choice/ChoiceKeyEventReaction/ChoiceKeyEventReaction.java 7185258 macosx-all java/awt/TrayIcon/RightClickWhenBalloonDisplayed/RightClickWhenBalloonDisplayed.java 8238720 windows-all java/awt/PopupMenu/PopupMenuLocation.java 8238720 windows-all -java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java 8238720 windows-all -java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java 8238720 windows-all +java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java 8238720,8324782 windows-all,macosx-all +java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java 8238720,8324782 windows-all,macosx-all java/awt/event/MouseEvent/FrameMouseEventAbsoluteCoordsTest/FrameMouseEventAbsoluteCoordsTest.java 8238720 windows-all # Several tests which fail sometimes on macos11 @@ -509,6 +509,9 @@ java/awt/KeyboardFocusmanager/TypeAhead/ButtonActionKeyTest/ButtonActionKeyTest. java/awt/Window/GetScreenLocation/GetScreenLocationTest.java 8225787 linux-x64 java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 8266243 macosx-aarch64 +# This test fails on macOS 14 +java/awt/Choice/SelectNewItemTest/SelectNewItemTest.java 8324782 macosx-all + ############################################################################ # jdk_beans @@ -551,7 +554,6 @@ javax/management/monitor/DerivedGaugeMonitorTest.java 8042211 generic-al # jdk_io java/io/pathNames/GeneralWin32.java 8180264 windows-all -java/io/File/createTempFile/SpecialTempFile.java 8274122 windows11 ############################################################################ @@ -572,8 +574,6 @@ sun/management/jdp/JdpSpecificAddressTest.java 8241865 macosx-a javax/management/MBeanServer/OldMBeanServerTest.java 8030957 aix-all -javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java 8042215 generic-all - javax/management/remote/mandatory/connection/RMIConnector_NPETest.java 8267887 generic-all ############################################################################ @@ -650,17 +650,10 @@ com/sun/security/sasl/gsskerb/ConfSecurityLayer.java 8039280 generic- com/sun/security/sasl/gsskerb/NoSecurityLayer.java 8039280 generic-all javax/security/auth/kerberos/KerberosHashEqualsTest.java 8039280 generic-all javax/security/auth/kerberos/KerberosTixDateTest.java 8039280 generic-all -javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java 8286045 generic-all sun/security/provider/PolicyFile/GrantAllPermToExtWhenNoPolicy.java 8039280 generic-all sun/security/provider/PolicyParser/ExtDirsChange.java 8039280 generic-all sun/security/provider/PolicyParser/PrincipalExpansionError.java 8039280 generic-all -sun/security/tools/keytool/NssTest.java 8295343 linux-all -sun/security/pkcs11/Signature/TestRSAKeyLength.java 8295343 linux-all -sun/security/pkcs11/rsa/TestSignatures.java 8295343 linux-all -sun/security/pkcs11/rsa/TestKeyPairGenerator.java 8295343 linux-all -sun/security/pkcs11/rsa/TestKeyFactory.java 8295343 linux-all -sun/security/pkcs11/KeyStore/Basic.java 8295343 linux-all sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java 8316183 linux-ppc64le ############################################################################ @@ -697,7 +690,6 @@ javax/swing/JWindow/ShapedAndTranslucentWindows/TranslucentJComboBox.java 802462 javax/swing/JTree/DnD/LastNodeLowerHalfDrop.java 8159131 linux-all javax/swing/JTree/4633594/JTreeFocusTest.java 8173125 macosx-all javax/swing/AbstractButton/6711682/bug6711682.java 8060765 windows-all,macosx-all -javax/swing/JFileChooser/4524490/bug4524490.java 8042380 generic-all javax/swing/JFileChooser/6396844/TwentyThousandTest.java 8198003 generic-all javax/swing/JPopupMenu/6580930/bug6580930.java 7124313 macosx-all javax/swing/JPopupMenu/6800513/bug6800513.java 7184956 macosx-all @@ -732,6 +724,9 @@ sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java 8265770 macosx-all # jdk_text +# This test fails on macOS 14 +javax/swing/plaf/synth/7158712/bug7158712.java 8324782 macosx-all + ############################################################################ # jdk_time @@ -774,8 +769,6 @@ sun/util/locale/provider/CalendarDataRegression.java 8268379 macosx-x # svc_tools -sun/tools/jhsdb/BasicLauncherTest.java 8211767 linux-ppc64,linux-ppc64le - sun/tools/jstatd/TestJstatdDefaults.java 8081569,8226420 windows-all sun/tools/jstatd/TestJstatdRmiPort.java 8226420,8251259 windows-all sun/tools/jstatd/TestJstatdServer.java 8081569,8226420 windows-all @@ -789,8 +782,6 @@ sun/tools/jstat/jstatLineCounts4.sh 8248691,8268211 # jdk_other -javax/rmi/ssl/SSLSocketParametersTest.sh 8162906 generic-all - javax/script/Test7.java 8239361 generic-all ############################################################################ diff --git a/test/jdk/TEST.groups b/test/jdk/TEST.groups index 8fe9747526c..21793455ff9 100644 --- a/test/jdk/TEST.groups +++ b/test/jdk/TEST.groups @@ -20,6 +20,17 @@ # questions. # +############################################################################### +# +# All tests +# + +all = \ + :jdk_all + +jdk_all = \ + / + ############################################################################### # # Tiered testing definitions diff --git a/test/jdk/com/sun/jdi/JdwpAllowTest.java b/test/jdk/com/sun/jdi/JdwpAllowTest.java index 6fa29ba14ad..a5c756f8790 100644 --- a/test/jdk/com/sun/jdi/JdwpAllowTest.java +++ b/test/jdk/com/sun/jdi/JdwpAllowTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 @@ -34,16 +34,14 @@ import java.net.Socket; import java.net.SocketException; +import jdk.test.lib.JDWP; import jdk.test.lib.Utils; import jdk.test.lib.apps.LingeredApp; -import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class JdwpAllowTest { @@ -76,16 +74,14 @@ public static String[] prepareCmd(String allowOpt) { return new String[] { jdwpArgs }; } - private static Pattern listenRegexp = Pattern.compile("Listening for transport \\b(.+)\\b at address: \\b(\\d+)\\b"); private static int detectPort(LingeredApp app) { long maxWaitTime = System.currentTimeMillis() + Utils.adjustTimeout(10000); // 10 seconds adjusted for TIMEOUT_FACTOR while (true) { String s = app.getProcessStdout(); - Matcher m = listenRegexp.matcher(s); - if (m.find()) { - // m.group(1) is transport, m.group(2) is port - return Integer.parseInt(m.group(2)); + JDWP.ListenAddress addr = JDWP.parseListenAddress(s); + if (addr != null) { + return Integer.parseInt(addr.address()); } if (System.currentTimeMillis() > maxWaitTime) { throw new RuntimeException("Could not detect port from '" + s + "' (timeout)"); diff --git a/test/jdk/com/sun/jdi/RunToExit.java b/test/jdk/com/sun/jdi/RunToExit.java index b7051b77dbc..d5fd5d2b6f7 100644 --- a/test/jdk/com/sun/jdi/RunToExit.java +++ b/test/jdk/com/sun/jdi/RunToExit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2021, 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 @@ -40,9 +40,9 @@ import java.util.List; import java.util.Iterator; import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Collectors; + +import jdk.test.lib.JDWP; import jdk.test.lib.process.ProcessTools; public class RunToExit { @@ -95,16 +95,12 @@ private static Process launch(String class_name) throws Exception { return p; } - /* warm-up predicate for debuggee */ - private static Pattern listenRegexp = Pattern.compile("Listening for transport \\b(.+)\\b at address: \\b(.+)\\b"); - private static boolean isTransportListening(String line) { - Matcher m = listenRegexp.matcher(line); - if (!m.matches()) { + JDWP.ListenAddress addr = JDWP.parseListenAddress(line); + if (addr == null) { return false; } - // address is 2nd group - address = m.group(2); + address = addr.address(); return true; } diff --git a/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java b/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java index 2379a9e4625..55956ca5811 100644 --- a/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java +++ b/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java @@ -23,8 +23,8 @@ package lib.jdb; +import jdk.test.lib.JDWP; import jdk.test.lib.Utils; -import jdk.test.lib.util.Pair; import jdk.test.lib.process.ProcessTools; import java.io.Closeable; @@ -128,7 +128,7 @@ public ProcessBuilder prepare() { public Debuggee launch(String name) { return new Debuggee(prepare(), name, onthrow.isEmpty() ? - Launcher::parseListenAddress : + JDWP::parseListenAddress : Launcher::parseLaunchEchoListenAddress ); } @@ -140,47 +140,29 @@ public Debuggee launch() { * Parses debuggee output to get listening transport and address, printed by `launch=echo`. * Returns null if the string specified does not contain required info. */ - private static Pair parseLaunchEchoListenAddress(String debuggeeOutput) { + private static JDWP.ListenAddress parseLaunchEchoListenAddress(String debuggeeOutput) { Pattern listenRegexp = Pattern.compile(LAUNCH_ECHO_STRING + " \\b(.+)\\b \\b(.+)\\b"); Matcher m = listenRegexp.matcher(debuggeeOutput); if (m.find()) { - return new Pair(m.group(1), m.group(2)); - } - return null; - } - - /** - * Parses debuggee output to get listening transport and address, printed by `launch=echo`. - * Returns null if the string specified does not contain required info. - */ - private static Pair parseListenAddress(String debuggeeOutput) { - Pattern listenRegexp = Pattern.compile("Listening for transport \\b(.+)\\b at address: \\b(.+)\\b"); - Matcher m = listenRegexp.matcher(debuggeeOutput); - if (m.find()) { - return new Pair(m.group(1), m.group(2)); + return new JDWP.ListenAddress(m.group(1), m.group(2)); } return null; } } // starts the process, waits until the provided addressDetector detects transport/address from the process output - private Debuggee(ProcessBuilder pb, String name, Function> addressDetector) { - String[] debuggeeListen = new String[2]; + private Debuggee(ProcessBuilder pb, String name, Function addressDetector) { + JDWP.ListenAddress[] listenAddress = new JDWP.ListenAddress[1]; try { p = ProcessTools.startProcess(name, pb, s -> output.add(s), // output consumer s -> { - Pair addr = addressDetector.apply(s); - if (addr != null) { - debuggeeListen[0] = addr.first; - debuggeeListen[1] = addr.second; - return true; - } - return false; + listenAddress[0] = addressDetector.apply(s); + return listenAddress[0] != null; }, 30, TimeUnit.SECONDS); - transport = debuggeeListen[0]; - address = debuggeeListen[1]; + transport = listenAddress[0].transport(); + address = listenAddress[0].address(); } catch (IOException | InterruptedException | TimeoutException ex) { throw new RuntimeException("failed to launch debuggee", ex); } diff --git a/test/jdk/com/sun/jndi/ldap/LdapSSLHandshakeFailureTest.java b/test/jdk/com/sun/jndi/ldap/LdapSSLHandshakeFailureTest.java index 29f74d250f7..15d8f8b074c 100644 --- a/test/jdk/com/sun/jndi/ldap/LdapSSLHandshakeFailureTest.java +++ b/test/jdk/com/sun/jndi/ldap/LdapSSLHandshakeFailureTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, 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 @@ -21,68 +21,117 @@ * questions. */ -import jdk.test.lib.net.URIBuilder; - -import javax.naming.Context; -import javax.naming.ldap.InitialLdapContext; -import javax.naming.ldap.LdapContext; -import javax.net.SocketFactory; -import javax.net.ssl.SSLServerSocketFactory; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.lang.reflect.Field; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; +import java.net.UnknownHostException; import java.util.Hashtable; +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.ldap.InitialLdapContext; +import javax.naming.ldap.LdapContext; +import javax.net.SocketFactory; +import javax.net.ssl.SSLServerSocketFactory; + +import jdk.test.lib.net.URIBuilder; + /* * @test - * @bug 8314063 + * @bug 8314063 8325579 * @library /test/lib - * @summary For LDAPs connection, if the value of com.sun.jndi.ldap.connect.timeout is - * set too small or not an optimal value for the system, after the socket is created and - * connected to the server, but the handshake between the client and server fails due to - * socket time out, the opened socket is not closed properly. In this test case, the server - * is forced to sleep ten seconds and connection time out for client is one second. This - * will allow the socket opened and connected, and give the chance for the handshake to be - * timed out. Before this fix, the socket is kept opened. Right now the exception will be - * caught and the socket will be closed. + * @summary Several scenarios for LDAP connection handshaking are tested here. + * We test different combinations of com.sun.jndi.ldap.connect.timeout values + * and server behavior, e.g. a server that replies immediately vs a server that + * delays the initial answer. We also try to check whether the underlying Socket + * object will be closed correctly. + * We expect exceptions when using a custom SocketFactory that does not supply + * SSL Sockets. In that case we instrument the supplied Socket object and check + * if it was properly closed after the handshake failure. + * When the value of com.sun.jndi.ldap.connect.timeout is set lower than the + * server delay, we also expect an exception. + * In all other cases a valid Context object shall be returned and we check + * whether the socket is closed after closing the Context. * - * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactory true 6000 - * @run main/othervm LdapSSLHandshakeFailureTest -1000 true 6000 - * @run main/othervm LdapSSLHandshakeFailureTest -1000 false 6000 - * @run main/othervm LdapSSLHandshakeFailureTest 2000 false 6000 - * @run main/othervm LdapSSLHandshakeFailureTest 0 true 6000 - * @run main/othervm LdapSSLHandshakeFailureTest 0 false 6000 + * @modules java.naming/javax.naming:+open java.naming/com.sun.jndi.ldap:+open + * @run main/othervm LdapSSLHandshakeFailureTest * @run main/othervm LdapSSLHandshakeFailureTest true - * @run main/othervm LdapSSLHandshakeFailureTest false + * @run main/othervm LdapSSLHandshakeFailureTest 0 + * @run main/othervm LdapSSLHandshakeFailureTest 0 true + * @run main/othervm LdapSSLHandshakeFailureTest 2000 + * @run main/othervm LdapSSLHandshakeFailureTest 2000 true + * @run main/othervm LdapSSLHandshakeFailureTest -1000 + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactoryNoUnconnected + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactoryNoUnconnected 1000 + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactoryNoUnconnected true + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactoryNoUnconnected 1000 true + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactory + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactory 1000 + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactory true + * @run main/othervm LdapSSLHandshakeFailureTest LdapSSLHandshakeFailureTest$CustomSocketFactory 1000 true */ public class LdapSSLHandshakeFailureTest { - private static String SOCKET_CLOSED_MSG = "The socket has been closed."; + private static int SERVER_SLEEPING_TIME = 4000; + private static String progArgs[]; + private static int curArg; + private static String customSocketFactory; + private static Integer connectTimeout; + private static boolean serverSlowDown; + + private static String popArg() { + if (curArg >= progArgs.length) { + return null; + } + return progArgs[curArg++]; + } - private static int serverSleepingTime = 5000; + private static void parseArgs(String args[]) { + progArgs = args; + curArg = 0; - public static void main(String args[]) throws Exception { + String arg = popArg(); + if (arg == null) + return; - // Set the keystores - setKeyStore(); - boolean serverSlowDown = Boolean.valueOf(args[0]); - if (args.length == 2) { - serverSlowDown = Boolean.valueOf(args[1]); + if (arg.startsWith("LdapSSLHandshakeFailureTest$CustomSocketFactory")) { + customSocketFactory = arg; + arg = popArg(); + if (arg == null) + return; } - if (args.length == 3) { - serverSleepingTime = Integer.valueOf(args[2]); + try { + connectTimeout = Integer.valueOf(arg); + arg = popArg(); + if (arg == null) + return; + } catch (NumberFormatException e) { + // then it must be the boolean arg for serverSlowDown } - boolean hasCustomSocketFactory = args[0] - .equals("LdapSSLHandshakeFailureTest$CustomSocketFactory"); + serverSlowDown = Boolean.valueOf(arg); + } + + public static void main(String args[]) { + parseArgs(args); + + System.out.println("Testing " + + (customSocketFactory == null ? "without custom SocketFactory" : "with custom SocketFactory \"" + customSocketFactory + "\"") + + ", " + (connectTimeout == null ? "no connectTimeout" : "connectTimeout=" + connectTimeout + "") + + ", serverSlowDown=" + serverSlowDown); + + // Set the keystores + setKeyStore(); + // start the test server first. - try (TestServer server = new TestServer(serverSlowDown, serverSleepingTime)) { + try (TestServer server = new TestServer(serverSlowDown)) { server.start(); Hashtable env = new Hashtable<>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); @@ -93,15 +142,13 @@ public static void main(String args[]) throws Exception { .port(server.getPortNumber()) .buildUnchecked().toString()); - if (hasCustomSocketFactory) { - env.put("java.naming.ldap.factory.socket", args[0]); - env.put("com.sun.jndi.ldap.connect.timeout", "1000"); + if (customSocketFactory != null) { + env.put("java.naming.ldap.factory.socket", customSocketFactory); } - if (args.length == 2 && !hasCustomSocketFactory) { - env.put("com.sun.jndi.ldap.connect.timeout", args[0]); + if (connectTimeout != null) { + env.put("com.sun.jndi.ldap.connect.timeout", connectTimeout.toString()); } - env.put(Context.SECURITY_PROTOCOL, "ssl"); env.put(Context.SECURITY_AUTHENTICATION, "Simple"); env.put(Context.SECURITY_PRINCIPAL, "cn=principal"); @@ -109,94 +156,127 @@ public static void main(String args[]) throws Exception { LdapContext ctx = null; try { ctx = new InitialLdapContext(env, null); - } catch (Exception e) { - if (CustomSocketFactory.customSocket.closeMethodCalledCount() > 0 - && hasCustomSocketFactory - && Boolean.valueOf(args[1])) { - System.out.println(SOCKET_CLOSED_MSG); + } catch (NamingException e) { + if (customSocketFactory != null) { + System.out.println("Caught expected Exception with custom SocketFactory (no SSL Socket)."); + if (CustomSocketFactory.customSocket.closeMethodCalledCount() <= 0) { + throw new RuntimeException("Custom Socket was not closed."); + } + } else if (connectTimeout > 0) { + System.out.println("Caught expected Exception with connectTimeout > 0."); } else { throw e; } } finally { - if (ctx != null) + if (ctx != null) { + System.out.println("Context was created, closing it."); + Socket sock = getSocket(ctx); ctx.close(); + if (!sock.isClosed()) { + throw new RuntimeException("Socket isn't closed"); + } + } } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); } } - public static class CustomSocketFactory extends SocketFactory { - private static CustomSocket customSocket; + private static Socket getSocket(LdapContext ctx) throws Exception { + Field defaultInitCtxField = ctx.getClass().getSuperclass().getSuperclass().getDeclaredField("defaultInitCtx"); + defaultInitCtxField.setAccessible(true); + Object defaultInitCtx = defaultInitCtxField.get(ctx); + Field clntField = defaultInitCtx.getClass().getDeclaredField("clnt"); + clntField.setAccessible(true); + Object clnt = clntField.get(defaultInitCtx); + Field connField = clnt.getClass().getDeclaredField("conn"); + connField.setAccessible(true); + Object conn = connField.get(clnt); + return (Socket)conn.getClass().getDeclaredField("sock").get(conn); + } - public static CustomSocketFactory getDefault() { - return new CustomSocketFactory(); + private static class CustomSocket extends Socket { + private int closeMethodCalled; + + public CustomSocket() { + super(); } - @Override - public Socket createSocket() throws SocketException { - customSocket = new CustomSocket(); - return customSocket; + public CustomSocket(String s, int port) throws IOException { + super(s, port); } - @Override - public Socket createSocket(String s, int timeout) { - return customSocket; + public int closeMethodCalledCount() { + return closeMethodCalled; } @Override - public Socket createSocket(String host, int port, InetAddress localHost, - int localPort) { - return customSocket; + public void close() throws java.io.IOException { + closeMethodCalled++; + super.close(); + } + } + + public static class CustomSocketFactoryNoUnconnected extends SocketFactory { + static CustomSocket customSocket; + + public static SocketFactory getDefault() { + return new CustomSocketFactoryNoUnconnected(); } @Override - public Socket createSocket(InetAddress host, int port) { + public Socket createSocket(String s, int port) throws IOException { + customSocket = new CustomSocket(s, port); return customSocket; } @Override - public Socket createSocket(InetAddress address, int port, - InetAddress localAddress, int localPort) { - return customSocket; + public Socket createSocket(String host, int port, InetAddress localHost, int localPort) + throws IOException, UnknownHostException { + return null; } - } - private static class CustomSocket extends Socket { - private int closeMethodCalled = 0; + @Override + public Socket createSocket(InetAddress host, int port) throws IOException { + return null; + } - public CustomSocket() { - closeMethodCalled = 0; + @Override + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) + throws IOException { + return null; } + } - public int closeMethodCalledCount() { - return closeMethodCalled; + public static class CustomSocketFactory extends CustomSocketFactoryNoUnconnected { + public static SocketFactory getDefault() { + return new CustomSocketFactory(); } @Override - public void close() throws java.io.IOException { - closeMethodCalled++; - super.close(); + public Socket createSocket() throws SocketException { + customSocket = new CustomSocket(); + return customSocket; } } private static void setKeyStore() { + String keystore = System.getProperty("test.src", ".") + File.separator + "ksWithSAN"; - String fileName = "ksWithSAN", dir = System.getProperty("test.src", ".") + File.separator; - - System.setProperty("javax.net.ssl.keyStore", dir + fileName); + System.setProperty("javax.net.ssl.keyStore", keystore); System.setProperty("javax.net.ssl.keyStorePassword", "welcome1"); - System.setProperty("javax.net.ssl.trustStore", dir + fileName); + System.setProperty("javax.net.ssl.trustStore", keystore); System.setProperty("javax.net.ssl.trustStorePassword", "welcome1"); } static class TestServer extends Thread implements AutoCloseable { private boolean isForceToSleep; - private int sleepingTime; private final ServerSocket serverSocket; private final int PORT; - private TestServer(boolean isForceToSleep, int sleepingTime) { + private TestServer(boolean isForceToSleep) { this.isForceToSleep = isForceToSleep; - this.sleepingTime = sleepingTime; try { SSLServerSocketFactory socketFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); serverSocket = socketFactory.createServerSocket(0, 0, InetAddress.getLoopbackAddress()); @@ -217,7 +297,7 @@ public void run() { InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream()) { if (isForceToSleep) { - Thread.sleep(sleepingTime); + Thread.sleep(SERVER_SLEEPING_TIME); } byte[] bindResponse = {0x30, 0x0C, 0x02, 0x01, 0x01, 0x61, 0x07, 0x0A, 0x01, 0x00, 0x04, 0x00, 0x04, 0x00}; @@ -233,7 +313,7 @@ public void run() { in.skip(in.available()); } } catch (Exception e) { - e.printStackTrace(); + // e.printStackTrace(); } } @@ -245,5 +325,3 @@ public void close() throws Exception { } } } - - diff --git a/test/jdk/com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java b/test/jdk/com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java index c7fded7399e..b3c7b064b30 100644 --- a/test/jdk/com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java +++ b/test/jdk/com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, 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 @@ -28,6 +28,7 @@ * @summary Basic test of ThreadMXBean.getThreadCpuTime(long[]) and * getThreadUserTime(long[]). * @author Paul Hohensee + * @requires vm.compMode != "Xcomp" */ import java.lang.management.*; diff --git a/test/jdk/com/sun/net/httpserver/SANTest.java b/test/jdk/com/sun/net/httpserver/SANTest.java new file mode 100644 index 00000000000..dc7f5e7bdd5 --- /dev/null +++ b/test/jdk/com/sun/net/httpserver/SANTest.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2021, 2023, 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 8278312 + * @library /test/lib /test/jdk/java/net/httpclient /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.test.lib.net.IPSupport + * + * @modules java.net.http/jdk.internal.net.http.common + * java.net.http/jdk.internal.net.http.frame + * java.net.http/jdk.internal.net.http.hpack + * java.logging + * java.base/sun.net.www.http + * java.base/sun.net.www + * java.base/sun.net + * + * @run main/othervm SANTest + * @summary Update SimpleSSLContext keystore to use SANs for localhost IP addresses + */ + +import com.sun.net.httpserver.*; + +import java.util.concurrent.*; +import java.io.*; +import java.net.*; +import java.net.http.*; +import java.nio.charset.StandardCharsets; +import javax.net.ssl.*; +import jdk.test.lib.net.SimpleSSLContext; +import jdk.test.lib.net.URIBuilder; +import jdk.test.lib.net.IPSupport; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; + +/* + * Will fail if the testkeys file belonging to SimpleSSLContext + * does not have SAN entries for 127.0.0.1 or ::1 + */ +public class SANTest implements HttpServerAdapters { + + static SSLContext ctx; + + static HttpServer getHttpsServer(InetSocketAddress addr, Executor exec, SSLContext ctx) throws Exception { + HttpsServer server = HttpsServer.create(addr, 0); + server.setExecutor(exec); + server.setHttpsConfigurator(new HttpsConfigurator (ctx)); + return server; + } + + static final boolean hasIPv4 = IPSupport.hasIPv4(); + static final boolean hasIPv6 = IPSupport.hasIPv6(); + + static HttpTestServer initServer(boolean h2, InetAddress addr, SSLContext ctx, + String sni, ExecutorService e) throws Exception { + HttpTestServer s = null; + InetSocketAddress ia = new InetSocketAddress (addr, 0); + if ((addr instanceof Inet4Address) && !hasIPv4) + return null; + if ((addr instanceof Inet6Address) && !hasIPv6) + return null; + + if (!h2) { + s = HttpTestServer.of(getHttpsServer(ia, e, ctx)); + HttpTestHandler h = new HttpTestEchoHandler(); + s.addHandler(h, "/test1"); + s.start(); + return s; + } else { + s = HttpTestServer.of(new Http2TestServer(addr, sni, true, 0, e, + 10, null, ctx, false)); + HttpTestHandler h = new HttpTestEchoHandler(); + s.addHandler(h, "/test1"); + s.start(); + return s; + } + } + + public static void main (String[] args) throws Exception { + // Http/1.1 servers + HttpTestServer h1s1 = null; + HttpTestServer h1s2 = null; + + // Http/2 servers + HttpTestServer h2s1 = null; + HttpTestServer h2s2 = null; + + ExecutorService executor=null; + try { + System.out.print ("SANTest: "); + ctx = new SimpleSSLContext().get(); + executor = Executors.newCachedThreadPool(); + + InetAddress l1 = InetAddress.getByName("::1"); + InetAddress l2 = InetAddress.getByName("127.0.0.1"); + + h1s1 = initServer(false, l1, ctx, "::1", executor); + h1s2 = initServer(false, l2, ctx, "127.0.0.1", executor); + + h2s1 = initServer(true, l1, ctx, "::1", executor); + h2s2 = initServer(true, l2, ctx, "127.0.0.1", executor); + + test("127.0.0.1", h1s2); + test("::1", h1s1); + testNew("127.0.0.1", h2s2, executor); + testNew("::1", h2s1, executor); + System.out.println ("OK"); + } finally { + if (h1s1 != null) + h1s1.stop(); + if (h1s2 != null) + h1s2.stop(); + if (h2s1 != null) + h2s1.stop(); + if (h2s2 != null) + h2s2.stop(); + if (executor != null) + executor.shutdown (); + } + } + + static void test (String host, HttpTestServer server) throws Exception { + if (server == null) + return; + int port = server.getAddress().getPort(); + String body = "Yellow world"; + URL url = URIBuilder.newBuilder() + .scheme("https") + .host(host) + .port(port) + .path("/test1/foo.txt") + .toURL(); + System.out.println("URL = " + url); + HttpURLConnection urlc = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY); + System.out.println("urlc = " + urlc); + if (urlc instanceof HttpsURLConnection) { + HttpsURLConnection urlcs = (HttpsURLConnection) urlc; + urlcs.setSSLSocketFactory (ctx.getSocketFactory()); + } + + urlc.setRequestMethod("POST"); + urlc.setDoOutput(true); + + OutputStream os = urlc.getOutputStream(); + os.write(body.getBytes(StandardCharsets.ISO_8859_1)); + os.close(); + InputStream is = urlc.getInputStream(); + byte[] vv = is.readAllBytes(); + String ff = new String(vv, StandardCharsets.ISO_8859_1); + System.out.println("resp = " + ff); + if (!ff.equals(body)) + throw new RuntimeException(); + is.close(); + } + + static void testNew (String host, HttpTestServer server, Executor exec) throws Exception { + if (server == null) + return; + int port = server.getAddress().getPort(); + String body = "Red and Yellow world"; + URI uri = URIBuilder.newBuilder() + .scheme("https") + .host(host) + .port(port) + .path("/test1/foo.txt") + .build(); + + HttpClient client = HttpClient.newBuilder() + .sslContext(ctx) + .executor(exec) + .build(); + HttpRequest req = HttpRequest.newBuilder(uri) + .version(HttpClient.Version.HTTP_2) + .POST(HttpRequest.BodyPublishers.ofString(body)) + .build(); + + HttpResponse resp = client.send(req, HttpResponse.BodyHandlers.ofString()); + System.out.println("resp = " + resp.body()); + if (!resp.body().equals(body)) + throw new RuntimeException(); + } +} diff --git a/test/jdk/java/awt/Choice/ChoiceSelectTest.java b/test/jdk/java/awt/Choice/ChoiceSelectTest.java new file mode 100644 index 00000000000..cf5b2e6d114 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceSelectTest.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 1998, 2023, 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.awt.Choice; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Panel; + +/* + * @test + * @bug 4115139 4128213 + * @summary Tests that the (rather bizarre) rules for handling selection + * in Choice components are implemented as documented in + * "The Java Class Libraries 2nd Edition" + * @key headful + */ + +public class ChoiceSelectTest extends Panel { + final Choice c; + + public ChoiceSelectTest() { + setLayout(new FlowLayout()); + c = new Choice(); + add(c); + } + + private void test() { + testAddition(); + testInsertion(); + testRemoval(); + testIndices(); + } + + public void testAddition() { + c.removeAll(); + + // check that after first item added selection is zero + c.addItem("zero"); + if (c.getSelectedIndex() != 0) { + throw new SelectionException("selection wrong after first add"); + } + + // check that selection doesn't change for subsequent adds + c.addItem("one"); + c.select(1); + c.addItem("two"); + if (c.getSelectedIndex() != 1) { + throw new SelectionException("selection wrong after subsequent add"); + } + } + + public void testInsertion() { + c.removeAll(); + + // check that after first item inserted selection is zero + c.insert("zero", 0); + if (c.getSelectedIndex() != 0) { + throw new SelectionException("selection wrong after first insert"); + } + + // check that if selected item shifted, selection goes to zero + c.insert("three", 1); + c.select(1); + c.insert("one", 1); + if (c.getSelectedIndex() != 0) { + throw new SelectionException("selection wrong after selected item shifted"); + } + + // check that if selected item not shifted, selection stays the same + c.select(1); + c.insert("two", 2); + if (c.getSelectedIndex() != 1) { + throw new SelectionException("selection wrong after item inserted after selection"); + } + } + + public void testRemoval() { + c.removeAll(); + + // check that if removing selected item, selection goes to 0 + c.add("zero"); + c.add("one"); + c.add("two"); + c.select(2); + c.remove(2); + if (c.getSelectedIndex() != 0) { + throw new SelectionException("selection wrong after removing selected item"); + } + + // check that if removing item before the selection + // the selected index is updated + c.add("two"); + c.add("three"); + c.select(3); + c.remove(1); + if (c.getSelectedIndex() != 2) { + throw new SelectionException("selection wrong after removing item before it"); + } + } + + public void testIndices() { + c.removeAll(); + + c.addItem("zero"); + c.addItem("one"); + c.addItem("two"); + c.addItem("three"); + c.addItem("four"); + c.addItem("five"); + + // Test selection of negative index + try { + c.select(-1); + throw new SelectionException("Negative Index Test FAILED"); + } catch (IllegalArgumentException expected) {} + + // Test selection of zero index + try { + c.select(0); + } catch (IllegalArgumentException iae) { + throw new SelectionException("Zero Index Test FAILED", iae); + } + + // Test selection of maximum index + try { + c.select(5); + } catch (IllegalArgumentException iae) { + throw new SelectionException("Maximum Index Test FAILED", iae); + } + + // Test selection of index that is too large + try { + c.select(6); + throw new SelectionException("Greater than Maximum Index Test FAILED"); + } catch (IllegalArgumentException expected) {} + } + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> new ChoiceSelectTest().test()); + } + + class SelectionException extends RuntimeException { + SelectionException(String msg, Throwable cause) { + super(msg, cause); + System.out.println( + "Selection item is '" + c.getSelectedItem() + + "' at index " + c.getSelectedIndex()); + } + + SelectionException(String msg) { + this(msg, null); + } + } +} diff --git a/test/jdk/java/awt/Component/Displayable.java b/test/jdk/java/awt/Component/Displayable.java new file mode 100644 index 00000000000..0c4969bb595 --- /dev/null +++ b/test/jdk/java/awt/Component/Displayable.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 1998, 2023, 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.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Label; +import java.awt.Panel; + +/* + * @test + * @key headful + * @summary automated test for "displayable" property on Component + */ + +public class Displayable extends Panel { + Label status = new Label("Displayable Test started..."); + + public void init() { + setLayout(new BorderLayout()); + add("South", status); + + LightDisplayable light = new LightDisplayable(); + shouldNotBeDisplayable(light, "before added to container "); + + HeavyDisplayable heavy = new HeavyDisplayable(); + shouldNotBeDisplayable(heavy, "before added to container "); + + add("West", light); + add("East", heavy); + + statusMessage("Displayable test completed successfully."); + } + + protected void addImpl(Component child, Object constraints, int index) { + super.addImpl(child, constraints, index); + if (isDisplayable()) { + shouldBeDisplayable(child, "after added to displayable container "); + } else { + shouldNotBeDisplayable(child, "after added to undisplayable container "); + } + } + + public void remove(Component child) { + super.remove(child); + shouldNotBeDisplayable(child, "after removed from displayable container "); + } + + public void statusMessage(String msg) { + status.setText(msg); + status.invalidate(); + validate(); + } + + public static void shouldNotBeDisplayable(Component c, String why) { + if (c.isDisplayable()) { + throw new RuntimeException("Component is displayable "+why+c.getName()); + } + } + + public static void shouldBeDisplayable(Component c, String why) { + if (!c.isDisplayable()) { + throw new RuntimeException("Component is NOT displayable "+why+c.getName()); + } + } + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + Frame f = new Frame(); + try { + Displayable test = new Displayable(); + test.init(); + f.add("North", test); + f.pack(); + } finally { + f.dispose(); + } + }); + } +} + +class LightDisplayable extends Component { + + public Dimension getPreferredSize() { + return new Dimension(50,50); + } + + public void paint(Graphics g) { + Dimension size = getSize(); + g.setColor(Color.blue); + g.fillRect(0, 0, size.width, size.height); + super.paint(g); + } + + public void addNotify() { + Displayable.shouldNotBeDisplayable(this, "before addNotify "); + super.addNotify(); + Displayable.shouldBeDisplayable(this, "after addNotify "); + } + + public void removeNotify() { + Displayable.shouldBeDisplayable(this, "before removeNotify "); + super.removeNotify(); + Displayable.shouldNotBeDisplayable(this, "after removeNotify "); + } +} + +class HeavyDisplayable extends Panel { + + public Dimension getPreferredSize() { + return new Dimension(50, 50); + } + + public void paint(Graphics g) { + Dimension size = getSize(); + g.setColor(Color.black); + g.fillRect(0, 0, size.width, size.height); + super.paint(g); + } + + public void addNotify() { + Displayable.shouldNotBeDisplayable(this, "before addNotify "); + super.addNotify(); + Displayable.shouldBeDisplayable(this, "after addNotify "); + } + + public void removeNotify() { + Displayable.shouldBeDisplayable(this, "before removeNotify "); + super.removeNotify(); + Displayable.shouldNotBeDisplayable(this, "after removeNotify "); + } +} diff --git a/test/jdk/java/awt/Component/RepaintTest.java b/test/jdk/java/awt/Component/RepaintTest.java new file mode 100644 index 00000000000..69d0ff8e3d4 --- /dev/null +++ b/test/jdk/java/awt/Component/RepaintTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 1999, 2023, 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.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Point; +import java.awt.Robot; + +/* + * @test + * @bug 4189198 + * @key headful + * @summary updateClient should post a PaintEvent + */ + +public class RepaintTest { + private static volatile Frame frame; + private static volatile Label label; + private static volatile Point frameLoc; + + private static final int FRAME_DIM = 100; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + EventQueue.invokeAndWait(() -> { + frame = new Frame("Repaint Tester"); + frame.setSize(FRAME_DIM, FRAME_DIM); + label = new Label("Hi"); + frame.add(label); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + label.setBackground(Color.GREEN); + label.repaint(); + frameLoc = frame.getLocationOnScreen(); + }); + robot.waitForIdle(); + robot.delay(500); + + Color expectedColor = robot.getPixelColor(frameLoc.x + FRAME_DIM / 2, + frameLoc.y + FRAME_DIM / 2); + if (!Color.GREEN.equals(expectedColor)) { + throw new RuntimeException("Test Failed! \n" + + "PaintEvent was not triggered: "); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/java/awt/Focus/NoFocusOwnerAWTTest.java b/test/jdk/java/awt/Focus/NoFocusOwnerAWTTest.java new file mode 100644 index 00000000000..953c392e79f --- /dev/null +++ b/test/jdk/java/awt/Focus/NoFocusOwnerAWTTest.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2001, 2023, 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 4390019 + @summary REGRESSION: Alt-F4 keybinding no longer shuts down java application on Windows + @key headful + @requires (os.family == "windows") + @run main NoFocusOwnerAWTTest +*/ +import java.awt.Frame; +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Label; +import java.awt.MenuBar; +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.MenuShortcut; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import java.awt.event.WindowEvent; +import java.awt.event.WindowAdapter; + +public class NoFocusOwnerAWTTest { + + static boolean actionFired = false; + static boolean closingWindowCalled = false; + static Frame frame; + + public static void main(String[] args) throws Exception { + try { + if (!System.getProperty("os.name").startsWith("Windows")) { + // this test is Win32 test only + return; + } + EventQueue.invokeAndWait(() -> { + + frame = new Frame("No Focus Owner AWT Test"); + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.out.println("windowClosing() is called."); + closingWindowCalled = true; + } + }); + frame.addFocusListener(new FocusListener() { + public void focusGained(FocusEvent fe) { + System.out.println("focus gained on frame"); + } + public void focusLost(FocusEvent fe) { + System.out.println("focus lost on frame"); + } + }); + MenuBar mb = new MenuBar(); + Menu m = new Menu("This is Menu"); + MenuItem mi = new MenuItem("Menu Item"); + mi.setShortcut(new MenuShortcut(KeyEvent.VK_A)); + mi.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent ae) { + System.out.println("action"); + actionFired = true; + } + }); + m.add(mi); + mb.add(m); + frame.setMenuBar(mb); + Label lb; + frame.add(lb = new Label("press")); + lb.addFocusListener(new FocusListener() { + public void focusGained(FocusEvent fe) { + System.out.println("focus gained on label"); + } + public void focusLost(FocusEvent fe) { + System.out.println("focus lost on label"); + } + }); + frame.pack(); + frame.toFront(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + Robot robot = new Robot(); + robot.setAutoDelay(100); + robot.delay(1000); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.keyPress(KeyEvent.VK_A); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_CONTROL); + robot.waitForIdle(); + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_F4); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_F4); + robot.keyRelease(KeyEvent.VK_ALT); + robot.waitForIdle(); + robot.delay(1000); + + if (!actionFired || !closingWindowCalled) { + throw new RuntimeException("Test FAILED(actionFired="+actionFired+ + ";closingWindowCalled="+closingWindowCalled+")"); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + }// class NoFocusOwnerAWTTest diff --git a/test/jdk/java/awt/Focus/NoFocusOwnerSwingTest.java b/test/jdk/java/awt/Focus/NoFocusOwnerSwingTest.java new file mode 100644 index 00000000000..23c898ae823 --- /dev/null +++ b/test/jdk/java/awt/Focus/NoFocusOwnerSwingTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2001, 2023, 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 4390019 + @summary REGRESSION: Alt-F4 keybinding no longer shuts down java application on Windows + @key headful + @requires (os.family == "windows") + @run main NoFocusOwnerSwingTest +*/ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Label; +import java.awt.MenuBar; +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.MenuShortcut; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import java.awt.event.WindowEvent; +import java.awt.event.WindowAdapter; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class NoFocusOwnerSwingTest { + static boolean closingWindowCalled = false; + static JFrame frame; + + public static void main(String[] args) throws Exception { + try { + if (!System.getProperty("os.name").startsWith("Windows")) { + // this test is Win32 test only + return; + } + + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("No Focus Owner Swing Test"); + JButton btn; + frame.getContentPane().add(btn = new JButton("press")); + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.out.println("windowClosing is called"); + closingWindowCalled = true; + } + }); + frame.pack(); + frame.toFront(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + Robot robot = new Robot(); + robot.setAutoDelay(100); + robot.delay(1000); + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_F4); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_F4); + robot.keyRelease(KeyEvent.VK_ALT); + robot.waitForIdle(); + + if (!closingWindowCalled) { + throw new RuntimeException("Test FAILED(closingWindowCalled=" + + closingWindowCalled + ")"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +}// class NoFocusOwnerSwingTest diff --git a/test/jdk/java/awt/Focus/QuickTypeTest.java b/test/jdk/java/awt/Focus/QuickTypeTest.java new file mode 100644 index 00000000000..0cfd0ef5f1d --- /dev/null +++ b/test/jdk/java/awt/Focus/QuickTypeTest.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2002, 2023, 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 4423838 + @summary KEY_TYPED and KEY_PRESSED generated by the same key are notified to + different TextFields + @key headful + @run main QuickTypeTest +*/ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextArea; +import java.awt.EventQueue; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +import java.util.Properties; + +import javax.swing.JFrame; +import javax.swing.JTextField; + +public class QuickTypeTest { + static final int TEST_TIMEOUT=10000; + static JFrame frame1; + static JFrame frame2; + static JTextField tf1; + static JTextField tf2; + static SmartKeyAdapter ska; + static Object keyMonitor; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame1 = new JFrame("First Frame"); + frame2 = new JFrame("Second Frame"); + tf1 = new JTextField("", 10); + tf2 = new JTextField("", 10); + frame1.getContentPane().add(tf1); + frame2.getContentPane().add(tf2); + frame1.setLocation(200,220); + frame2.setLocation(220,300); + frame1.pack(); + frame2.pack(); + keyMonitor = new Object(); + ska = new SmartKeyAdapter(frame2, keyMonitor); + tf1.addKeyListener(ska); + frame1.setVisible(true); + }); + + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(100); + robot.waitForIdle(); + robot.delay(1000); + Object tf1Monitor = new Object(); + MonitoredFocusListener monitorer = new MonitoredFocusListener(tf1Monitor); + tf1.addFocusListener(monitorer); + Point origin = tf1.getLocationOnScreen(); + Dimension dim = tf1.getSize(); + robot.mouseMove((int)origin.getX() + (int)dim.getWidth()/2, + (int)origin.getY() + (int)dim.getHeight()/2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + if (!tf1.isFocusOwner()) { + synchronized (tf1Monitor) { + tf1Monitor.wait(TEST_TIMEOUT); + } + } + if (!tf1.isFocusOwner()) { + throw new RuntimeException("TEST FAILED. tf1 doesn't receive focus."); + } + + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + robot.keyPress(KeyEvent.VK_B); + robot.keyRelease(KeyEvent.VK_B); + if (!ska.isFrameShown) { + synchronized (keyMonitor) { + keyMonitor.wait(TEST_TIMEOUT); + } + } + if (!ska.isFrameShown) { + throw new RuntimeException("TEST FAILED. Second frame is not shown."); + } + + Object waitMonitor = new Object(); + ReleaseWaiter waiter = new ReleaseWaiter(waitMonitor, KeyEvent.VK_C); + tf1.addKeyListener(waiter); + tf2.addKeyListener(waiter); + robot.keyPress(KeyEvent.VK_C); + robot.keyRelease(KeyEvent.VK_C); + + synchronized (waitMonitor) { + waitMonitor.wait(2000); + } + + if ((tf1.getText().length() > 2) || (tf2.getText().length() < 1)) { + System.out.println("tf1's text = \"" + tf1.getText() + "\""); + System.out.println("tf2's text = \"" + tf2.getText() + "\""); + System.out.println("l1 = " + tf1.getText().length()); + System.out.println("l2 = " + tf2.getText().length()); + throw new RuntimeException("TEST FAILED."); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame1 != null) { + frame1.dispose(); + } + if (frame2 != null) { + frame2.dispose(); + } + }); + } + } + + }// class QuickTypeTest + +class ReleaseWaiter extends KeyAdapter { + Object monitor; + int keycode; + public ReleaseWaiter(Object monitor, int keycode) { + this.monitor = monitor; + this.keycode = keycode; + } + + public void keyReleased(KeyEvent ke) { + System.out.println("keyReleased " + ke.getKeyCode()); + if (ke.getKeyCode() == keycode) { + synchronized (monitor) { + monitor.notify(); + } + } + } +} + +class SmartKeyAdapter implements KeyListener { + JFrame frame; + int charCounter = 0; + boolean isFrameShown = false; + Object monitor; + + public SmartKeyAdapter(JFrame frame, Object monitor) { + this.frame = frame; + this.monitor = monitor; + } + + public void keyReleased(KeyEvent ke) { + System.out.println(ke.toString()); + } + public void keyPressed(KeyEvent ke) { + System.out.println(ke.toString()); + charCounter++; + if (charCounter == 2) { + frame.setVisible(true); + isFrameShown = true; + synchronized (monitor) { + monitor.notify(); + } + } + } + public void keyTyped(KeyEvent ke) { + System.out.println(ke.toString()); + } +} + +class MonitoredFocusListener extends FocusAdapter { + Object monitor; + + public MonitoredFocusListener(Object monitor) { + this.monitor = monitor; + } + + public void focusLost(FocusEvent fe) { + System.out.println(fe.toString()); + } + public void focusGained(FocusEvent fe) { + System.out.println(fe.toString()); + synchronized (monitor) { + monitor.notify(); + } + } +} diff --git a/test/jdk/java/awt/Focus/RestoreFocusInfiniteLoopTest.java b/test/jdk/java/awt/Focus/RestoreFocusInfiniteLoopTest.java new file mode 100644 index 00000000000..64b1ae9477c --- /dev/null +++ b/test/jdk/java/awt/Focus/RestoreFocusInfiniteLoopTest.java @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2002, 2023, 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 4504665 + @summary MerlinBeta2 - vetoing a focus change causes infinite loop + @key headful + @run main RestoreFocusInfiniteLoopTest +*/ + +import java.awt.AWTException; +import java.awt.Button; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.KeyboardFocusManager; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextArea; + +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyVetoException; +import java.beans.VetoableChangeListener; + +public class RestoreFocusInfiniteLoopTest { + static final int TEST_TIMEOUT = 1000; + static final int DELAY = 100; + static Button b1; + static Frame frame; + static Object b1Monitor; + static Point origin; + static Dimension dim; + static MonitoredFocusListener monitorer; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> { + + b1Monitor = new Object(); + frame = new Frame(); + b1 = new Button("1"); + Button b2 = new Button("2"); + b1.setName("b1"); + b2.setName("b2"); + + frame.setLayout(new FlowLayout()); + frame.add(b1); + frame.add(b2); + frame.pack(); + frame.setSize(100, 100); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + FocusVetoableChangeListener vetoer = new FocusVetoableChangeListener(b2); + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + addVetoableChangeListener("focusOwner", vetoer); + + }); + Robot robot = new Robot(); + robot.setAutoDelay(DELAY); + robot.setAutoWaitForIdle(true); + robot.delay(1000); + EventQueue.invokeAndWait(() -> { + monitorer = new MonitoredFocusListener(b1Monitor); + b1.addFocusListener(monitorer); + origin = b1.getLocationOnScreen(); + dim = b1.getSize(); + }); + robot.mouseMove((int)origin.getX() + (int)dim.getWidth()/2, + (int)origin.getY() + (int)dim.getHeight()/2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + if (!b1.isFocusOwner()) { + synchronized (b1Monitor) { + b1Monitor.wait(TEST_TIMEOUT); + } + } + + monitorer.resetFocusLost(); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + + if (!monitorer.isFocusLostReceived() || !b1.isFocusOwner()) { + synchronized (b1Monitor) { + b1Monitor.wait(TEST_TIMEOUT); + } + } + if (!b1.isFocusOwner()) { + throw new RuntimeException("Test is FAILED"); + } else { + System.out.println("Test is PASSED"); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + + }// class RestoreFocusInfiniteLoopTest + +class FocusVetoableChangeListener implements VetoableChangeListener { + Component vetoedComponent; + public FocusVetoableChangeListener(Component vetoedComponent) { + this.vetoedComponent = vetoedComponent; + } + public void vetoableChange(PropertyChangeEvent evt) + throws PropertyVetoException + { + Component oldComp = (Component)evt.getOldValue(); + Component newComp = (Component)evt.getNewValue(); + + boolean vetoFocusChange = (newComp == vetoedComponent); + process(evt.getPropertyName(), oldComp, newComp); + + if (vetoFocusChange) { + throw new PropertyVetoException("message", evt); + } + } + boolean process(String propName, Component o1, Component o2) { + System.out.println(propName + + " old=" + (o1 != null ? o1.getName() : "null") + + " new=" + (o2 != null ? o2.getName() : "null")); + return true; + } + } + +class MonitoredFocusListener extends FocusAdapter { + Object monitor; + boolean focuslost = false; + + public void resetFocusLost() { + focuslost = false; + } + public boolean isFocusLostReceived() { + return focuslost; + } + public MonitoredFocusListener(Object monitor) { + this.monitor = monitor; + } + + public void focusLost(FocusEvent fe) { + System.out.println(fe.toString()); + focuslost = true; + } + public void focusGained(FocusEvent fe) { + System.out.println(fe.toString()); + synchronized (monitor) { + monitor.notify(); + } + } +} diff --git a/test/jdk/java/awt/Focus/RowToleranceTransitivityTest.java b/test/jdk/java/awt/Focus/RowToleranceTransitivityTest.java new file mode 100644 index 00000000000..099e81a1ab0 --- /dev/null +++ b/test/jdk/java/awt/Focus/RowToleranceTransitivityTest.java @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2005, 2023, 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 5070991 + @key headful + @summary Tests for a transitivity problem with ROW_TOLERANCE in SortingFTP. + @run main RowToleranceTransitivityTest +*/ +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.KeyboardFocusManager; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import javax.swing.JCheckBox; +import javax.swing.JFrame; +import javax.swing.JFormattedTextField; +import javax.swing.JLabel; +import javax.swing.JPanel; +import java.util.concurrent.atomic.AtomicBoolean; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +public class RowToleranceTransitivityTest { + static JFrame frame; + static JPanel panel; + static JFormattedTextField ft; + static JCheckBox cb; + static GridBagConstraints gc; + static Robot robot; + + static AtomicBoolean focusGained = new AtomicBoolean(false); + + public static void main(String[] args) throws Exception { + robot = new Robot(); + robot.setAutoDelay(100); + robot.setAutoWaitForIdle(true); + try { + EventQueue.invokeAndWait(() -> { + gc = new GridBagConstraints(); + frame = new JFrame("JFrame"); + JPanel panel = new JPanel(new GridBagLayout()); + ft = new JFormattedTextField(); + cb = new JCheckBox("JCheckBox"); + Dimension dim = new Dimension(100, ft.getPreferredSize().height); + ft.setPreferredSize(dim); + ft.setMinimumSize(dim); + gc.gridx = 5; + gc.gridy = 1; + gc.gridwidth = 10; + panel.add(ft, gc); + + gc.gridy = 3; + panel.add(cb, gc); + + cb.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + System.out.println(e.toString()); + synchronized (focusGained) { + focusGained.set(true); + focusGained.notifyAll(); + } + } + }); + + gc.weightx = 1.0; + gc.gridwidth = 1; + gc.gridy = 0; + gc.gridx = 0; + for (int n = 0; n < 7; n++) { + panel.add(getlabel(), gc); + gc.gridy++; + } + + gc.gridx = 0; + gc.gridy = 0; + for (int n = 0; n < 7; n++) { + panel.add(getlabel(), gc); + gc.gridx++; + } + + frame.getContentPane().add(panel); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.setAlwaysOnTop(true); + + }); + robot.waitForIdle(); + robot.delay(1000); + test(); + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + + static void test() throws Exception { + robot.delay(500); + + // Set focus on the first component to start traversal + if (!setFocusOn(ft, new Runnable() { + public void run() { + clickOn(ft); + } + })) { + System.out.println("Couldn't set focus on " + ft); + throw new RuntimeException("Test couldn't be performed."); + } + + robot.delay(500); + + // Try to traverse + if (!setFocusOn(cb, new Runnable() { + public void run() { + robot.keyPress(KeyEvent.VK_TAB); + } + })) { + System.out.println("Focus got stuck while traversing."); + throw new RuntimeException("Test failed!"); + } + + System.out.println("Test passed."); + } + + static boolean setFocusOn(Component comp, Runnable action) { + + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == comp) { + System.out.println("Already focus owner: " + comp); + return true; + } + + focusGained.set(false); + + System.out.println("Setting focus on " + comp); + + comp.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + System.out.println(e.toString()); + synchronized (focusGained) { + focusGained.set(true); + focusGained.notifyAll(); + } + } + }); + + action.run(); + + synchronized (focusGained) { + if (!focusGained.get()) { + try { + focusGained.wait(3000); + } catch (InterruptedException e) { + System.out.println("Unexpected exception caught!"); + throw new RuntimeException(e); + } + } + } + + return focusGained.get(); + } + + static JLabel getlabel(){ + Dimension dim = new Dimension(5, 9); // LayoutComparator.ROW_TOLERANCE = 10; + JLabel l = new JLabel("*"); + l.setMinimumSize(dim); + l.setMaximumSize(dim); + l.setPreferredSize(dim); + return l; + } + + static void clickOn(Component c) { + Point p = c.getLocationOnScreen(); + Dimension d = c.getSize(); + + System.out.println("Clicking " + c); + + if (c instanceof Frame) { + robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + ((Frame)c).getInsets().top/2); + } else { + robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + (int)(d.getHeight()/2)); + } + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + } + +} diff --git a/test/jdk/java/awt/Focus/SequencedLightweightRequestsTest.java b/test/jdk/java/awt/Focus/SequencedLightweightRequestsTest.java new file mode 100644 index 00000000000..9daa87a4263 --- /dev/null +++ b/test/jdk/java/awt/Focus/SequencedLightweightRequestsTest.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2002, 2023, 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 4648816 + @summary Sometimes focus requests on LW components are delayed + @key headful + @run main SequencedLightweightRequestsTest +*/ + +import java.awt.AWTException; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextArea; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.InputEvent; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; + +public class SequencedLightweightRequestsTest implements FocusListener { + final int WAIT_TIME = 5000; + + JFrame testFrame; + JButton testButton1; + JButton testButton2; + JTextField testField; + + public void focusGained(FocusEvent fe) { + System.err.println("FocusGained on " + fe.getComponent().getName()); + } + + public void focusLost(FocusEvent fe) { + System.err.println("FocusLost on " + fe.getComponent().getName()); + } + + public static void main(String[] args) throws Exception { + SequencedLightweightRequestsTest test = + new SequencedLightweightRequestsTest(); + test.start(); + } + + public void start() throws Exception { + try { + + SwingUtilities.invokeAndWait(() -> { + testFrame = new JFrame("See my components!"); + testButton1 = new JButton("Click me!"); + testButton2 = new JButton("Do I have focus?"); + testField = new JTextField("Do I have focus?"); + testFrame.getContentPane().setLayout(new FlowLayout()); + testFrame.getContentPane().add(testButton1); + testFrame.getContentPane().add(testField); + testFrame.getContentPane().add(testButton2); + + testButton1.setName("Button1"); + testButton2.setName("Button2"); + testField.setName("textField"); + testButton1.addFocusListener(this); + testButton2.addFocusListener(this); + testField.addFocusListener(this); + testFrame.addFocusListener(this); + + testFrame.setSize(300, 100); + testFrame.setLocationRelativeTo(null); + testFrame.setVisible(true); + }); + + Robot robot = new Robot(); + robot.setAutoDelay(100); + robot.setAutoWaitForIdle(true); + + // wait to give to frame time for showing + robot.delay(1000); + + // make sure that first button has focus + Object monitor = new Object(); + MonitoredFocusListener monitorer = + new MonitoredFocusListener(monitor); + Point origin = testButton1.getLocationOnScreen(); + Dimension dim = testButton1.getSize(); + robot.mouseMove((int)origin.getX() + (int)dim.getWidth()/2, + (int)origin.getY() + (int)dim.getHeight()/2); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + if (!testButton1.isFocusOwner()) { + synchronized (monitor) { + testButton1.addFocusListener(monitorer); + monitor.wait(WAIT_TIME); + testButton1.removeFocusListener(monitorer); + } + } + + // if first button still doesn't have focus, test fails + if (!testButton1.isFocusOwner()) { + throw new RuntimeException("First button doesn't receive focus"); + } + + // two lightweight requests + java.awt.EventQueue.invokeAndWait(new Runnable() { + public void run() { + testButton2.requestFocus(); + testField.requestFocus(); + } + }); + + // make sure third button receives focus + if (!testField.isFocusOwner()) { + synchronized (monitor) { + testField.addFocusListener(monitorer); + monitor.wait(WAIT_TIME); + testField.removeFocusListener(monitorer); + } + } + + // if the text field still doesn't have focus, test fails + if (!testField.isFocusOwner()) { + throw new RuntimeException("Text field doesn't receive focus"); + } + System.out.println("Test PASSED"); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (testFrame != null) { + testFrame.dispose(); + } + }); + } + } +}// class SequencedLightweightRequestsTest + +class MonitoredFocusListener extends FocusAdapter { + Object monitor; + + public MonitoredFocusListener(Object monitor) { + this.monitor = monitor; + } + + public void focusGained(FocusEvent fe) { + synchronized (monitor) { + monitor.notify(); + } + } +} diff --git a/test/jdk/java/awt/Focus/SetFocusableTest.java b/test/jdk/java/awt/Focus/SetFocusableTest.java new file mode 100644 index 00000000000..371b8ff49ba --- /dev/null +++ b/test/jdk/java/awt/Focus/SetFocusableTest.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2002, 2023, 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 4597455 + @summary setFocusable(false) is not moving the focus to next Focusable Component + @key headful + @run main SetFocusableTest +*/ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextArea; +import java.awt.TextField; + +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +public class SetFocusableTest implements KeyListener { + static Object buttonMonitor; + Object tfMonitor; + static final int TEST_TIMEOUT = 5000; + Button button; + Frame frame; + TextField textfield; + + public static void main(String[] args) throws Exception { + SetFocusableTest test = new SetFocusableTest(); + test.start(); + } + + public void start() throws Exception { + try { + EventQueue.invokeAndWait(() -> { + buttonMonitor = new Object(); + tfMonitor = new Object(); + frame = new Frame(); + frame.setTitle("Test Frame"); + frame.setLocation(100, 100); + frame.setLayout(new FlowLayout()); + + button = new Button("BUTTON"); + textfield = new TextField("First"); + + button.addKeyListener(this); + textfield.addKeyListener(this); + + frame.add(button); + frame.add(textfield); + + frame.setBackground(Color.red); + frame.setSize(500,200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.toFront(); + button.addFocusListener(new MonitoredFocusListener(buttonMonitor)); + textfield.addFocusListener(new MonitoredFocusListener(tfMonitor)); + }); + + Robot robot; + robot = new Robot(); + robot.setAutoDelay(100); + robot.setAutoWaitForIdle(true); + robot.delay(1000); + + Point buttonOrigin = button.getLocationOnScreen(); + Dimension buttonSize = button.getSize(); + robot.mouseMove( + (int)buttonOrigin.getX() + (int)buttonSize.getWidth() / 2, + (int)buttonOrigin.getY() + (int)buttonSize.getHeight() / 2); + + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + if (!button.isFocusOwner()) { + synchronized (buttonMonitor) { + buttonMonitor.wait(TEST_TIMEOUT); + } + } + System.out.println("\n\nBefore calling the method button.setFocusable(false)"); + System.out.println("===================================================="); + System.out.println("Button is Focusable(button.isFocusable()) :"+button.isFocusable()); + System.out.println("Button is Focus owner(button.isFocusOwner()) :"+button.isFocusOwner()); + System.out.println("Button has Focus (button.hasFocus) :"+button.hasFocus()); + System.out.println("===================================================="); + + button.setFocusable(false); + + if (!textfield.isFocusOwner()) { + synchronized (tfMonitor) { + tfMonitor.wait(TEST_TIMEOUT); + } + } + + System.out.println("\nAfter Calling button.setFocusable(false)"); + System.out.println("===================================================="); + System.out.println("Button is Focusable(button.isFocusable()) :"+button.isFocusable()); + System.out.println("Button is Focus owner(button.isFocusOwner()) :"+button.isFocusOwner()); + System.out.println("Button has Focus (button.hasFocus()) :"+button.hasFocus()); + System.out.println("TextField is Focusable(textfield.isFocusable()) :"+textfield.isFocusable()); + System.out.println("TextField is Focus owner(textfield.isFocusOwner()) :"+textfield.isFocusOwner()); + System.out.println("TextField has Focus (textfield.hasFocus()) :"+textfield.hasFocus()); + System.out.println("====================================================n\n\n\n"); + + if (!button.hasFocus() && !button.isFocusOwner() && + textfield.hasFocus() && textfield.isFocusOwner()){ + System.out.println("\n\n\nASSERTION :PASSED"); + System.out.println("========================="); + System.out.println("Textfield is having the Focus.Transfer of Focus has happend."); + } else { + System.out.println("\n\n\nASSERTION :FAILED"); + System.out.println("=========================="); + System.out.println("Button is still having the Focus instead of TextField"); + throw new RuntimeException("Test FIALED"); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + }// start() + + public void keyPressed(KeyEvent e) { + System.out.println("Key Pressed "); + } + public void keyReleased(KeyEvent ke) { + System.out.println("keyReleased called "); + } + public void keyTyped(KeyEvent ke) { + System.out.println("keyTyped called "); + } +}// class SetFocusableTest + +class MonitoredFocusListener extends FocusAdapter { + Object monitor; + public MonitoredFocusListener(Object monitor) { + this.monitor = monitor; + } + + public void focusGained(FocusEvent fe) { + System.out.println(fe.toString()); + synchronized (monitor) { + monitor.notify(); + } + } +} diff --git a/test/jdk/java/awt/Focus/TemporaryLostComponentDeadlock.java b/test/jdk/java/awt/Focus/TemporaryLostComponentDeadlock.java new file mode 100644 index 00000000000..e14492ecf16 --- /dev/null +++ b/test/jdk/java/awt/Focus/TemporaryLostComponentDeadlock.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2003, 2023, 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 4794413 + * @summary Tests that access to temporaryLostComponent from two different threads doesn't cause a deadlock + * @key headful + * @run main TemporaryLostComponentDeadlock +*/ +import java.awt.Button; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.Frame; + +public class TemporaryLostComponentDeadlock { + static Dialog frame1; + static Frame frame; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + frame = new Frame("frame"); + frame1 = new Dialog(frame, "Frame 1", false); + frame1.add(new Button("focus owner")); + frame1.pack(); + frame1.setLocationRelativeTo(null); + frame1.setVisible(true); + }); + + Thread t1 = new Thread() { + public void run() { + synchronized(frame1) { + frame1.dispose(); + synchronized(frame1) { + frame1.notify(); + } + } + } + }; + try { + synchronized(frame1) { + t1.start(); + frame1.wait(); + } + } catch( InterruptedException ie) { + } finally { + if (frame != null) { + frame.dispose(); + } + } + System.out.println("Test PASSED"); + } + +}// class TemporaryLostComponentDeadlock diff --git a/test/jdk/java/awt/Focus/TestWindowsLFFocus.java b/test/jdk/java/awt/Focus/TestWindowsLFFocus.java new file mode 100644 index 00000000000..8dd27f0a649 --- /dev/null +++ b/test/jdk/java/awt/Focus/TestWindowsLFFocus.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2002, 2023, 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 javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.WindowConstants; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; + +/* + * @test + * @bug 4749659 + * @summary Tests that popup menu doesn't steal focus from top-level + * @key headful + */ + +public class TestWindowsLFFocus { + static volatile boolean actionFired; + + static JFrame frame; + static JMenuBar bar; + static JMenuItem item; + static volatile Point frameLoc; + + public static void main(String[] args) throws Exception { + for (UIManager.LookAndFeelInfo lookAndFeel : UIManager.getInstalledLookAndFeels()) { + UIManager.setLookAndFeel(lookAndFeel.getClassName()); + test(); + } + + System.err.println("PASSED"); + } + + private static void test() throws Exception { + try { + SwingUtilities.invokeAndWait(() -> { + actionFired = false; + frame = new JFrame(); + bar = new JMenuBar(); + frame.setJMenuBar(bar); + JMenu menu = new JMenu("menu"); + bar.add(menu); + item = new JMenuItem("item"); + menu.add(item); + item.addActionListener(e -> actionFired = true); + + frame.getContentPane().add(new JButton("none")); + frame.setBounds(100, 100, 100, 100); + frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + frame.setVisible(true); + }); + + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + Point location = frame.getLocationOnScreen(); + Insets insets = frame.getInsets(); + + location.translate(insets.left + 15, insets.top + bar.getHeight() / 2); + + frameLoc = location; + }); + + robot.mouseMove(frameLoc.x, frameLoc.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + Point location = new Point(frameLoc); + location.y += bar.getHeight() / 2 + item.getHeight() / 2; + + frameLoc = location; + }); + + robot.mouseMove(frameLoc.x, frameLoc.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + robot.waitForIdle(); + robot.delay(500); + + if (!actionFired) { + throw new RuntimeException("Menu closed without action"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/java/awt/Focus/TraversalKeysPropertyNamesTest.java b/test/jdk/java/awt/Focus/TraversalKeysPropertyNamesTest.java new file mode 100644 index 00000000000..aec724e457d --- /dev/null +++ b/test/jdk/java/awt/Focus/TraversalKeysPropertyNamesTest.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2001, 2023, 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 4457455 + @summary Component and KeyboardFocusManager use wrong names of the properties + @run main TraversalKeysPropertyNamesTest +*/ + +import java.awt.AWTKeyStroke; +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.EventQueue; +import java.awt.KeyboardFocusManager; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.HashSet; + +public class TraversalKeysPropertyNamesTest implements PropertyChangeListener { + final String[] properties = { + "forwardDefaultFocusTraversalKeys", + "backwardDefaultFocusTraversalKeys", + "upCycleDefaultFocusTraversalKeys", + "downCycleDefaultFocusTraversalKeys", + "forwardFocusTraversalKeys", + "backwardFocusTraversalKeys", + "upCycleFocusTraversalKeys", + "downCycleFocusTraversalKeys" + }; + final int PROPERTIES_COUNT = properties.length; + boolean[] flags = new boolean[PROPERTIES_COUNT]; + + public static void main(String[] args) throws Exception { + TraversalKeysPropertyNamesTest test = new TraversalKeysPropertyNamesTest(); + test.start(); + } + + public void start() throws Exception { + EventQueue.invokeAndWait(() -> { + Container cont = new Container() {}; + HashSet forwardKeys = new HashSet(); + forwardKeys.add(AWTKeyStroke.getAWTKeyStroke("ctrl A")); + HashSet backwardKeys = new HashSet(); + backwardKeys.add(AWTKeyStroke.getAWTKeyStroke("ctrl B")); + HashSet upKeys = new HashSet(); + upKeys.add(AWTKeyStroke.getAWTKeyStroke("ctrl C")); + HashSet downKeys = new HashSet(); + downKeys.add(AWTKeyStroke.getAWTKeyStroke("ctrl D")); + + KeyboardFocusManager manager = + KeyboardFocusManager.getCurrentKeyboardFocusManager(); + manager.addPropertyChangeListener(this); + manager.setDefaultFocusTraversalKeys( + KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys); + manager.setDefaultFocusTraversalKeys( + KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys); + manager.setDefaultFocusTraversalKeys( + KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS, downKeys); + manager.setDefaultFocusTraversalKeys( + KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, upKeys); + + cont.addPropertyChangeListener(this); + cont.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys); + cont.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys); + cont.setFocusTraversalKeys(KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS, downKeys); + cont.setFocusTraversalKeys(KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, upKeys); + + for (int i = 0; i < PROPERTIES_COUNT; i++) { + if (!flags[i]) { + throw new RuntimeException( + "Notification on "+properties[i]+" change was not received"); + } + } + }); + }// start() + + public void propertyChange(PropertyChangeEvent pce) { + String property = pce.getPropertyName(); + System.err.println(property); + int index; + for (index = 0; index < PROPERTIES_COUNT; index++) { + if (property.equals(properties[index])) { + break; + } + } + + if (index < PROPERTIES_COUNT) { + flags[index] = true; + } + } + }// class TraversalKeysPropertyNamesTest diff --git a/test/jdk/java/awt/Focus/UpFocusCycleTest.java b/test/jdk/java/awt/Focus/UpFocusCycleTest.java new file mode 100644 index 00000000000..2c421ffe822 --- /dev/null +++ b/test/jdk/java/awt/Focus/UpFocusCycleTest.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2001, 2023, 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 4394789 + @summary KeyboardFocusManager.upFocusCycle is not working for Swing properly + @key headful + @run main UpFocusCycleTest +*/ +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Color; +import java.awt.DefaultKeyboardFocusManager; +import java.awt.EventQueue; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.Robot; +import javax.swing.DefaultFocusManager; +import javax.swing.JButton; +import javax.swing.JFrame; + +public class UpFocusCycleTest { + static boolean isFailed = true; + static Object sema = new Object(); + static JFrame frame; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + EventQueue.invokeAndWait(() -> { + + frame = new JFrame("Test frame"); + + Container container1 = frame.getContentPane(); + container1.setBackground(Color.yellow); + + JButton button = new JButton("Button"); + button.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent fe) { + DefaultKeyboardFocusManager manager = new DefaultFocusManager(); + manager.upFocusCycle(button); + System.out.println("Button receive focus"); + frame.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent fe) { + System.out.println("Frame receive focus"); + synchronized (sema) { + isFailed = false; + sema.notifyAll(); + } + } + }); + } + }); + container1.add(button,BorderLayout.WEST); + button.requestFocus(); + frame.setSize(300,300); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + if (isFailed) { + System.out.println("Test FAILED"); + throw new RuntimeException("Test FAILED"); + } else { + System.out.println("Test PASSED"); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + }// class UpFocusCycleTest diff --git a/test/jdk/java/awt/Focus/VetoableChangeListenerLoopTest.java b/test/jdk/java/awt/Focus/VetoableChangeListenerLoopTest.java new file mode 100644 index 00000000000..b6449b16dbc --- /dev/null +++ b/test/jdk/java/awt/Focus/VetoableChangeListenerLoopTest.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2004, 2023, 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 5074189 + @summary Tests that VetoableChangeListener doesn't initiate infinite loop. + @key headful + @run main VetoableChangeListenerLoopTest +*/ +import java.awt.AWTEvent; +import java.awt.Button; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.KeyboardFocusManager; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; +import java.awt.event.FocusEvent; +import java.awt.event.WindowEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyVetoException; +import java.beans.VetoableChangeListener; + +public class VetoableChangeListenerLoopTest { + static Button b1; + static Button b2; + static Frame frame; + static Robot robot; + + static int counter = 0; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + EventQueue.invokeAndWait(() -> { + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + addVetoableChangeListener(new VetoableChangeListener () { + public void vetoableChange(PropertyChangeEvent evt) + throws PropertyVetoException { + if (b1.equals(evt.getNewValue())) { + System.out.println("VETOING: " + (counter++)); + if (counter > 2) { + throw new RuntimeException("Test failed!"); + } + throw new PropertyVetoException("Change in property", evt); + } + } + }); + + Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { + public void eventDispatched(AWTEvent e) { + System.out.println(e.toString()); + } + }, FocusEvent.FOCUS_EVENT_MASK | WindowEvent.WINDOW_FOCUS_EVENT_MASK); + + b1 = new Button("Button 1"); + b2 = new Button("Button 2"); + Frame frame = new Frame(); + frame.add(b1); + frame.add(b2); + frame.setSize(200, 100); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + robot.delay(1000); + test(); + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + + static void test() { + b2.requestFocusInWindow(); + waitTillFocus(b2); + b2.setVisible(false); + } + + + static void waitTillFocus(Component comp) { + while (!checkFocusOwner(comp)) { + robot.delay(100); + } + } + + static boolean checkFocusOwner(Component comp) { + return (comp == KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner()); + } +} diff --git a/test/jdk/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java b/test/jdk/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java index 20ca18587ef..52a5754a9c3 100644 --- a/test/jdk/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java +++ b/test/jdk/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, 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 @@ -21,51 +21,56 @@ * questions. */ -/* - @test - @key headful - @bug 6988428 - @summary Tests whether shape is always set - @author anthony.petrov@oracle.com: area=awt.toplevel - @run main ShapeNotSetSometimes -*/ - - import java.awt.Color; +import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Frame; import java.awt.Graphics; import java.awt.Point; import java.awt.Rectangle; import java.awt.Robot; +import java.awt.Toolkit; import java.awt.geom.Area; import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; +/* + * @test + * @key headful + * @bug 6988428 + * @summary Tests whether shape is always set + * @run main/othervm -Dsun.java2d.uiScale=1 ShapeNotSetSometimes + */ public class ShapeNotSetSometimes { private Frame backgroundFrame; private Frame window; - private static final Color BACKGROUND_COLOR = Color.GREEN; - private static final Color SHAPE_COLOR = Color.WHITE; + private Point[] pointsOutsideToCheck; private Point[] shadedPointsToCheck; private Point innerPoint; - private final Rectangle bounds = new Rectangle(220, 400, 300, 300); - private static Robot robot; + private static final Color BACKGROUND_COLOR = Color.GREEN; + private static final Color SHAPE_COLOR = Color.WHITE; + private static final int DIM = 300; + private static final int DELTA = 2; public ShapeNotSetSometimes() throws Exception { EventQueue.invokeAndWait(this::initializeGUI); robot.waitForIdle(); + robot.delay(500); } private void initializeGUI() { backgroundFrame = new BackgroundFrame(); backgroundFrame.setUndecorated(true); - backgroundFrame.setBounds(bounds); + backgroundFrame.setSize(DIM, DIM); + backgroundFrame.setLocationRelativeTo(null); backgroundFrame.setVisible(true); Area area = new Area(); @@ -76,8 +81,10 @@ private void initializeGUI() { area.add(new Area(new Ellipse2D.Float(150, 50, 100, 100))); area.add(new Area(new Ellipse2D.Float(150, 100, 100, 100))); - + // point at the center of white ellipse innerPoint = new Point(150, 130); + + // mid points on the 4 sides - on the green background frame pointsOutsideToCheck = new Point[] { new Point(150, 20), new Point(280, 120), @@ -85,6 +92,7 @@ private void initializeGUI() { new Point(20, 120) }; + // points just outside the ellipse (opposite side of diagonal) shadedPointsToCheck = new Point[] { new Point(62, 62), new Point(240, 185) @@ -92,7 +100,8 @@ private void initializeGUI() { window = new TestFrame(); window.setUndecorated(true); - window.setBounds(bounds); + window.setSize(DIM, DIM); + window.setLocationRelativeTo(null); window.setShape(area); window.setVisible(true); } @@ -103,7 +112,7 @@ static class BackgroundFrame extends Frame { public void paint(Graphics g) { g.setColor(BACKGROUND_COLOR); - g.fillRect(0, 0, 300, 300); + g.fillRect(0, 0, DIM, DIM); super.paint(g); } @@ -115,7 +124,7 @@ class TestFrame extends Frame { public void paint(Graphics g) { g.setColor(SHAPE_COLOR); - g.fillRect(0, 0, bounds.width, bounds.height); + g.fillRect(0, 0, DIM, DIM); super.paint(g); } @@ -124,7 +133,7 @@ public void paint(Graphics g) { public static void main(String[] args) throws Exception { robot = new Robot(); - for(int i = 0; i < 50; i++) { + for (int i = 1; i <= 50; i++) { System.out.println("Attempt " + i); new ShapeNotSetSometimes().doTest(); } @@ -136,7 +145,6 @@ private void doTest() throws Exception { EventQueue.invokeAndWait(window::toFront); robot.waitForIdle(); - robot.delay(500); try { @@ -151,17 +159,24 @@ private void doTest() throws Exception { } } finally { EventQueue.invokeAndWait(() -> { - backgroundFrame.dispose(); - window.dispose(); + if (backgroundFrame != null) { + backgroundFrame.dispose(); + } + if (window != null) { + window.dispose(); + } }); } } private void colorCheck(int x, int y, Color expectedColor, boolean mustBeExpectedColor) { - int screenX = window.getX() + x; int screenY = window.getY() + y; + robot.mouseMove(screenX, screenY); + robot.waitForIdle(); + robot.delay(50); + Color actualColor = robot.getPixelColor(screenX, screenY); System.out.printf( @@ -172,9 +187,9 @@ private void colorCheck(int x, int y, Color expectedColor, boolean mustBeExpecte expectedColor ); - if (mustBeExpectedColor != expectedColor.equals(actualColor)) { + if (mustBeExpectedColor != colorCompare(expectedColor, actualColor)) { + captureScreen(); System.out.printf("window.getX() = %3d, window.getY() = %3d\n", window.getX(), window.getY()); - System.err.printf( "Checking for transparency failed: point: %3d, %3d\n\tactual %s\n\texpected %s%s\n", screenX, @@ -185,4 +200,27 @@ private void colorCheck(int x, int y, Color expectedColor, boolean mustBeExpecte throw new RuntimeException("Test failed. The shape has not been applied."); } } + + private static boolean colorCompare(Color expected, Color actual) { + if (Math.abs(expected.getRed() - actual.getRed()) <= DELTA + && Math.abs(expected.getGreen() - actual.getGreen()) <= DELTA + && Math.abs(expected.getBlue() - actual.getBlue()) <= DELTA) { + return true; + } + return false; + } + + private static void captureScreen() { + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Rectangle screenBounds = new Rectangle(0, 0, screenSize.width, screenSize.height); + try { + ImageIO.write( + robot.createScreenCapture(screenBounds), + "png", + new File("Screenshot.png") + ); + } catch (IOException e) { + e.printStackTrace(); + } + } } diff --git a/test/jdk/java/awt/Graphics/DrawNullStringTest.java b/test/jdk/java/awt/Graphics/DrawNullStringTest.java new file mode 100644 index 00000000000..7ae2d066fa9 --- /dev/null +++ b/test/jdk/java/awt/Graphics/DrawNullStringTest.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 1999, 2023, 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 4166809 + * @summary Make sure NPE is thrown when calling + * Graphics.drawString(null, int, int) + * @run main DrawNullStringTest + */ +import java.awt.image.BufferedImage; +import java.awt.EventQueue; +import java.awt.Graphics; + +public class DrawNullStringTest { + static String s = null; + static boolean passed = false; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + BufferedImage img = new BufferedImage(100, 100, + BufferedImage.TYPE_INT_RGB); + Graphics g = (Graphics)(img.getGraphics()); + try { + g.drawString(s, 30, 30); + } catch (NullPointerException npe) { + System.out.println("NPE thrown - test passes"); + passed = true; + } + + if (passed == false) { + throw new Error("No Exception was thrown - should be an NPE"); + } + }); + } + + }// class DrawNullStringTest diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/SPublisherOfStream.java b/test/jdk/java/awt/Graphics/GetGraphicsTest.java similarity index 57% rename from test/jdk/java/net/httpclient/reactivestreams-tck-tests/SPublisherOfStream.java rename to test/jdk/java/awt/Graphics/GetGraphicsTest.java index 555906461a2..7a80e1fd0df 100644 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/SPublisherOfStream.java +++ b/test/jdk/java/awt/Graphics/GetGraphicsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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 @@ -20,30 +20,32 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ +/* + * @test + * @bug 4746122 + * @key headful + * @summary Checks getGraphics doesn't throw NullPointerExcepton for invalid colors and font. + * @run main GetGraphicsTest +*/ -import org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowPublisherVerification; - -import java.util.concurrent.Flow.Publisher; -import java.util.stream.LongStream; -import java.util.stream.Stream; - -/* See TckDriver.java for more information */ -public class SPublisherOfStream - extends FlowPublisherVerification { +import java.awt.Color; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Graphics; - public SPublisherOfStream() { - super(new TestEnvironment(450L)); +public class GetGraphicsTest extends Frame { + public Color getBackground() { + return null; } - - @Override - public Publisher createFlowPublisher(long nElements) { - Stream s = LongStream.range(0, nElements).boxed(); - return S.publisherOfStream(s); + public Color getForeground() { + return null; } - - @Override - public Publisher createFailedFlowPublisher() { + public Font getFont() { return null; } -} + + public static void main(String[] args) throws Exception { + GetGraphicsTest test = new GetGraphicsTest(); + Graphics g = test.getGraphics(); + } +}// class GetGraphicsTest diff --git a/test/jdk/java/awt/GridBagLayout/GridBagLayoutButtonsOverlapTest.java b/test/jdk/java/awt/GridBagLayout/GridBagLayoutButtonsOverlapTest.java new file mode 100644 index 00000000000..dda70992889 --- /dev/null +++ b/test/jdk/java/awt/GridBagLayout/GridBagLayoutButtonsOverlapTest.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2003, 2023, 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 4930685 + @summary Test effect of GridBagConstraints on padding / layout + @key headful + @run main GridBagLayoutButtonsOverlapTest +*/ + +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.Frame; +import java.awt.GridBagLayout; +import java.awt.GridBagConstraints; + +public class GridBagLayoutButtonsOverlapTest { + public static GridBagLayout gridbag; + public static GridBagConstraints c; + public static Button b1; + public static Button b2; + public static Button b4; + public static Button b5; + public static Button b6; + public static Button b7; + public static Button b8; + public static Button b9; + public static Button b10; + public static Frame frame; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + try { + createUI(); + test(); + } finally { + if (frame != null) { + frame.dispose(); + } + } + }); + } + + public static void createUI() { + frame = new Frame(); + gridbag = new GridBagLayout(); + GridBagConstraints c = new GridBagConstraints(); + frame.setFont(new Font(Font.DIALOG, Font.PLAIN, 14)); + frame.setLayout(gridbag); + c.fill = GridBagConstraints.BOTH; + c.weightx = 1.0; + b1 = makeButton("button1", gridbag, c); + b2 = makeButton("button2", gridbag, c); + + c.gridwidth = GridBagConstraints.REMAINDER; + b4 = makeButton("button4", gridbag, c); + + c.weightx = 0.0; + b5 = makeButton("button5", gridbag, c); + + c.gridwidth = GridBagConstraints.RELATIVE; + b6 = makeButton("button6", gridbag, c); + + c.gridwidth = GridBagConstraints.REMAINDER; + b7 = makeButton("button7", gridbag, c); + + c.gridwidth = 1; + c.gridheight = 2; + c.weighty = 1.0; + b8 = makeButton("button8", gridbag, c); + + c.weighty = 0.0; + c.gridwidth = GridBagConstraints.REMAINDER; + c.gridheight = 1; + b9 = makeButton("button9", gridbag, c); + b10 = makeButton("button10", gridbag, c); + } + + public static void test() { + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + + int b1Corner = b1.getLocation().y + b1.getHeight(); + int b5Corner = b5.getLocation().y; + if (b1Corner > b5Corner) { //they are equals each other in best case + throw new RuntimeException("Buttons are overlapped when container is small enough"); + } + System.out.println("Test passed."); + } + + protected static Button makeButton(String name, + GridBagLayout gridbag, + GridBagConstraints c) { + Button button = new Button(name); + gridbag.setConstraints(button, c); + frame.add(button); + return button; + } + +}// class diff --git a/test/jdk/java/awt/GridBagLayout/GridBagLayoutOutOfBoundsTest.java b/test/jdk/java/awt/GridBagLayout/GridBagLayoutOutOfBoundsTest.java new file mode 100644 index 00000000000..1f68dbb8620 --- /dev/null +++ b/test/jdk/java/awt/GridBagLayout/GridBagLayoutOutOfBoundsTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2004, 2023, 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 5055696 + @summary REGRESSION: GridBagLayout throws ArrayIndexOutOfBoundsExceptions + @key headful + @run main GridBagLayoutOutOfBoundsTest +*/ +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridBagLayout; +import java.awt.GridBagConstraints; +import java.awt.Panel; + +public class GridBagLayoutOutOfBoundsTest { + final static int L=2; + static Frame frame; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + try { + frame = new Frame("GridBagLayoutOutOfBoundsTestFrame"); + frame.validate(); + GridBagLayout layout = new GridBagLayout(); + frame.setLayout(layout); + GridBagConstraints gridBagConstraints; + + Button[] mb = new Button[L]; + for (int i = 0; i { + try { + // Test with non-existent image to test with null data + // not throwing NPE + Image icon = Toolkit.getDefaultToolkit().getImage("notexistent.gif"); + f = new Frame("Frame with icon"); + f.setIconImage(icon); + f.setVisible(true); + } finally { + if (f != null) { + f.dispose(); + } + } + }); + } + + }// class SetIconImageExceptionTest + diff --git a/test/jdk/java/awt/PopupMenu/TruncatedPopupMenuTest.java b/test/jdk/java/awt/PopupMenu/TruncatedPopupMenuTest.java new file mode 100644 index 00000000000..64d655aa351 --- /dev/null +++ b/test/jdk/java/awt/PopupMenu/TruncatedPopupMenuTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2004, 2024, 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.awt.Frame; +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 5090643 + * @key headful + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Menus added to the popup menu are truncated on XToolkit + * @run main/manual TruncatedPopupMenuTest + */ + +public class TruncatedPopupMenuTest { + private static final String INSTRUCTIONS = + "1. Right-click on the Test Window.\n\n" + + "2. Look at the appeared popup menu.\n\n" + + "3. It should consist of one menu item (\"First simple menu item\")\n" + + "and one submenu (\"Just simple menu for the test\").\n\n" + + "4. The submenu should not be truncated. The submenu title text should\n" + + "be followed by a triangle. On the whole, menu should be good-looking.\n\n" + + "5. Left-click on the submenu (\"Just simple menu for the test\").\n" + + "After this operation, a submenu should popup. It should consist of\n"+ + "one menu item (\"Second simple menu item \") and one submenu (\"Other Menu\").\n\n" + + "6. The submenu should not be truncated. The \"Other Menu\" text should be followed by\n" + + "a triangle.\n\n" + + "On the whole, menu should be good-looking.\n"; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .rows(20) + .columns(55) + .testUI(TruncatedPopupMenuTest::createTestUI) + .build() + .awaitAndCheck(); + } + + private static Frame createTestUI() { + Menu subMenu = new Menu("Just simple menu for the test"); + subMenu.add(new MenuItem("Second simple menu item")); + subMenu.add(new Menu("Other Menu")); + + PopupMenu popup = new PopupMenu(); + popup.add(new MenuItem("First simple menu item")); + popup.add(subMenu); + + Frame testUI = new Frame("TruncatedPopupMenuTest"); + testUI.add(popup); + testUI.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + if (me.isPopupTrigger()) { + popup.show(me.getComponent(), me.getX(), me.getY()); + } + } + public void mouseReleased(MouseEvent me) { + if (me.isPopupTrigger()) { + popup.show(me.getComponent(), me.getX(), me.getY()); + } + } + }); + + testUI.setSize(400, 400); + return testUI; + } +} diff --git a/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java b/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java index ed72ce115cf..ec878c10c20 100644 --- a/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java +++ b/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, 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 @@ -52,8 +52,9 @@ public class TrayIconScalingTest { private static TrayIcon icon; private static final String INSTRUCTIONS = - "This test checks if the tray icon gets updated when DPI / Scale" + - " is changed on the fly.\n\n" + + "This test checks if the tray icon gets updated correctly under 2 scenarios:\n\n" + + "Case 1: Single Screen - when DPI / Scale is changed on the fly.\n" + + "Case 2: Multi Screen - when both screens are set to different scales.\n\n" + "STEPS: \n\n" + "1. Check the system tray / notification area on Windows" + " taskbar, you should see a white icon which displays a" + @@ -61,11 +62,17 @@ public class TrayIconScalingTest { "2. Navigate to Settings > System > Display and change the" + " display scale by selecting any value from" + " Scale & Layout dropdown.\n\n"+ - "3. When the scale changes, check the white tray icon," + + "3. For Case 1, when the scale changes, check the white tray icon," + " there should be no distortion, it should be displayed sharp,\n" + " and the displayed number should correspond to the current"+ - " scale:\n" + - " 100% - 16, 125% - 20, 150% - 24, 175% - 28, 200% - 32.\n\n"+ + " scale.\n\n" + + "4. For Case 2, a dual monitor setup is required with 'Multiple Display'" + + " option under Display settings set to 'Extend the display'.\n\n" + + "5. Have the monitors set to different scales and toggle the" + + " 'Make this my main display' option under Display settings.\n\n" + + " In both cases, the tray icon should be displayed as a clear image" + + " without any distortion with the display number corresponding to the scale.\n" + + " 100% - 16, 125% - 20, 150% - 24, 175% - 28, 200% - 32.\n\n" + " If the icon is displayed sharp and without any distortion," + " press PASS, otherwise press FAIL.\n"; @@ -78,8 +85,15 @@ public static void main(String[] args) System.out.println("SystemTray is not supported"); return; } - PassFailJFrame passFailJFrame = new PassFailJFrame("TrayIcon " + - "Test Instructions", INSTRUCTIONS, 8, 18, 85); + PassFailJFrame passFailJFrame = new PassFailJFrame.Builder() + .title("TrayIcon Test Instructions") + .instructions(INSTRUCTIONS) + .testTimeOut(8) + .rows(25) + .columns(70) + .screenCapture() + .build(); + createAndShowGUI(); // does not have a test window, // hence only the instruction frame is positioned diff --git a/test/jdk/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.java b/test/jdk/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.java index 3656c44246f..9548bd4fe2f 100644 --- a/test/jdk/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.java +++ b/test/jdk/java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, 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 @@ -29,16 +29,37 @@ @run main InterJVMGetDropSuccessTest */ -import java.awt.*; -import java.awt.datatransfer.*; -import java.awt.dnd.*; -import java.awt.event.*; -import java.io.*; +import java.awt.AWTEvent; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.AWTEventListener; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.io.File; +import java.io.InputStream; public class InterJVMGetDropSuccessTest { private int returnCode = Util.CODE_NOT_RETURNED; - private boolean successCodes[] = { true, false }; + private final boolean[] successCodes = { true, false }; private int dropCount = 0; final Frame frame = new Frame("Target Frame"); @@ -68,7 +89,9 @@ public void start() { frame.setVisible(true); try { - Thread.sleep(Util.FRAME_ACTIVATION_TIMEOUT); + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(Util.FRAME_ACTIVATION_TIMEOUT); Point p = frame.getLocationOnScreen(); Dimension d = frame.getSize(); @@ -136,10 +159,9 @@ final class Util implements AWTEventListener { public static final int CODE_SECOND_SUCCESS = 0x2; public static final int CODE_FAILURE = 0x1; - public static final int FRAME_ACTIVATION_TIMEOUT = 3000; + public static final int FRAME_ACTIVATION_TIMEOUT = 1000; static final Object SYNC_LOCK = new Object(); - static final int MOUSE_RELEASE_TIMEOUT = 1000; static final Util theInstance = new Util(); @@ -158,45 +180,13 @@ public static int sign(int n) { return n < 0 ? -1 : n == 0 ? 0 : 1; } - private Component clickedComponent = null; - - private void reset() { - clickedComponent = null; - } - public void eventDispatched(AWTEvent e) { if (e.getID() == MouseEvent.MOUSE_RELEASED) { - clickedComponent = (Component)e.getSource(); synchronized (SYNC_LOCK) { SYNC_LOCK.notifyAll(); } } } - - public static boolean pointInComponent(Robot robot, Point p, Component comp) - throws InterruptedException { - return theInstance.pointInComponentImpl(robot, p, comp); - } - - private boolean pointInComponentImpl(Robot robot, Point p, Component comp) - throws InterruptedException { - robot.waitForIdle(); - reset(); - robot.mouseMove(p.x, p.y); - robot.mousePress(InputEvent.BUTTON1_MASK); - synchronized (SYNC_LOCK) { - robot.mouseRelease(InputEvent.BUTTON1_MASK); - SYNC_LOCK.wait(MOUSE_RELEASE_TIMEOUT); - } - - Component c = clickedComponent; - - while (c != null && c != comp) { - c = c.getParent(); - } - - return c == comp; - } } class Child { @@ -226,6 +216,9 @@ public void dragDropEnd(DragSourceDropEvent dsde) { } } + private volatile boolean success1 = false; + private volatile boolean success2 = false; + final Frame frame = new Frame("Source Frame"); final DragSource dragSource = DragSource.getDefaultDragSource(); final DragSourceDropListener dragSourceListener = new DragSourceDropListener(); @@ -258,53 +251,62 @@ public void run(String[] args) { frame.setBounds(300, 200, 150, 150); frame.setVisible(true); - Thread.sleep(Util.FRAME_ACTIVATION_TIMEOUT); + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(Util.FRAME_ACTIVATION_TIMEOUT); Point sourcePoint = Util.getCenterLocationOnScreen(frame); - Point targetPoint = new Point(x + w / 2, y + h / 2); - Robot robot = new Robot(); robot.mouseMove(sourcePoint.x, sourcePoint.y); - robot.mousePress(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + robot.delay(50); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); for (Point p = new Point(sourcePoint); !p.equals(targetPoint); - p.translate(Util.sign(targetPoint.x - p.x), - Util.sign(targetPoint.y - p.y))) { + p.translate(Util.sign(targetPoint.x - p.x), + Util.sign(targetPoint.y - p.y))) { robot.mouseMove(p.x, p.y); - Thread.sleep(50); + robot.delay(5); } synchronized (Util.SYNC_LOCK) { - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); Util.SYNC_LOCK.wait(Util.FRAME_ACTIVATION_TIMEOUT); } - if (!dragSourceListener.isDropFinished()) { - throw new RuntimeException("Drop not finished"); - } + EventQueue.invokeAndWait(() -> { + if (!dragSourceListener.isDropFinished()) { + throw new RuntimeException("Drop not finished"); + } + success1 = dragSourceListener.getDropSuccess(); + dragSourceListener.reset(); + }); - boolean success1 = dragSourceListener.getDropSuccess(); - dragSourceListener.reset(); robot.mouseMove(sourcePoint.x, sourcePoint.y); - robot.mousePress(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + robot.delay(50); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); for (Point p = new Point(sourcePoint); !p.equals(targetPoint); - p.translate(Util.sign(targetPoint.x - p.x), - Util.sign(targetPoint.y - p.y))) { + p.translate(Util.sign(targetPoint.x - p.x), + Util.sign(targetPoint.y - p.y))) { robot.mouseMove(p.x, p.y); - Thread.sleep(50); + robot.delay(5); } synchronized (Util.SYNC_LOCK) { - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); Util.SYNC_LOCK.wait(Util.FRAME_ACTIVATION_TIMEOUT); } - if (!dragSourceListener.isDropFinished()) { - throw new RuntimeException("Drop not finished"); - } + EventQueue.invokeAndWait(() -> { + if (!dragSourceListener.isDropFinished()) { + throw new RuntimeException("Drop not finished"); + } + success2 = dragSourceListener.getDropSuccess(); + dragSourceListener.reset(); + }); - boolean success2 = dragSourceListener.getDropSuccess(); int retCode = 0; if (success1) { diff --git a/test/jdk/java/awt/event/KeyEvent/KeyTyped/DeleteKeyTyped.java b/test/jdk/java/awt/event/KeyEvent/KeyTyped/DeleteKeyTyped.java new file mode 100644 index 00000000000..cde75cf7c3a --- /dev/null +++ b/test/jdk/java/awt/event/KeyEvent/KeyTyped/DeleteKeyTyped.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2002, 2023, 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.awt.EventQueue; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.TextField; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +/* + * @test + * @bug 4724007 + * @key headful + * @summary Tests that KeyTyped events are fired for the Delete key + * and that no extraneous characters are entered as a result. + */ + +public class DeleteKeyTyped { + private static Frame frame; + private static TextField tf; + + private static boolean deleteKeyTypedReceived = false; + private static final String ORIGINAL = "0123456789"; + private static final String SUCCESS = "123456789"; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(100); + + EventQueue.invokeAndWait(DeleteKeyTyped::createTestUI); + robot.waitForIdle(); + robot.delay(1000); + + // Move cursor to start of TextField + robot.keyPress(KeyEvent.VK_HOME); + robot.keyRelease(KeyEvent.VK_HOME); + robot.waitForIdle(); + robot.delay(50); + + // Press and release Delete + robot.keyPress(KeyEvent.VK_DELETE); + robot.keyRelease(KeyEvent.VK_DELETE); + robot.waitForIdle(); + robot.delay(50); + + EventQueue.invokeAndWait(DeleteKeyTyped::testDeleteKeyEvent); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void createTestUI() { + frame = new Frame(); + tf = new TextField(ORIGINAL, 20); + frame.add(tf); + frame.setSize(300, 100); + frame.setVisible(true); + tf.requestFocusInWindow(); + + tf.addKeyListener(new KeyListener() { + @Override + public void keyPressed(KeyEvent evt) { + printKey(evt); + } + + @Override + public void keyTyped(KeyEvent evt) { + printKey(evt); + int keychar = evt.getKeyChar(); + if (keychar == 127) { // Delete character is 127 or \u007F + deleteKeyTypedReceived = true; + } + } + + @Override + public void keyReleased(KeyEvent evt) { + printKey(evt); + } + + private void printKey(KeyEvent evt) { + switch(evt.getID()) { + case KeyEvent.KEY_TYPED: + case KeyEvent.KEY_PRESSED: + case KeyEvent.KEY_RELEASED: + break; + default: + System.out.println("Other Event"); + return; + } + + System.out.println("params= " + evt.paramString() + " \n" + + "KeyChar: " + evt.getKeyChar() + " = " + (int) evt.getKeyChar() + + " KeyCode: " + evt.getKeyCode() + + " Modifiers: " + evt.getModifiersEx()); + + if (evt.isActionKey()) { + System.out.println("Action Key"); + } + + System.out.println("keyText= " + KeyEvent.getKeyText(evt.getKeyCode()) + "\n"); + } + }); + } + + private static void testDeleteKeyEvent() { + if (deleteKeyTypedReceived) { + if (tf.getText().equals(SUCCESS)) { + System.out.println("Test PASSED"); + } else { + System.out.println("Test FAILED: wrong string"); + throw new RuntimeException("The test failed: wrong string: " + + tf.getText()); + } + } + } +} diff --git a/test/jdk/java/awt/event/KeyEvent/KeyTyped/EscapeKeyTyped.java b/test/jdk/java/awt/event/KeyEvent/KeyTyped/EscapeKeyTyped.java new file mode 100644 index 00000000000..6410fc4bad8 --- /dev/null +++ b/test/jdk/java/awt/event/KeyEvent/KeyTyped/EscapeKeyTyped.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2002, 2023, 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.awt.EventQueue; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.TextField; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +/* + * @test + * @key headful + * @bug 4734408 + * @summary Tests that KeyTyped events are fired for the Escape key + * and that no extraneous characters are entered as a result. + */ + +public class EscapeKeyTyped { + private static Frame frame; + private static TextField tf; + + private static final String ORIGINAL = "0123456789"; + private static boolean escapeKeyTypedReceived = false; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(30); + + EventQueue.invokeAndWait(EscapeKeyTyped::createAndShowUI); + robot.waitForIdle(); + robot.delay(1000); + + // Press and release Escape + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.waitForIdle(); + robot.delay(20); + + EventQueue.invokeAndWait(EscapeKeyTyped::testEscKeyEvent); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + frame = new Frame(); + tf = new TextField(ORIGINAL, 20); + frame.add(tf); + frame.setSize(300, 100); + frame.setVisible(true); + tf.requestFocusInWindow(); + + tf.addKeyListener(new KeyListener() { + @Override + public void keyTyped(KeyEvent e) { + printKey(e); + } + + @Override + public void keyPressed(KeyEvent e) { + printKey(e); + int keychar = e.getKeyChar(); + if (keychar == 27) { // Escape character is 27 or \u0021 + escapeKeyTypedReceived = true; + } + } + + @Override + public void keyReleased(KeyEvent e) { + printKey(e); + } + + private void printKey(KeyEvent evt) { + switch (evt.getID()) { + case KeyEvent.KEY_TYPED: + case KeyEvent.KEY_PRESSED: + case KeyEvent.KEY_RELEASED: + break; + default: + System.out.println("Other Event"); + return; + } + + System.out.println("params= " + evt.paramString() + " \n" + + "KeyChar: " + evt.getKeyChar() + " = " + (int) evt.getKeyChar() + + " KeyCode: " + evt.getKeyCode() + + " Modifiers: " + evt.getModifiersEx()); + + if (evt.isActionKey()) { + System.out.println("Action Key"); + } + + System.out.println("keyText= " + KeyEvent.getKeyText(evt.getKeyCode()) + "\n"); + } + }); + } + + private static void testEscKeyEvent() { + if (escapeKeyTypedReceived) { + if (tf.getText().equals(ORIGINAL)) { + System.out.println("Test PASSED"); + } else { + System.out.println("Test FAILED: wrong string"); + throw new RuntimeException("The test failed: wrong string: " + + tf.getText()); + } + } + } +} diff --git a/test/jdk/java/awt/event/KeyEvent/ShiftF10Test.java b/test/jdk/java/awt/event/KeyEvent/ShiftF10Test.java new file mode 100644 index 00000000000..df002164ef8 --- /dev/null +++ b/test/jdk/java/awt/event/KeyEvent/ShiftF10Test.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2004, 2023, 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.awt.EventQueue; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.event.KeyEvent; + +/* + * @test + * @key headful + * @bug 4965227 + * @requires (os.family == "linux") + * @summary tests that Shift+F10 during Window show doesn't cause deadlock- Linux only + */ + +public class ShiftF10Test { + private static Frame frame; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoDelay(10); + + EventQueue.invokeLater(() -> { + frame = new Frame("Deadlocking one"); + frame.setSize(100, 100); + frame.setVisible(true); + }); + + for (int i = 0; i < 250; i++) { + robot.keyPress(KeyEvent.VK_SHIFT); + robot.keyPress(KeyEvent.VK_F10); + robot.keyRelease(KeyEvent.VK_F10); + robot.keyRelease(KeyEvent.VK_SHIFT); + robot.delay(10); + } + } catch (Exception e) { + throw new RuntimeException("Test Failed due to following error: ", e); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/java/awt/event/MouseEvent/MouseEventAbsoluteCoordsTest.java b/test/jdk/java/awt/event/MouseEvent/MouseEventAbsoluteCoordsTest.java new file mode 100644 index 00000000000..2444861ff54 --- /dev/null +++ b/test/jdk/java/awt/event/MouseEvent/MouseEventAbsoluteCoordsTest.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2005, 2023, 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.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +/* + * @test + * @bug 4992908 + * @key headful + * @summary Need way to get location of MouseEvent in screen coordinates + */ + +// The test consists of several parts: +// 1. create MouseEvent with new Ctor and checking get(X|Y)OnScreen(), +// getLocationOnScreen(), get(X|Y), getPoint(). +// 2. create MouseEvent with old Ctor and checking get(X|Y)OnScreen(), +// getLocationOnScreen(), get(X|Y), getPoint() . + +public class MouseEventAbsoluteCoordsTest implements MouseListener { + private static Frame frame; + private static Robot robot; + + private static Point mousePositionOnScreen = new Point(200, 200); + private static final Point mousePosition = new Point(100, 100); + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + + MouseEventAbsoluteCoordsTest cordsTest = + new MouseEventAbsoluteCoordsTest(); + cordsTest.createTestUI(); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public void createTestUI() throws Exception { + EventQueue.invokeAndWait(() -> { + frame = new Frame("MouseEvent Test Frame"); + frame.setSize(200, 200); + frame.setLocation(300, 400); + frame.addMouseListener(this); + frame.setVisible(true); + }); + + robot.waitForIdle(); + robot.delay(1000); + + // use new MouseEvent's Ctor with user-defined absolute + // coordinates + System.out.println("Stage MOUSE_PRESSED"); + postMouseEventNewCtor(MouseEvent.MOUSE_PRESSED); + + System.out.println("Stage MOUSE_RELEASED"); + postMouseEventNewCtor(MouseEvent.MOUSE_RELEASED); + + System.out.println("Stage MOUSE_CLICKED"); + postMouseEventNewCtor(MouseEvent.MOUSE_CLICKED); + + // call syncLocation to get correct on-screen frame position + syncLocationToWindowManager(); + + // now we gonna use old MouseEvent's Ctor thus absolute + // position calculates as frame's location + relative coords + // of the event. + EventQueue.invokeAndWait(() -> mousePositionOnScreen = new Point( + frame.getLocationOnScreen().x + mousePosition.x, + frame.getLocationOnScreen().y + mousePosition.y)); + + System.out.println("Stage MOUSE_PRESSED"); + postMouseEventOldCtor(MouseEvent.MOUSE_PRESSED); + + System.out.println("Stage MOUSE_RELEASED"); + postMouseEventOldCtor(MouseEvent.MOUSE_RELEASED); + + System.out.println("Stage MOUSE_CLICKED"); + postMouseEventOldCtor(MouseEvent.MOUSE_CLICKED); + } + + private static void syncLocationToWindowManager() { + Toolkit.getDefaultToolkit().sync(); + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + @Override + public void mousePressed(MouseEvent e) { + checkEventAbsolutePosition(e, "MousePressed OK"); + }; + + @Override + public void mouseExited(MouseEvent e) { + System.out.println("mouse exited"); + }; + + @Override + public void mouseReleased(MouseEvent e) { + checkEventAbsolutePosition(e, "MousePressed OK"); + }; + + @Override + public void mouseEntered(MouseEvent e) { + System.out.println("mouse entered"); + }; + + @Override + public void mouseClicked(MouseEvent e) { + checkEventAbsolutePosition(e, "MousePressed OK"); + }; + + public void postMouseEventNewCtor(int MouseEventType) { + MouseEvent mouseEvt = new MouseEvent(frame, + MouseEventType, + System.currentTimeMillis(), + MouseEvent.BUTTON1_DOWN_MASK, + mousePosition.x, mousePosition.y, + mousePositionOnScreen.x, + mousePositionOnScreen.y, + 1, + false, + MouseEvent.NOBUTTON + ); + frame.dispatchEvent(mouseEvt); + } + + public void postMouseEventOldCtor(int MouseEventType) { + MouseEvent oldMouseEvt = new MouseEvent(frame, + MouseEventType, + System.currentTimeMillis(), + MouseEvent.BUTTON1_DOWN_MASK, + mousePosition.x, mousePosition.y, + 1, + false, + MouseEvent.NOBUTTON + ); + frame.dispatchEvent(oldMouseEvt); + } + + public void checkEventAbsolutePosition(MouseEvent evt, String message) { + if (evt.getXOnScreen() != mousePositionOnScreen.x || + evt.getYOnScreen() != mousePositionOnScreen.y || + !evt.getLocationOnScreen().equals( mousePositionOnScreen)) { + System.out.println("evt.location = "+evt.getLocationOnScreen()); + System.out.println("mouse.location = "+mousePositionOnScreen); + throw new RuntimeException("get(X|Y)OnScreen() or getPointOnScreen() work incorrectly"); + } + + if (evt.getX() != mousePosition.x || + evt.getY() != mousePosition.y || + !evt.getPoint().equals( mousePosition)) { + throw new RuntimeException("get(X|Y)() or getPoint() work incorrectly"); + } + System.out.println(message); + } +} diff --git a/test/jdk/java/awt/event/OtherEvents/ContainerEventChildTest.java b/test/jdk/java/awt/event/OtherEvents/ContainerEventChildTest.java new file mode 100644 index 00000000000..5e0d6a4d32a --- /dev/null +++ b/test/jdk/java/awt/event/OtherEvents/ContainerEventChildTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1998, 2023, 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.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.event.ContainerAdapter; +import java.awt.event.ContainerEvent; + +/* + * @test + * @key headful + * @bug 4028904 + * @summary Tests whether System.out.println(ContainerEvent e) + * yields incorrect display or not. + */ + +public class ContainerEventChildTest { + private static Frame frame; + private static String com1, com2; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame(); + Panel outerPanel = new Panel(); + Panel innerPanel = new Panel(); + Button b = new Button("Panel Button"); + + innerPanel.addContainerListener(new ContainerAdapter() { + public void componentAdded(ContainerEvent e) { + String str1 = e.toString(); + String str2 = (e.getChild()).toString(); + + // extracting child values from ContainerEvent i.e., "e" and "e.getChild()" + com1 = str1.substring(str1.indexOf("child") + 6, str1.indexOf("]")); + com2 = str2.substring(str2.indexOf("[") + 1, str2.indexOf(",")); + + System.out.println("e : " + com1); + System.out.println("e.getChild() : " + com2); + + // comparing the child values between "e" and "e.getChild()" + // if child value of "e" equals null and child values between + // "e" and "e.getChild()" are not equal then throws exception + if (com1.equals("null") && !(com1.equals(com2))) { + System.out.println("unequal"); + throw new RuntimeException("Test Failed e.toString returns false value"); + } else { + System.out.println("Test Passed - e and e.getChild() are same"); + } + } + }); + innerPanel.add(b); + outerPanel.add(innerPanel); + frame.add(outerPanel); + frame.setVisible(true); + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/java/awt/event/OtherEvents/UndecoratedShrink.java b/test/jdk/java/awt/event/OtherEvents/UndecoratedShrink.java new file mode 100644 index 00000000000..1ac59666ca5 --- /dev/null +++ b/test/jdk/java/awt/event/OtherEvents/UndecoratedShrink.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2001, 2023, 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.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Robot; + +/* + * @test + * @bug 4418155 + * @key headful + * @summary Checks Undecorated Frame repaints when shrinking + */ + +public class UndecoratedShrink extends Frame { + private static boolean passed = false; + private static UndecoratedShrink frame; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + EventQueue.invokeAndWait(() -> { + frame = new UndecoratedShrink(); + frame.setUndecorated(true); + frame.setSize(100, 100); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + frame.setSize(50, 50); + frame.repaint(); + }); + robot.waitForIdle(); + robot.delay(500); + + if (!passed) { + throw new RuntimeException("Test Fails." + + " Frame does not get repainted"); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + @Override + public void paint(Graphics g) { + passed = true; + } +} diff --git a/test/jdk/java/awt/event/TextEvent/InitialTextEventTest.java b/test/jdk/java/awt/event/TextEvent/InitialTextEventTest.java new file mode 100644 index 00000000000..00d3e16a618 --- /dev/null +++ b/test/jdk/java/awt/event/TextEvent/InitialTextEventTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2003, 2023, 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.awt.Color; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.IllegalComponentStateException; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextArea; +import java.awt.TextField; +import java.awt.event.TextEvent; +import java.awt.event.TextListener; + +/* + * @test + * @bug 4503516 + * @key headful + * @summary TextEvent behaves differently across platforms, especially Solaris. + * Following testcase is used to test whether an initial TextEvent + * is triggered when a TextArea or TextField is initially added to UI. + */ + +public class InitialTextEventTest implements TextListener { + private static Frame frame; + private static TextField textField; + private static TextArea textArea; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + + InitialTextEventTest textEventObj = new InitialTextEventTest(); + EventQueue.invokeAndWait(textEventObj::createUI); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(textEventObj::testInitialTextEvent); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private void createUI() { + frame = new Frame(); + frame.setTitle("Text Event Test"); + frame.setLayout(new FlowLayout()); + + textField = new TextField("TextField"); + textArea = new TextArea("TextArea", 5, 10); + + textField.addTextListener(this); + textArea.addTextListener(this); + + frame.add(textField); + frame.add(textArea); + + frame.setBackground(Color.red); + frame.setSize(500,200); + frame.setVisible(true); + } + + private void testInitialTextEvent() { + Point pt; + boolean drawn = false; + while (!drawn) { + try { + pt = textArea.getLocationOnScreen(); + System.out.println("On-Screen Location on Text Area: " + pt); + pt = textField.getLocationOnScreen(); + System.out.println("On-Screen Location on Text Field: " + pt); + } catch (IllegalComponentStateException icse) { + try { + Thread.sleep(50); + } catch (InterruptedException ignored) {} + continue; + } + drawn = true; + } + } + + @Override + public void textValueChanged(TextEvent e) { + System.out.println("text event paramString: " + e.paramString()); + System.out.println("text event changed on: " + e.getSource().getClass().getName()); + throw new RuntimeException("InitialTextEventTest FAILED"); + } +} diff --git a/test/jdk/java/awt/geom/HitTest/PathHitTest.java b/test/jdk/java/awt/geom/HitTest/PathHitTest.java new file mode 100644 index 00000000000..930e7f764a6 --- /dev/null +++ b/test/jdk/java/awt/geom/HitTest/PathHitTest.java @@ -0,0 +1,392 @@ +/* + * Copyright (c) 1999, 2023, 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.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Choice; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Panel; +import java.awt.Polygon; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Area; +import java.awt.geom.Ellipse2D; +import java.awt.geom.GeneralPath; +import java.awt.geom.Point2D; + +/* + * @test + * @bug 4210936 4214524 + * @summary Tests the results of the hit test methods on 3 different + * Shape objects - Polygon, Area, and GeneralPath. Both an + * automatic test for constraint compliance and a manual + * test for correctness are included in this one class. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main PathHitTest + */ + +/* + * @test + * @bug 4210936 4214524 + * @summary Tests the results of the hit test methods on 3 different + * Shape objects - Polygon, Area, and GeneralPath. Both an + * automatic test for constraint compliance and a manual + * test for correctness are included in this one class. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual PathHitTest manual + */ + +public class PathHitTest { + + public static final int BOXSIZE = 5; + public static final int BOXCENTER = 2; + public static final int TESTSIZE = 400; + public static final int NUMTESTS = (TESTSIZE + BOXSIZE - 1) / BOXSIZE; + + public static Shape[] testShapes = new Shape[5]; + public static String[] testNames = { + "Polygon", + "EvenOdd GeneralPath", + "NonZero GeneralPath", + "Area from EO GeneralPath", + "Area from NZ GeneralPath", + }; + + static { + GeneralPath gpeo = new GeneralPath(GeneralPath.WIND_EVEN_ODD); + Ellipse2D ell = new Ellipse2D.Float(); + Point2D center = new Point2D.Float(); + AffineTransform at = new AffineTransform(); + for (int i = 0; i < 360; i += 30) { + center.setLocation(100, 0); + at.setToTranslation(200, 200); + at.rotate(i * Math.PI / 180); + at.transform(center, center); + ell.setFrame(center.getX() - 50, center.getY() - 50, 100, 100); + gpeo.append(ell, false); + } + GeneralPath side = new GeneralPath(); + side.moveTo(0, 0); + side.lineTo(15, 10); + side.lineTo(30, 0); + side.lineTo(45, -10); + side.lineTo(60, 0); + append4sides(gpeo, side, 20, 20); + side.reset(); + side.moveTo(0, 0); + side.quadTo(15, 10, 30, 0); + side.quadTo(45, -10, 60, 0); + append4sides(gpeo, side, 320, 20); + side.reset(); + side.moveTo(0, 0); + side.curveTo(15, 10, 45, -10, 60, 0); + append4sides(gpeo, side, 20, 320); + + GeneralPath gpnz = new GeneralPath(GeneralPath.WIND_NON_ZERO); + gpnz.append(gpeo, false); + Polygon p = new Polygon(); + p.addPoint( 50, 50); + p.addPoint( 60, 350); + p.addPoint(250, 340); + p.addPoint(260, 150); + p.addPoint(140, 140); + p.addPoint(150, 260); + p.addPoint(340, 250); + p.addPoint(350, 60); + testShapes[0] = p; + testShapes[1] = gpeo; + testShapes[2] = gpnz; + testShapes[3] = new Area(gpeo); + testShapes[3].getPathIterator(null); + testShapes[4] = new Area(gpnz); + testShapes[4].getPathIterator(null); + } + + private static void append4sides(GeneralPath path, GeneralPath side, + double xoff, double yoff) { + AffineTransform at = new AffineTransform(); + at.setToTranslation(xoff, yoff); + for (int i = 0; i < 4; i++) { + path.append(side.getPathIterator(at), i != 0); + at.rotate(Math.toRadians(90), 30, 30); + } + } + + public static void main(String[] argv) throws Exception { + if (argv.length > 0 && argv[0].equals("manual")) { + PathHitTestManual.doManual(); + } else { + int totalerrs = 0; + for (int i = 0; i < testShapes.length; i++) { + totalerrs += testshape(testShapes[i], testNames[i]); + } + if (totalerrs != 0) { + throw new RuntimeException(totalerrs + + " constraint conditions violated!"); + } + } + } + + public static int testshape(Shape s, String name) { + int numerrs = 0; + long start = System.currentTimeMillis(); + for (int y = 0; y < TESTSIZE; y += BOXSIZE) { + for (int x = 0; x < TESTSIZE; x += BOXSIZE) { + boolean rectintersects = s.intersects(x, y, BOXSIZE, BOXSIZE); + boolean rectcontains = s.contains(x, y, BOXSIZE, BOXSIZE); + boolean pointcontains = s.contains(x + BOXCENTER, y + BOXCENTER); + if (rectcontains && !rectintersects) { + System.err.println("rect is contained " + + "but does not intersect!"); + numerrs++; + } + if (rectcontains && !pointcontains) { + System.err.println("rect is contained " + + "but center is not contained!"); + numerrs++; + } + if (pointcontains && !rectintersects) { + System.err.println("center is contained " + + "but rect does not intersect!"); + numerrs++; + } + } + } + long end = System.currentTimeMillis(); + System.out.println(name + " completed in " + + (end - start) + "ms with " + + numerrs + " errors"); + return numerrs; + } + + static class PathHitTestManual extends Panel { + private static final String INSTRUCTIONS = """ + This test displays the results of hit testing 5 different Shape + objects one at a time. + + You can switch between shapes using the Choice component located + at the bottom of the window. + + Each square in the test represents the + return values of the hit testing operators for that square region: + + yellow - not yet tested + translucent blue overlay - the shape being tested + + black - all outside + dark gray - rectangle intersects shape + light gray - rectangle intersects and center point is inside shape + white - rectangle is entirely contained in shape + red - some constraint was violated, including: + rectangle is contained, but center point is not + rectangle is contained, but rectangle.intersects is false + centerpoint is contained, but rectangle.intersects is false + + Visually inspect the results to see if they match the above table. + Note that it is not a violation for rectangles that are entirely + inside the path to be light gray instead of white since sometimes + the path is complex enough to make an exact determination expensive. + You might see this on the GeneralPath NonZero example where the + circles that make up the path cross over the interior of the shape + and cause the hit testing methods to guess that the rectangle is + not guaranteed to be contained within the shape. + """; + + PathHitTestCanvas phtc; + + public void init() { + setLayout(new BorderLayout()); + phtc = new PathHitTestCanvas(); + add("Center", phtc); + final Choice ch = new Choice(); + for (int i = 0; i < PathHitTest.testNames.length; i++) { + ch.add(PathHitTest.testNames[i]); + } + ch.addItemListener(e -> phtc.setShape(ch.getSelectedIndex())); + ch.select(0); + phtc.setShape(0); + add("South", ch); + } + + public void start() { + phtc.start(); + } + + public void stop() { + phtc.stop(); + } + + public static class PathHitTestCanvas extends Canvas implements Runnable { + public static final Color[] colors = { + /* contains? point in? intersects? */ + Color.black, /* NO NO NO */ + Color.darkGray, /* NO NO YES */ + Color.red, /* NO YES NO */ + Color.lightGray, /* NO YES YES */ + Color.red, /* YES NO NO */ + Color.red, /* YES NO YES */ + Color.red, /* YES YES NO */ + Color.white, /* YES YES YES */ + Color.yellow, /* used for untested points */ + }; + + public Dimension getPreferredSize() { + return new Dimension(TESTSIZE, TESTSIZE); + } + + public synchronized void start() { + if (!testdone) { + renderer = new Thread(this); + renderer.setPriority(Thread.MIN_PRIORITY); + renderer.start(); + } + } + + public synchronized void stop() { + renderer = null; + } + + private Thread renderer; + private int shapeIndex = 0; + private byte[] indices = new byte[NUMTESTS * NUMTESTS]; + boolean testdone = false; + + private synchronized void setShape(int index) { + shapeIndex = index; + testdone = false; + start(); + } + + public void run() { + Thread me = Thread.currentThread(); + Graphics2D g2d = (Graphics2D) getGraphics(); + byte[] indices; + Shape s = testShapes[shapeIndex]; + synchronized (this) { + if (renderer != me) { + return; + } + this.indices = new byte[NUMTESTS * NUMTESTS]; + java.util.Arrays.fill(this.indices, (byte) 8); + indices = this.indices; + } + + System.err.printf("%s %s\n", g2d, Color.yellow); + g2d.setColor(Color.yellow); + g2d.fillRect(0, 0, TESTSIZE, TESTSIZE); + int numtests = 0; + long start = System.currentTimeMillis(); + for (int y = 0; renderer == me && y < TESTSIZE; y += BOXSIZE) { + for (int x = 0; renderer == me && x < TESTSIZE; x += BOXSIZE) { + byte index = 0; + if (s.intersects(x, y, BOXSIZE, BOXSIZE)) { + index += 1; + } + if (s.contains(x + BOXCENTER, y + BOXCENTER)) { + index += 2; + } + if (s.contains(x, y, BOXSIZE, BOXSIZE)) { + index += 4; + } + numtests++; + int i = (y / BOXSIZE) * NUMTESTS + (x / BOXSIZE); + indices[i] = index; + g2d.setColor(colors[index]); + g2d.fillRect(x, y, BOXSIZE, BOXSIZE); + } + } + synchronized (this) { + if (renderer != me) { + return; + } + g2d.setColor(new Color(0, 0, 1, .2f)); + g2d.fill(s); + testdone = true; + long end = System.currentTimeMillis(); + System.out.println(numtests + " tests took " + (end - start) + "ms"); + } + } + + public void paint(Graphics g) { + g.setColor(Color.yellow); + g.fillRect(0, 0, TESTSIZE, TESTSIZE); + byte[] indices = this.indices; + if (indices != null) { + for (int y = 0; y < TESTSIZE; y += BOXSIZE) { + for (int x = 0; x < TESTSIZE; x += BOXSIZE) { + int i = (y / BOXSIZE) * NUMTESTS + (x / BOXSIZE); + g.setColor(colors[indices[i]]); + g.fillRect(x, y, BOXSIZE, BOXSIZE); + } + } + } + Graphics2D g2d = (Graphics2D) g; + g2d.setColor(new Color(0, 0, 1, .2f)); + g2d.fill(testShapes[shapeIndex]); + } + } + + static volatile PathHitTestManual pathHitTestManual; + + private static void createAndShowGUI() { + pathHitTestManual = new PathHitTestManual(); + Frame frame = new Frame("PathHitTestManual test window"); + + frame.add(pathHitTestManual); + frame.setSize(400, 450); + + PassFailJFrame.addTestWindow(frame); + PassFailJFrame.positionTestWindow(frame, PassFailJFrame.Position.HORIZONTAL); + + frame.setVisible(true); + + pathHitTestManual.init(); + pathHitTestManual.start(); + } + + public static void doManual() throws Exception { + PassFailJFrame passFailJFrame = new PassFailJFrame.Builder() + .title("PathHitTestManual Instructions") + .instructions(INSTRUCTIONS) + .testTimeOut(5) + .rows(30) + .columns(70) + .screenCapture() + .build(); + + EventQueue.invokeAndWait(PathHitTestManual::createAndShowGUI); + try { + passFailJFrame.awaitAndCheck(); + } finally { + pathHitTestManual.stop(); + } + } + } +} diff --git a/test/jdk/java/awt/print/PrinterJob/PrintLatinCJKTest.java b/test/jdk/java/awt/print/PrinterJob/PrintLatinCJKTest.java index 785855749a8..f6221aa5706 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintLatinCJKTest.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintLatinCJKTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, 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 @@ -98,8 +98,13 @@ public int print(Graphics g, PageFormat pf, int pageIndex) } public static void main(String[] args) throws InterruptedException, InvocationTargetException { - PassFailJFrame passFailJFrame = new PassFailJFrame("Test Instruction" + - "Frame", info, 10, 10, 45); + PassFailJFrame passFailJFrame = new PassFailJFrame.Builder() + .title("Test Instructions Frame") + .instructions(info) + .testTimeOut(10) + .rows(10) + .columns(45) + .build(); showFrame(); passFailJFrame.awaitAndCheck(); } diff --git a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java index a13d6ee2e08..15a914934e7 100644 --- a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java +++ b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, 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 @@ -21,35 +21,136 @@ * questions. */ +import java.awt.AWTException; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; +import java.awt.Image; import java.awt.Insets; +import java.awt.Point; import java.awt.Rectangle; +import java.awt.Robot; import java.awt.Toolkit; import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.awt.image.RenderedImage; +import java.io.File; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.imageio.ImageIO; import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JComponent; import javax.swing.JDialog; +import javax.swing.JEditorPane; import javax.swing.JFrame; import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.Timer; +import javax.swing.text.JTextComponent; +import javax.swing.text.html.HTMLEditorKit; +import javax.swing.text.html.StyleSheet; - +import static java.util.Collections.unmodifiableList; import static javax.swing.SwingUtilities.invokeAndWait; import static javax.swing.SwingUtilities.isEventDispatchThread; -public class PassFailJFrame { +/** + * Provides a framework for manual tests to display test instructions and + * Pass/Fail buttons. + *

    + * Instructions for the user can be either plain text or HTML as supported + * by Swing. If the instructions start with {@code }, the + * instructions are displayed as HTML. + *

    + * A simple test would look like this: + *

    {@code
    + * public class SampleManualTest {
    + *     private static final String INSTRUCTIONS =
    + *             "Click Pass, or click Fail if the test failed.";
    + *
    + *     public static void main(String[] args) throws Exception {
    + *         PassFailJFrame.builder()
    + *                       .instructions(INSTRUCTIONS)
    + *                       .testUI(() -> createTestUI())
    + *                       .build()
    + *                       .awaitAndCheck();
    + *     }
    + *
    + *     private static Window createTestUI() {
    + *         JFrame testUI = new JFrame("Test UI");
    + *         testUI.setSize(250, 150);
    + *         return testUI;
    + *     }
    + * }
    + * }
    + *

    + * The above example uses the {@link Builder Builder} to set the parameters of + * the instruction frame. It is the recommended way. + *

    + * The framework will create instruction UI, it will call + * the provided {@code createTestUI} on the Event Dispatch Thread (EDT), + * and it will automatically position the test UI and make it visible. + *

    + * The {@code Builder.testUI} methods accept interfaces which create one window + * or a list of windows if the test needs multiple windows, + * or directly a single window, an array of windows or a list of windows. + *

    + * Alternatively, use one of the {@code PassFailJFrame} constructors to + * create an object, then create secondary test UI, register it + * with {@code PassFailJFrame}, position it and make it visible. + * The following sample demonstrates it: + *

    {@code
    + * public class SampleOldManualTest {
    + *     private static final String INSTRUCTIONS =
    + *             "Click Pass, or click Fail if the test failed.";
    + *
    + *     public static void main(String[] args) throws Exception {
    + *         PassFailJFrame passFail = new PassFailJFrame(INSTRUCTIONS);
    + *
    + *         SwingUtilities.invokeAndWait(() -> createTestUI());
    + *
    + *         passFail.awaitAndCheck();
    + *     }
    + *
    + *     private static void createTestUI() {
    + *         JFrame testUI = new JFrame("Test UI");
    + *         testUI.setSize(250, 150);
    + *         PassFailJFrame.addTestWindow(testUI);
    + *         PassFailJFrame.positionTestWindow(testUI, PassFailJFrame.Position.HORIZONTAL);
    + *         testUI.setVisible(true);
    + *     }
    + * }
    + * }
    + *

    + * Use methods of the {@code Builder} class or constructors of the + * {@code PassFailJFrame} class to control other parameters: + *

      + *
    • the title of the instruction UI,
    • + *
    • the timeout of the test,
    • + *
    • the size of the instruction UI via rows and columns, and
    • + *
    • to enable screenshots.
    • + *
    + */ +public final class PassFailJFrame { private static final String TITLE = "Test Instruction Frame"; private static final long TEST_TIMEOUT = 5; @@ -60,16 +161,33 @@ public class PassFailJFrame { * Prefix for the user-provided failure reason. */ private static final String FAILURE_REASON = "Failure Reason:\n"; + /** + * The failure reason message when the user didn't provide one. + */ + private static final String EMPTY_REASON = "(no reason provided)"; private static final List windowList = new ArrayList<>(); - private static final Timer timer = new Timer(0, null); + private static final CountDownLatch latch = new CountDownLatch(1); - private static volatile boolean failed; - private static volatile boolean timeout; - private static volatile String testFailedReason; + private static TimeoutHandler timeoutHandler; + + /** + * The description of why the test fails. + *

    + * Note: do not use this field directly, + * use the {@link #setFailureReason(String) setFailureReason} and + * {@link #getFailureReason() getFailureReason} methods to modify and + * to read its value. + */ + private static String failureReason; + + private static final AtomicInteger imgCounter = new AtomicInteger(0); + private static JFrame frame; + private static Robot robot; + public enum Position {HORIZONTAL, VERTICAL, TOP_LEFT_CORNER} public PassFailJFrame(String instructions) throws InterruptedException, @@ -114,84 +232,446 @@ public PassFailJFrame(String title, String instructions, public PassFailJFrame(String title, String instructions, long testTimeOut, int rows, int columns) throws InterruptedException, InvocationTargetException { + this(title, instructions, testTimeOut, rows, columns, false); + } + + /** + * Constructs a JFrame with a given title & serves as test instructional + * frame where the user follows the specified test instruction in order + * to test the test case & mark the test pass or fail. If the expected + * result is seen then the user click on the 'Pass' button else click + * on the 'Fail' button and the reason for the failure should be + * specified in the JDialog JTextArea. + *

    + * The test instruction frame also provides a way for the tester to take + * a screenshot (full screen or individual frame) if this feature + * is enabled by passing {@code true} as {@code enableScreenCapture} + * parameter. + * + * @param title title of the Frame. + * @param instructions the instruction for the tester on how to test + * and what is expected (pass) and what is not + * expected (fail). + * @param testTimeOut test timeout where time is specified in minutes. + * @param rows number of visible rows of the JTextArea where the + * instruction is show. + * @param columns Number of columns of the instructional + * JTextArea + * @param enableScreenCapture if set to true, 'Capture Screen' button & its + * associated UIs are added to test instruction + * frame + * @throws InterruptedException exception thrown when thread is + * interrupted + * @throws InvocationTargetException if an exception is thrown while + * creating the test instruction frame on + * EDT + */ + public PassFailJFrame(String title, String instructions, long testTimeOut, + int rows, int columns, + boolean enableScreenCapture) + throws InterruptedException, InvocationTargetException { + invokeOnEDT(() -> createUI(title, instructions, + testTimeOut, + rows, columns, + enableScreenCapture)); + } + + private PassFailJFrame(Builder builder) throws InterruptedException, + InvocationTargetException { + this(builder.title, builder.instructions, builder.testTimeOut, + builder.rows, builder.columns, builder.screenCapture); + + if (builder.windowListCreator != null) { + invokeOnEDT(() -> + builder.testWindows = builder.windowListCreator.createTestUI()); + if (builder.testWindows == null) { + throw new IllegalStateException("Window list creator returned null list"); + } + } + + if (builder.testWindows != null) { + if (builder.testWindows.isEmpty()) { + throw new IllegalStateException("Window list is empty"); + } + addTestWindow(builder.testWindows); + builder.testWindows + .forEach(w -> w.addWindowListener(windowClosingHandler)); + + if (builder.positionWindows != null) { + positionInstructionFrame(builder.position); + invokeOnEDT(() -> { + builder.positionWindows + .positionTestWindows(unmodifiableList(builder.testWindows), + builder.instructionUIHandler); + }); + } else if (builder.testWindows.size() == 1) { + Window window = builder.testWindows.get(0); + positionTestWindow(window, builder.position); + } else { + positionTestWindow(null, builder.position); + } + } + showAllWindows(); + } + + /** + * Performs an operation on EDT. If called on EDT, invokes {@code run} + * directly, otherwise wraps into {@code invokeAndWait}. + * + * @param doRun an operation to run on EDT + * @throws InterruptedException if we're interrupted while waiting for + * the event dispatching thread to finish executing + * {@code doRun.run()} + * @throws InvocationTargetException if an exception is thrown while + * running {@code doRun} + * @see javax.swing.SwingUtilities#invokeAndWait(Runnable) + */ + private static void invokeOnEDT(Runnable doRun) + throws InterruptedException, InvocationTargetException { if (isEventDispatchThread()) { - createUI(title, instructions, testTimeOut, rows, columns); + doRun.run(); } else { - invokeAndWait(() -> createUI(title, instructions, testTimeOut, - rows, columns)); + invokeAndWait(doRun); } } private static void createUI(String title, String instructions, - long testTimeOut, int rows, int columns) { + long testTimeOut, int rows, int columns, + boolean enableScreenCapture) { frame = new JFrame(title); frame.setLayout(new BorderLayout()); - JTextArea instructionsText = new JTextArea(instructions, rows, columns); - instructionsText.setEditable(false); - instructionsText.setLineWrap(true); - - long tTimeout = TimeUnit.MINUTES.toMillis(testTimeOut); - - final JLabel testTimeoutLabel = new JLabel(String.format("Test " + - "timeout: %s", convertMillisToTimeStr(tTimeout)), JLabel.CENTER); - final long startTime = System.currentTimeMillis(); - timer.setDelay(1000); - timer.addActionListener((e) -> { - long leftTime = tTimeout - (System.currentTimeMillis() - startTime); - if ((leftTime < 0) || failed) { - timer.stop(); - testFailedReason = FAILURE_REASON - + "Timeout User did not perform testing."; - timeout = true; - latch.countDown(); - } - testTimeoutLabel.setText(String.format("Test timeout: %s", convertMillisToTimeStr(leftTime))); - }); - timer.start(); + + JLabel testTimeoutLabel = new JLabel("", JLabel.CENTER); + timeoutHandler = new TimeoutHandler(testTimeoutLabel, testTimeOut); frame.add(testTimeoutLabel, BorderLayout.NORTH); - frame.add(new JScrollPane(instructionsText), BorderLayout.CENTER); + + JTextComponent text = instructions.startsWith("") + ? configureHTML(instructions, rows, columns) + : configurePlainText(instructions, rows, columns); + text.setEditable(false); + + frame.add(new JScrollPane(text), BorderLayout.CENTER); JButton btnPass = new JButton("Pass"); btnPass.addActionListener((e) -> { latch.countDown(); - timer.stop(); + timeoutHandler.stop(); }); JButton btnFail = new JButton("Fail"); btnFail.addActionListener((e) -> { - getFailureReason(); - timer.stop(); + requestFailureReason(); + timeoutHandler.stop(); }); JPanel buttonsPanel = new JPanel(); buttonsPanel.add(btnPass); buttonsPanel.add(btnFail); - frame.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - super.windowClosing(e); - testFailedReason = FAILURE_REASON - + "User closed the instruction Frame"; - failed = true; - latch.countDown(); - } - }); + if (enableScreenCapture) { + buttonsPanel.add(createCapturePanel()); + } + + frame.addWindowListener(windowClosingHandler); frame.add(buttonsPanel, BorderLayout.SOUTH); frame.pack(); frame.setLocationRelativeTo(null); - windowList.add(frame); + addTestWindow(frame); + } + + private static JTextComponent configurePlainText(String instructions, + int rows, int columns) { + JTextArea text = new JTextArea(instructions, rows, columns); + text.setLineWrap(true); + text.setWrapStyleWord(true); + return text; + } + + private static JTextComponent configureHTML(String instructions, + int rows, int columns) { + JEditorPane text = new JEditorPane("text/html", instructions); + text.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, + Boolean.TRUE); + // Set preferred size as if it were JTextArea + text.setPreferredSize(new JTextArea(rows, columns).getPreferredSize()); + + HTMLEditorKit kit = (HTMLEditorKit) text.getEditorKit(); + StyleSheet styles = kit.getStyleSheet(); + // Reduce the default margins + styles.addRule("ol, ul { margin-left-ltr: 20; margin-left-rtl: 20 }"); + // Make the size of code blocks the same as other text + styles.addRule("code { font-size: inherit }"); + + return text; + } + + + /** + * Creates a test UI window. + */ + @FunctionalInterface + public interface WindowCreator { + /** + * Creates a window for test UI. + * This method is called by the framework on the EDT. + * @return a test UI window + */ + Window createTestUI(); + } + + /** + * Creates a list of test UI windows. + */ + @FunctionalInterface + public interface WindowListCreator { + /** + * Creates one or more windows for test UI. + * This method is called by the framework on the EDT. + * @return a list of test UI windows + */ + List createTestUI(); + } + + /** + * Positions test UI windows. + */ + @FunctionalInterface + public interface PositionWindows { + /** + * Positions test UI windows. + * This method is called by the framework on the EDT after + * the instruction UI frame was positioned on the screen. + *

    + * The list of the test windows contains the windows + * that were passed to the framework via the + * {@link Builder#testUI(Window...) testUI(Window...)} method or + * that were created with {@code WindowCreator} + * or {@code WindowListCreator} which were passed via + * {@link Builder#testUI(WindowCreator) testUI(WindowCreator)} or + * {@link Builder#testUI(WindowListCreator) testUI(WindowListCreator)} + * correspondingly. + * + * @param testWindows the list of test windows + * @param instructionUI information about the instruction frame + */ + void positionTestWindows(List testWindows, + InstructionUI instructionUI); } - private static String convertMillisToTimeStr(long millis) { - if (millis < 0) { - return "00:00:00"; + /** + * Provides information about the instruction frame. + */ + public interface InstructionUI { + /** + * {@return the location of the instruction frame} + */ + Point getLocation(); + + /** + * {@return the size of the instruction frame} + */ + Dimension getSize(); + + /** + * {@return the bounds of the instruction frame} + */ + Rectangle getBounds(); + + /** + * Allows to change the location of the instruction frame. + * + * @param location the new location of the instruction frame + */ + void setLocation(Point location); + + /** + * Allows to change the location of the instruction frame. + * + * @param x the x coordinate of the new location + * @param y the y coordinate of the new location + */ + void setLocation(int x, int y); + + /** + * Returns the specified position that was used to set + * the initial location of the instruction frame. + * + * @return the specified position + * + * @see Position + */ + Position getPosition(); + } + + + private static final class TimeoutHandler implements ActionListener { + private final long endTime; + + private final Timer timer; + + private final JLabel label; + + public TimeoutHandler(final JLabel label, final long testTimeOut) { + endTime = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(testTimeOut); + + this.label = label; + + timer = new Timer(1000, this); + timer.start(); + updateTime(testTimeOut); + } + + @Override + public void actionPerformed(ActionEvent e) { + long leftTime = endTime - System.currentTimeMillis(); + if (leftTime < 0) { + timer.stop(); + setFailureReason(FAILURE_REASON + + "Timeout - User did not perform testing."); + latch.countDown(); + } + updateTime(leftTime); + } + + private void updateTime(final long leftTime) { + if (leftTime < 0) { + label.setText("Test timeout: 00:00:00"); + return; + } + long hours = leftTime / 3_600_000; + long minutes = (leftTime - hours * 3_600_000) / 60_000; + long seconds = (leftTime - hours * 3_600_000 - minutes * 60_000) / 1_000; + label.setText(String.format("Test timeout: %02d:%02d:%02d", + hours, minutes, seconds)); + } + + public void stop() { + timer.stop(); } - long hours = millis / 3_600_000; - long minutes = (millis - hours * 3_600_000) / 60_000; - long seconds = (millis - hours * 3_600_000 - minutes * 60_000) / 1_000; - return String.format("%02d:%02d:%02d", hours, minutes, seconds); + } + + + private static final class WindowClosingHandler extends WindowAdapter { + @Override + public void windowClosing(WindowEvent e) { + setFailureReason(FAILURE_REASON + + "User closed a window"); + latch.countDown(); + } + } + + private static final WindowListener windowClosingHandler = + new WindowClosingHandler(); + + + private static JComponent createCapturePanel() { + JComboBox screenShortType = new JComboBox<>(CaptureType.values()); + + JButton capture = new JButton("ScreenShot"); + capture.addActionListener((e) -> + captureScreen((CaptureType) screenShortType.getSelectedItem())); + + JPanel panel = new JPanel(); + panel.add(screenShortType); + panel.add(capture); + return panel; + } + + private enum CaptureType { + FULL_SCREEN("Capture Full Screen"), + WINDOWS("Capture Individual Frame"); + + private final String type; + CaptureType(String type) { + this.type = type; + } + + @Override + public String toString() { + return type; + } + } + + private static Robot createRobot() { + if (robot == null) { + try { + robot = new Robot(); + } catch (AWTException e) { + String errorMsg = "Failed to create an instance of Robot."; + JOptionPane.showMessageDialog(frame, errorMsg, "Failed", + JOptionPane.ERROR_MESSAGE); + forceFail(errorMsg + e.getMessage()); + } + } + return robot; + } + + private static void captureScreen(Rectangle bounds) { + Robot robot = createRobot(); + + List imageList = robot.createMultiResolutionScreenCapture(bounds) + .getResolutionVariants(); + Image image = imageList.get(imageList.size() - 1); + + File file = new File("CaptureScreen_" + + imgCounter.incrementAndGet() + ".png"); + try { + ImageIO.write((RenderedImage) image, "png", file); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static void captureScreen(CaptureType type) { + switch (type) { + case FULL_SCREEN: + Arrays.stream(GraphicsEnvironment.getLocalGraphicsEnvironment() + .getScreenDevices()) + .map(GraphicsDevice::getDefaultConfiguration) + .map(GraphicsConfiguration::getBounds) + .forEach(PassFailJFrame::captureScreen); + break; + + case WINDOWS: + windowList.stream() + .filter(Window::isShowing) + .map(Window::getBounds) + .forEach(PassFailJFrame::captureScreen); + break; + + default: + throw new IllegalStateException("Unexpected value of capture type"); + } + + JOptionPane.showMessageDialog(frame, + "Screen Captured Successfully", + "Screen Capture", + JOptionPane.INFORMATION_MESSAGE); + } + + /** + * Sets the failure reason which describes why the test fails. + * This method ensures the {@code failureReason} field does not change + * after it's set to a non-{@code null} value. + * @param reason the description of why the test fails + * @throws IllegalArgumentException if the {@code reason} parameter + * is {@code null} + */ + private static synchronized void setFailureReason(final String reason) { + if (reason == null) { + throw new IllegalArgumentException("The failure reason must not be null"); + } + if (failureReason == null) { + failureReason = reason; + } + } + + /** + * {@return the description of why the test fails} + */ + private static synchronized String getFailureReason() { + return failureReason; } /** @@ -212,32 +692,18 @@ public void awaitAndCheck() throws InterruptedException, InvocationTargetExcepti latch.await(); invokeAndWait(PassFailJFrame::disposeWindows); - if (timeout) { - throw new RuntimeException(testFailedReason); - } - - if (failed) { - throw new RuntimeException("Test failed! : " + testFailedReason); + String failure = getFailureReason(); + if (failure != null) { + throw new RuntimeException(failure); } System.out.println("Test passed!"); } /** - * Dispose all the window(s) i,e both the test instruction frame and - * the window(s) that is added via addTestWindow(Window testWindow) - */ - private static synchronized void disposeWindows() { - for (Window win : windowList) { - win.dispose(); - } - } - - /** - * Read the test failure reason and add the reason to the test result - * example in the jtreg .jtr file. + * Requests the description of the test failure reason from the tester. */ - private static void getFailureReason() { + private static void requestFailureReason() { final JDialog dialog = new JDialog(frame, "Test Failure ", true); dialog.setTitle("Failure reason"); JPanel jPanel = new JPanel(new BorderLayout()); @@ -245,7 +711,9 @@ private static void getFailureReason() { JButton okButton = new JButton("OK"); okButton.addActionListener((ae) -> { - testFailedReason = FAILURE_REASON + jTextArea.getText(); + String text = jTextArea.getText(); + setFailureReason(FAILURE_REASON + + (!text.isEmpty() ? text : EMPTY_REASON)); dialog.setVisible(false); }); @@ -260,11 +728,52 @@ private static void getFailureReason() { dialog.pack(); dialog.setVisible(true); - failed = true; + // Ensure the test fails even if the dialog is closed + // without clicking the OK button + setFailureReason(FAILURE_REASON + EMPTY_REASON); + dialog.dispose(); latch.countDown(); } + /** + * Disposes of all the windows. It disposes of the test instruction frame + * and all other windows added via {@link #addTestWindow(Window)}. + */ + private static synchronized void disposeWindows() { + windowList.forEach(Window::dispose); + } + + private static void positionInstructionFrame(final Position position) { + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + + // Get the screen insets to position the frame by taking into + // account the location of taskbar or menu bar on screen. + GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment() + .getDefaultScreenDevice() + .getDefaultConfiguration(); + Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc); + + switch (position) { + case HORIZONTAL: + int newX = ((screenSize.width / 2) - frame.getWidth()); + frame.setLocation((newX + screenInsets.left), + (frame.getY() + screenInsets.top)); + break; + + case VERTICAL: + int newY = ((screenSize.height / 2) - frame.getHeight()); + frame.setLocation((frame.getX() + screenInsets.left), + (newY + screenInsets.top)); + break; + + case TOP_LEFT_CORNER: + frame.setLocation(screenInsets.left, screenInsets.top); + break; + } + syncLocationToWindowManager(); + } + /** * Approximately positions the instruction frame relative to the test * window as specified by the {@code position} parameter. If {@code testWindow} @@ -295,40 +804,23 @@ private static void getFailureReason() { *

*/ public static void positionTestWindow(Window testWindow, Position position) { - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + positionInstructionFrame(position); - // Get the screen insets to position the frame by taking into - // account the location of taskbar/menubars on screen. - GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment() - .getDefaultScreenDevice().getDefaultConfiguration(); - Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc); + if (testWindow != null) { + switch (position) { + case HORIZONTAL: + case TOP_LEFT_CORNER: + testWindow.setLocation((frame.getX() + frame.getWidth() + 5), + frame.getY()); + break; - if (position.equals(Position.HORIZONTAL)) { - int newX = ((screenSize.width / 2) - frame.getWidth()); - frame.setLocation((newX + screenInsets.left), - (frame.getY() + screenInsets.top)); - syncLocationToWindowManager(); - if (testWindow != null) { - testWindow.setLocation((frame.getX() + frame.getWidth() + 5), - frame.getY()); - } - } else if (position.equals(Position.VERTICAL)) { - int newY = ((screenSize.height / 2) - frame.getHeight()); - frame.setLocation((frame.getX() + screenInsets.left), - (newY + screenInsets.top)); - syncLocationToWindowManager(); - if (testWindow != null) { - testWindow.setLocation(frame.getX(), - (frame.getY() + frame.getHeight() + 5)); - } - } else if (position.equals(Position.TOP_LEFT_CORNER)) { - frame.setLocation(screenInsets.left, screenInsets.top); - syncLocationToWindowManager(); - if (testWindow != null) { - testWindow.setLocation((frame.getX() + frame.getWidth() + 5), - frame.getY()); + case VERTICAL: + testWindow.setLocation(frame.getX(), + (frame.getY() + frame.getHeight() + 5)); + break; } } + // make instruction frame visible after updating // frame & window positions frame.setVisible(true); @@ -368,13 +860,7 @@ public static Rectangle getInstructionFrameBounds() throws InterruptedException, InvocationTargetException { final Rectangle[] bounds = {null}; - if (isEventDispatchThread()) { - bounds[0] = frame != null ? frame.getBounds() : null; - } else { - invokeAndWait(() -> { - bounds[0] = frame != null ? frame.getBounds() : null; - }); - } + invokeOnEDT(() -> bounds[0] = frame != null ? frame.getBounds() : null); return bounds[0]; } @@ -389,6 +875,39 @@ public static synchronized void addTestWindow(Window testWindow) { windowList.add(testWindow); } + /** + * Adds a collection of test windows to the windowList to be disposed of + * when the test completes. + * + * @param testWindows the collection of test windows to be disposed of + */ + public static synchronized void addTestWindow(Collection testWindows) { + windowList.addAll(testWindows); + } + + /** + * Displays all the windows in {@code windowList}. + * + * @throws InterruptedException if the thread is interrupted while + * waiting for the event dispatch thread to finish running + * the {@link #showUI() showUI} + * @throws InvocationTargetException if an exception is thrown while + * the event dispatch thread executes {@code showUI} + */ + private static void showAllWindows() + throws InterruptedException, InvocationTargetException { + invokeOnEDT(PassFailJFrame::showUI); + } + + /** + * Displays all the windows in {@code windowList}; it has to be called on + * the EDT — use {@link #showAllWindows() showAllWindows} to ensure it. + */ + private static synchronized void showUI() { + windowList.forEach(w -> w.setVisible(true)); + } + + /** * Forcibly pass the test. *

The sample usage: @@ -417,8 +936,247 @@ public static void forceFail() { * @param reason the reason why the test is failed */ public static void forceFail(String reason) { - failed = true; - testFailedReason = FAILURE_REASON + reason; + setFailureReason(FAILURE_REASON + reason); latch.countDown(); } + + public static final class Builder { + private String title; + private String instructions; + private long testTimeOut; + private int rows; + private int columns; + private boolean screenCapture; + + private List testWindows; + private WindowListCreator windowListCreator; + private PositionWindows positionWindows; + private InstructionUI instructionUIHandler; + + private Position position; + + public Builder title(String title) { + this.title = title; + return this; + } + + public Builder instructions(String instructions) { + this.instructions = instructions; + return this; + } + + public Builder testTimeOut(long testTimeOut) { + this.testTimeOut = testTimeOut; + return this; + } + + public Builder rows(int rows) { + this.rows = rows; + return this; + } + + public Builder columns(int columns) { + this.columns = columns; + return this; + } + + public Builder screenCapture() { + this.screenCapture = true; + return this; + } + + /** + * Adds a {@code WindowCreator} which the framework will use + * to create the test UI window. + * + * @param windowCreator a {@code WindowCreator} + * to create the test UI window + * @return this builder + * @throws IllegalArgumentException if {@code windowCreator} is {@code null} + * @throws IllegalStateException if a window creator + * or a list of test windows is already set + */ + public Builder testUI(WindowCreator windowCreator) { + if (windowCreator == null) { + throw new IllegalArgumentException("The window creator can't be null"); + } + + checkWindowsLists(); + + this.windowListCreator = () -> List.of(windowCreator.createTestUI()); + return this; + } + + /** + * Adds a {@code WindowListCreator} which the framework will use + * to create a list of test UI windows. + * + * @param windowListCreator a {@code WindowListCreator} + * to create test UI windows + * @return this builder + * @throws IllegalArgumentException if {@code windowListCreator} is {@code null} + * @throws IllegalStateException if a window creator + * or a list of test windows is already set + */ + public Builder testUI(WindowListCreator windowListCreator) { + if (windowListCreator == null) { + throw new IllegalArgumentException("The window list creator can't be null"); + } + + checkWindowsLists(); + + this.windowListCreator = windowListCreator; + return this; + } + + /** + * Adds an already created test UI window. + * The window is positioned and shown automatically. + * + * @param window a test UI window + * @return this builder + */ + public Builder testUI(Window window) { + return testUI(List.of(window)); + } + + /** + * Adds an array of already created test UI windows. + * + * @param windows an array of test UI windows + * @return this builder + */ + public Builder testUI(Window... windows) { + return testUI(List.of(windows)); + } + + /** + * Adds a list of already created test UI windows. + * + * @param windows a list of test UI windows + * @return this builder + * @throws IllegalArgumentException if {@code windows} is {@code null} + * or the list contains {@code null} + * @throws IllegalStateException if a window creator + * or a list of test windows is already set + */ + public Builder testUI(List windows) { + if (windows == null) { + throw new IllegalArgumentException("The list of windows can't be null"); + } + if (windows.stream() + .anyMatch(Objects::isNull)) { + throw new IllegalArgumentException("The list of windows can't contain null"); + } + + checkWindowsLists(); + + this.testWindows = windows; + return this; + } + + /** + * Verifies the state of window list and window creator. + * + * @throws IllegalStateException if a windows list creator + * or a list of test windows is already set + */ + private void checkWindowsLists() { + if (windowListCreator != null) { + throw new IllegalStateException("Window list creator is already set"); + } + if (testWindows != null) { + throw new IllegalStateException("The list of test windows is already set"); + } + } + + public Builder positionTestUI(PositionWindows positionWindows) { + this.positionWindows = positionWindows; + return this; + } + + public Builder position(Position position) { + this.position = position; + return this; + } + + public PassFailJFrame build() throws InterruptedException, + InvocationTargetException { + validate(); + return new PassFailJFrame(this); + } + + private void validate() { + if (title == null) { + title = TITLE; + } + + if (instructions == null || instructions.isEmpty()) { + throw new IllegalStateException("Please provide the test " + + "instructions for this manual test"); + } + + if (testTimeOut == 0L) { + testTimeOut = TEST_TIMEOUT; + } + + if (rows == 0) { + rows = ROWS; + } + + if (columns == 0) { + columns = COLUMNS; + } + + if (position == null + && (testWindows != null || windowListCreator != null)) { + + position = Position.HORIZONTAL; + } + + if (positionWindows != null) { + if (testWindows == null && windowListCreator == null) { + throw new IllegalStateException("To position windows, " + + "provide an a list of windows to the builder"); + } + instructionUIHandler = new InstructionUIHandler(); + } + } + + private final class InstructionUIHandler implements InstructionUI { + @Override + public Point getLocation() { + return frame.getLocation(); + } + + @Override + public Dimension getSize() { + return frame.getSize(); + } + + @Override + public Rectangle getBounds() { + return frame.getBounds(); + } + + @Override + public void setLocation(Point location) { + setLocation(location.x, location.y); + } + + @Override + public void setLocation(int x, int y) { + frame.setLocation(x, y); + } + + @Override + public Position getPosition() { + return position; + } + } + } + + public static Builder builder() { + return new Builder(); + } } diff --git a/test/jdk/java/foreign/channels/TestAsyncSocketChannels.java b/test/jdk/java/foreign/channels/TestAsyncSocketChannels.java index 1189600ddfe..d53ad4a5c6c 100644 --- a/test/jdk/java/foreign/channels/TestAsyncSocketChannels.java +++ b/test/jdk/java/foreign/channels/TestAsyncSocketChannels.java @@ -221,7 +221,6 @@ public void testCloseWithOutstandingRead(Supplier scopeSupplier, ioOp.accept(handler); assertFalse(handler.isDone()); assertTrue(scope.isAlive()); - assertMessage(expectThrows(ISE, () -> scope.close()), "Scope is acquired by"); // write to allow the blocking read complete, which will // in turn unlock the scope and allow it to be closed. @@ -270,7 +269,6 @@ public void completed(Long result, Void att) { // give time for socket buffer to fill up. awaitNoFurtherWrites(bytesWritten); - assertMessage(expectThrows(ISE, () -> scope.close()), "Scope is acquired by"); assertTrue(scope.isAlive()); // signal handler to stop further writing diff --git a/test/jdk/java/io/File/createTempFile/SpecialTempFile.java b/test/jdk/java/io/File/createTempFile/SpecialTempFile.java index a2fa85524a0..736e721d641 100644 --- a/test/jdk/java/io/File/createTempFile/SpecialTempFile.java +++ b/test/jdk/java/io/File/createTempFile/SpecialTempFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, 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,11 @@ /* * @test * @bug 8013827 8011950 8017212 8025128 + * @library /test/lib + * @modules java.base/jdk.internal.util * @summary Check whether File.createTempFile can handle special parameters + * @build jdk.test.lib.OSVersion jdk.test.lib.Platform + @run main SpecialTempFile * @author Dan Xu */ @@ -32,10 +36,11 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; -public class SpecialTempFile { +import jdk.test.lib.Platform; +import jdk.test.lib.OSVersion; +public class SpecialTempFile { private static void test(String name, String[] prefix, String[] suffix, boolean exceptionExpected) throws IOException { @@ -48,7 +53,7 @@ private static void test(String name, String[] prefix, String[] suffix, final String exceptionMsg = "Unable to create temporary file"; String[] dirs = { null, "." }; - Path testPath = Paths.get(System.getProperty("test.dir", ".")); + Path testPath = Path.of(System.getProperty("test.dir", ".")); for (int i = 0; i < prefix.length; i++) { boolean exceptionThrown = false; File f = null; @@ -99,12 +104,15 @@ public static void main(String[] args) throws Exception { test("SlashedName", slashPre, slashSuf, true); // Windows tests - if (!System.getProperty("os.name").startsWith("Windows")) + if (!Platform.isWindows()) return; // Test JDK-8013827 String[] resvPre = { "LPT1.package.zip", "com7.4.package.zip" }; String[] resvSuf = { ".temp", ".temp" }; - test("ReservedName", resvPre, resvSuf, true); + boolean exceptionExpected = + !(System.getProperty("os.name").endsWith("11") || + new OSVersion(10, 0).compareTo(OSVersion.current()) > 0); + test("ReservedName", resvPre, resvSuf, exceptionExpected); } } diff --git a/test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java b/test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java index d82a317148e..ca257a96430 100644 --- a/test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java +++ b/test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java @@ -25,7 +25,7 @@ /* * @test * @bug 8307990 - * @requires (os.family == "linux") | (os.family == "aix") + * @requires (os.family == "linux") | (os.family == "aix") | (os.family == "mac") * @requires vm.debug * @library /test/lib * @run main/othervm/timeout=300 JspawnhelperProtocol diff --git a/test/jdk/java/lang/SecurityManager/CheckAccessClassInPackagePermissions.java b/test/jdk/java/lang/SecurityManager/CheckAccessClassInPackagePermissions.java index 8e9e148b705..2fc98ed4494 100644 --- a/test/jdk/java/lang/SecurityManager/CheckAccessClassInPackagePermissions.java +++ b/test/jdk/java/lang/SecurityManager/CheckAccessClassInPackagePermissions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -50,9 +50,6 @@ 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 @@ -91,16 +88,9 @@ public static void main(String[] args) throws Exception { // Check if each target module has the right permissions to access // its qualified exports Policy policy = Policy.getPolicy(); - List deployMods = Arrays.asList(deployModules); for (Map.Entry> 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 = bootLayer.findModule(moduleName); if (!module.isPresent()) { diff --git a/test/jdk/java/lang/String/CompactString/NegativeSize.java b/test/jdk/java/lang/String/CompactString/NegativeSize.java new file mode 100644 index 00000000000..34e9ae4b435 --- /dev/null +++ b/test/jdk/java/lang/String/CompactString/NegativeSize.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023, 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.IOException; +import java.nio.charset.StandardCharsets; + +/* + * @test + * @bug 8077559 + * @summary Tests Compact String for negative size. + * @requires vm.bits == 64 & os.maxMemory >= 4G + * @compile -encoding utf-8 NegativeSize.java + * @run main/othervm -XX:+CompactStrings -Xmx4g NegativeSize + * @run main/othervm -XX:-CompactStrings -Xmx4g NegativeSize + */ + +// In Java8: java.lang.OutOfMemoryError: Java heap space +// In Java9+: was java.lang.NegativeArraySizeException: -1894967266 +public class NegativeSize { + + static byte[] generateData() { + int asciisize = 1_200_000_000; + byte[] nonAscii = "非アスキー".getBytes(); + int nonAsciiSize = nonAscii.length; + // 1 GB + byte[] arr = new byte[asciisize + nonAsciiSize]; + for (int i=0; i= 2G - * @requires !(os.family == "windows" & sun.arch.data.model == "32") + * @requires vm.bits == "64" * @run main/othervm -Xmx2g StringRepeat 16777216 */ diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/TestException.java b/test/jdk/java/lang/invoke/MethodHandleProxies/Driver.java similarity index 72% rename from test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/TestException.java rename to test/jdk/java/lang/invoke/MethodHandleProxies/Driver.java index 8b4fbb44406..6acd4fb30e1 100644 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/TestException.java +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/Driver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -21,14 +21,12 @@ * questions. */ -package org.reactivestreams.tck.flow.support; - /** - * Exception used by the TCK to signal failures. - * May be thrown or signalled through {@link org.reactivestreams.Subscriber#onError(Throwable)}. + * @test + * @bug 8280377 + * @build m1/* m2/* Unnamed + * @run testng/othervm m1/p1.Main + * @run testng/othervm Unnamed + * @summary Test MethodHandleProxies::asInterfaceInstance with a default + * method with varargs */ -public final class TestException extends RuntimeException { - public TestException() { - super("Test Exception: Boom!"); - } -} diff --git a/test/jdk/java/lang/invoke/MethodHandlesProxiesTest.java b/test/jdk/java/lang/invoke/MethodHandleProxies/MethodHandlesProxiesTest.java similarity index 100% rename from test/jdk/java/lang/invoke/MethodHandlesProxiesTest.java rename to test/jdk/java/lang/invoke/MethodHandleProxies/MethodHandlesProxiesTest.java diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersDiscarding.java b/test/jdk/java/lang/invoke/MethodHandleProxies/Unnamed.java similarity index 54% rename from test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersDiscarding.java rename to test/jdk/java/lang/invoke/MethodHandleProxies/Unnamed.java index 640000a8efc..f42071f0427 100644 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersDiscarding.java +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/Unnamed.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -21,29 +21,25 @@ * questions. */ -import org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandleProxies; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Method; -import java.net.http.HttpResponse.BodySubscribers; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.concurrent.Flow.Subscriber; +import static org.testng.Assert.*; -/* See TckDriver.java for more information */ -public class BodySubscribersDiscarding - extends FlowSubscriberBlackboxVerification> { - - public BodySubscribersDiscarding() { - super(new TestEnvironment(450L)); - } - - @Override - public Subscriber> createFlowSubscriber() { - return BodySubscribers.discarding(); - } +/* + * Test MethodHandleProxies::asInterfaceInstance with an inaccessible interface + */ +public class Unnamed { + public static void main(String... args) throws Throwable { + MethodHandle target = MethodHandles.constant(String.class, "test"); + Class intf = Class.forName("p2.TestIntf"); + Object t = MethodHandleProxies.asInterfaceInstance(intf, target); - @Override - public List createElement(int element) { - return S.listOfBuffersFromBufferOfNBytes(element % 17); + // verify that the caller has no access to the proxy created on an + // inaccessible interface + Method m = intf.getMethod("test", Object[].class); + assertFalse(m.canAccess(null)); } } diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Processor.java b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/module-info.java similarity index 68% rename from test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Processor.java rename to test/jdk/java/lang/invoke/MethodHandleProxies/m1/module-info.java index 0b76901b4f5..1bdeddce28f 100644 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Processor.java +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -20,15 +20,8 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ - -package org.reactivestreams; - -/** - * A Processor represents a processing stage—which is both a {@link Subscriber} - * and a {@link Publisher} and obeys the contracts of both. - * - * @param the type of element signaled to the {@link Subscriber} - * @param the type of element signaled by the {@link Publisher} - */ -public interface Processor extends Subscriber, Publisher { +module m1 { + requires m2; + requires org.testng; + exports p1; } diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/m1/p1/Main.java b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/p1/Main.java new file mode 100644 index 00000000000..df71809996b --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/p1/Main.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2022, 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 p1; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandleProxies; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.util.Arrays; +import java.util.stream.Collectors; + +import p2.TestIntf; + +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +public class Main { + public interface A { + default String aConcat(Object... objs) { return Arrays.deepToString(objs); } + } + + public interface B { + default String bConcat(Object[] objs) { return Arrays.deepToString(objs); } + } + + public interface C extends A, B { + String c(Object... objs); + } + + private static String concat(Object... objs) { + return Arrays.stream(objs).map(Object::toString).collect(Collectors.joining()); + } + + /* + * Test the invocation of default methods with varargs + */ + @Test + public static void testVarargsMethods() throws Throwable { + MethodHandle target = MethodHandles.lookup().findStatic(Main.class, + "concat", MethodType.methodType(String.class, Object[].class)); + C proxy = MethodHandleProxies.asInterfaceInstance(C.class, target); + + assertEquals(proxy.c("a", "b", "c"), "abc"); + assertEquals(proxy.aConcat("a", "b", "c"), "[a, b, c]"); + assertEquals(proxy.aConcat(new Object[] { "a", "b", "c" }), "[a, b, c]"); + assertEquals(proxy.bConcat(new Object[] { "a", "b", "c" }), "[a, b, c]"); + } + + /* + * Test the invocation of a default method of an accessible interface + */ + @Test + public static void modulePrivateInterface() { + MethodHandle target = MethodHandles.constant(String.class, "test"); + TestIntf t = MethodHandleProxies.asInterfaceInstance(TestIntf.class, target); + assertEquals(t.test(), "test"); + } +} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/SubscriberBufferOverflowException.java b/test/jdk/java/lang/invoke/MethodHandleProxies/m2/module-info.java similarity index 65% rename from test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/SubscriberBufferOverflowException.java rename to test/jdk/java/lang/invoke/MethodHandleProxies/m2/module-info.java index 822493619cb..1015757fc9c 100644 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/SubscriberBufferOverflowException.java +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/m2/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -20,22 +20,6 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ - -package org.reactivestreams.tck.flow.support; - -public final class SubscriberBufferOverflowException extends RuntimeException { - public SubscriberBufferOverflowException() { - } - - public SubscriberBufferOverflowException(String message) { - super(message); - } - - public SubscriberBufferOverflowException(String message, Throwable cause) { - super(message, cause); - } - - public SubscriberBufferOverflowException(Throwable cause) { - super(cause); - } +module m2 { + exports p2 to m1; } diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/Function.java b/test/jdk/java/lang/invoke/MethodHandleProxies/m2/p2/TestIntf.java similarity index 83% rename from test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/Function.java rename to test/jdk/java/lang/invoke/MethodHandleProxies/m2/p2/TestIntf.java index c3d26a5bdd8..a87d248e0c8 100644 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/Function.java +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/m2/p2/TestIntf.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -20,9 +20,8 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ +package p2; -package org.reactivestreams.tck.flow.support; - -public interface Function { - public Out apply(In in) throws Throwable; +public interface TestIntf { + String test(); } diff --git a/test/jdk/java/lang/module/ModuleDescriptorHashCodeTest.java b/test/jdk/java/lang/module/ModuleDescriptorHashCodeTest.java index 78b124d8701..c1269f28c48 100644 --- a/test/jdk/java/lang/module/ModuleDescriptorHashCodeTest.java +++ b/test/jdk/java/lang/module/ModuleDescriptorHashCodeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, 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 @@ -21,22 +21,24 @@ * questions. */ -import org.testng.annotations.Test; - import java.io.IOException; import java.io.InputStream; import java.lang.module.ModuleDescriptor; +import java.lang.module.ModuleDescriptor.Exports; +import java.lang.module.ModuleDescriptor.Opens; +import java.lang.module.ModuleDescriptor.Requires; import java.util.Set; +import org.testng.annotations.Test; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotSame; /** * @test - * @bug 8275509 + * @bug 8275509 8290041 + * @summary Tests the ModuleDescriptor.hashCode() * @run testng ModuleDescriptorHashCodeTest * @run testng/othervm -Xshare:off ModuleDescriptorHashCodeTest - * @summary Tests the ModuleDescriptor.hashCode() for boot layer modules */ public class ModuleDescriptorHashCodeTest { @@ -63,6 +65,99 @@ public void testBootModuleDescriptor() throws Exception { } } + /** + * Verifies that two "equal" module descriptors which only differ in the order of + * {@link ModuleDescriptor.Opens.Modifier opens modifiers}, that were used to construct the + * descriptors, have the same hashcode. + */ + @Test + public void testOpensModifiersOrdering() throws Exception { + // important to use Set.of() (i.e. backed by immutable set) to reproduce the issue + final Set mods1 = Set.of(Opens.Modifier.SYNTHETIC, Opens.Modifier.MANDATED); + final ModuleDescriptor desc1 = createModuleDescriptor(mods1, null, null); + + // create the same module descriptor again and this time just change the order of the + // "opens" modifiers' Set. + + // important to use Set.of() (i.e. backed by immutable set) to reproduce the issue + final Set mods2 = Set.of(Opens.Modifier.MANDATED, Opens.Modifier.SYNTHETIC); + final ModuleDescriptor desc2 = createModuleDescriptor(mods2, null, null); + + // basic verification of the modifiers themselves before we check the module descriptors + assertEquals(mods1, mods2, "Modifiers were expected to be equal"); + + // now verify the module descriptors + assertEquals(desc1, desc2, "Module descriptors were expected to be equal"); + assertEquals(desc1.compareTo(desc2), 0, "compareTo was expected to return" + + " 0 for module descriptors that are equal"); + System.out.println(desc1 + " hashcode = " + desc1.hashCode()); + System.out.println(desc2 + " hashcode = " + desc2.hashCode()); + assertEquals(desc1.hashCode(), desc2.hashCode(), "Module descriptor hashcodes" + + " were expected to be equal"); + } + + /** + * Verifies that two "equal" module descriptors which only differ in the order of + * {@link ModuleDescriptor.Exports.Modifier exports modifiers}, that were used to construct the + * descriptors, have the same hashcode. + */ + @Test + public void testExportsModifiersOrdering() throws Exception { + // important to use Set.of() (i.e. backed by immutable set) to reproduce the issue + final Set mods1 = Set.of(Exports.Modifier.SYNTHETIC, Exports.Modifier.MANDATED); + final ModuleDescriptor desc1 = createModuleDescriptor(null, null, mods1); + + // create the same module descriptor again and this time just change the order of the + // "exports" modifiers' Set. + + // important to use Set.of() (i.e. backed by immutable set) to reproduce the issue + final Set mods2 = Set.of(Exports.Modifier.MANDATED, Exports.Modifier.SYNTHETIC); + final ModuleDescriptor desc2 = createModuleDescriptor(null, null, mods2); + + // basic verification of the modifiers themselves before we check the module descriptors + assertEquals(mods1, mods2, "Modifiers were expected to be equal"); + + // now verify the module descriptors + assertEquals(desc1, desc2, "Module descriptors were expected to be equal"); + assertEquals(desc1.compareTo(desc2), 0, "compareTo was expected to return" + + " 0 for module descriptors that are equal"); + System.out.println(desc1 + " hashcode = " + desc1.hashCode()); + System.out.println(desc2 + " hashcode = " + desc2.hashCode()); + assertEquals(desc1.hashCode(), desc2.hashCode(), "Module descriptor hashcodes" + + " were expected to be equal"); + } + + /** + * Verifies that two "equal" module descriptors which only differ in the order of + * {@link ModuleDescriptor.Requires.Modifier requires modifiers}, that were used to construct the + * descriptors, have the same hashcode. + */ + @Test + public void testRequiresModifiersOrdering() throws Exception { + // important to use Set.of() (i.e. backed by immutable set) to reproduce the issue + final Set mods1 = Set.of(Requires.Modifier.SYNTHETIC, Requires.Modifier.MANDATED); + final ModuleDescriptor desc1 = createModuleDescriptor(null, mods1, null); + + // create the same module descriptor again and this time just change the order of the + // "exports" modifiers' Set. + + // important to use Set.of() (i.e. backed by immutable set) to reproduce the issue + final Set mods2 = Set.of(Requires.Modifier.MANDATED, Requires.Modifier.SYNTHETIC); + final ModuleDescriptor desc2 = createModuleDescriptor(null, mods2, null); + + // basic verification of the modifiers themselves before we check the module descriptors + assertEquals(mods1, mods2, "Modifiers were expected to be equal"); + + // now verify the module descriptors + assertEquals(desc1, desc2, "Module descriptors were expected to be equal"); + assertEquals(desc1.compareTo(desc2), 0, "compareTo was expected to return" + + " 0 for module descriptors that are equal"); + System.out.println(desc1 + " hashcode = " + desc1.hashCode()); + System.out.println(desc2 + " hashcode = " + desc2.hashCode()); + assertEquals(desc1.hashCode(), desc2.hashCode(), "Module descriptor hashcodes" + + " were expected to be equal"); + } + // Returns a ModuleDescriptor parsed out of the module-info.class of the passed Module private static ModuleDescriptor fromModuleInfoClass(Module module) throws IOException { try (InputStream moduleInfo = module.getResourceAsStream("module-info.class")) { @@ -73,4 +168,23 @@ private static ModuleDescriptor fromModuleInfoClass(Module module) throws IOExce return ModuleDescriptor.read(moduleInfo); } } + + // creates a module descriptor with passed (optional) opens/exports/requires modifiers + private static ModuleDescriptor createModuleDescriptor( + Set opensModifiers, + Set reqsModifiers, + Set expsModifiers) { + + final ModuleDescriptor.Builder builder = ModuleDescriptor.newModule("foobar"); + if (opensModifiers != null) { + builder.opens(opensModifiers, "a.p1", Set.of("a.m1")); + } + if (reqsModifiers != null) { + builder.requires(reqsModifiers, "a.m2"); + } + if (expsModifiers != null) { + builder.exports(expsModifiers, "a.b.c", Set.of("a.m3")); + } + return builder.build(); + } } diff --git a/test/jdk/java/math/BigInteger/BigIntegerTest.java b/test/jdk/java/math/BigInteger/BigIntegerTest.java index 9e19f2039b0..2ac4750e43f 100644 --- a/test/jdk/java/math/BigInteger/BigIntegerTest.java +++ b/test/jdk/java/math/BigInteger/BigIntegerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, 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 @@ -1222,6 +1222,17 @@ public static void serialize() throws Exception { * */ public static void main(String[] args) throws Exception { + // subset zero indicates to run all subsets + int subset = Integer.valueOf(System.getProperty("subset", + String.valueOf(1 + random.nextInt(3)))); + if (subset < 0 || subset > 3) { + throw new RuntimeException("Unknown subset " + subset); + } + if (subset == 0) + System.out.println("Testing all subsets"); + else + System.out.println("Testing subset " + subset); + // Some variables for sizing test numbers in bits int order1 = ORDER_MEDIUM; int order2 = ORDER_SMALL; @@ -1237,52 +1248,57 @@ public static void main(String[] args) throws Exception { if (args.length >3) order4 = (int)((Integer.parseInt(args[3]))* 3.333); - constructor(); - - prime(); - nextProbablePrime(); + if (subset == 0 || subset == 1) { + constructor(); - arithmetic(order1); // small numbers - arithmetic(order3); // Karatsuba range - arithmetic(order4); // Toom-Cook / Burnikel-Ziegler range + prime(); + nextProbablePrime(); - divideAndRemainder(order1); // small numbers - divideAndRemainder(order3); // Karatsuba range - divideAndRemainder(order4); // Toom-Cook / Burnikel-Ziegler range + arithmetic(order1); // small numbers + arithmetic(order3); // Karatsuba range + arithmetic(order4); // Toom-Cook / Burnikel-Ziegler range - pow(order1); - pow(order3); - pow(order4); + divideAndRemainder(order1); // small numbers + divideAndRemainder(order3); // Karatsuba range + divideAndRemainder(order4); // Toom-Cook / Burnikel-Ziegler range - square(ORDER_MEDIUM); - square(ORDER_KARATSUBA_SQUARE); - square(ORDER_TOOM_COOK_SQUARE); + pow(order1); + pow(order3); + pow(order4); - squareRoot(); - squareRootAndRemainder(); + square(ORDER_MEDIUM); + square(ORDER_KARATSUBA_SQUARE); + square(ORDER_TOOM_COOK_SQUARE); - bitCount(); - bitLength(); - bitOps(order1); - bitwise(order1); + squareRoot(); + squareRootAndRemainder(); - shift(order1); + bitCount(); + bitLength(); + bitOps(order1); + bitwise(order1); - byteArrayConv(order1); + shift(order1); - modInv(order1); // small numbers - modInv(order3); // Karatsuba range - modInv(order4); // Toom-Cook / Burnikel-Ziegler range + byteArrayConv(order1); - modExp(order1, order2); - modExp2(order1); + modInv(order1); // small numbers + modInv(order3); // Karatsuba range + } + if (subset == 0 || subset == 2) { + modInv(order4); // Toom-Cook / Burnikel-Ziegler range - stringConv(); - serialize(); + modExp(order1, order2); + modExp2(order1); + } + if (subset == 0 || subset == 3) { + stringConv(); + serialize(); - multiplyLarge(); - squareLarge(); - divideLarge(); + multiplyLarge(); + squareLarge(); + divideLarge(); + } if (failure) throw new RuntimeException("Failure in BigIntegerTest."); diff --git a/test/jdk/java/math/BigInteger/LargeValueExceptions.java b/test/jdk/java/math/BigInteger/LargeValueExceptions.java index 961f87f3f61..bba3a23b438 100644 --- a/test/jdk/java/math/BigInteger/LargeValueExceptions.java +++ b/test/jdk/java/math/BigInteger/LargeValueExceptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -30,6 +30,8 @@ */ import java.math.BigInteger; import static java.math.BigInteger.ONE; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; import org.testng.annotations.Test; // @@ -62,6 +64,13 @@ public class LargeValueExceptions { // Half BigInteger.MAX_MAG_LENGTH private static final int MAX_INTS_HALF = MAX_INTS / 2; + // Print the run time of each sub-test in milliseconds + @AfterMethod + public void getRunTime(ITestResult tr) { + long time = tr.getEndMillis() - tr.getStartMillis(); + System.out.printf("Run time: %d ms%n", time); + } + // --- squaring --- // Largest no overflow determined by examining data lengths alone. diff --git a/test/jdk/java/math/BigInteger/largeMemory/SymmetricRangeTests.java b/test/jdk/java/math/BigInteger/largeMemory/SymmetricRangeTests.java index e71afe6a028..cb8f5b04b83 100644 --- a/test/jdk/java/math/BigInteger/largeMemory/SymmetricRangeTests.java +++ b/test/jdk/java/math/BigInteger/largeMemory/SymmetricRangeTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, 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 @@ -46,6 +46,8 @@ public class SymmetricRangeTests { private static final BigInteger MAX_VALUE = makeMaxValue(); private static final BigInteger MIN_VALUE = MAX_VALUE.negate(); + private static final Random RANDOM = RandomFactory.getRandom(); + private static BigInteger makeMaxValue() { byte[] ba = new byte[1 << 28]; Arrays.fill(ba, (byte) 0xFF); @@ -117,8 +119,7 @@ private static void testOverflowInBitSieve() { System.out.println("Testing overflow in BitSieve.sieveSingle"); int bitLength = (5 << 27) - 1; try { - Random random = RandomFactory.getRandom(); - BigInteger actual = new BigInteger(bitLength, 0, random); + BigInteger actual = new BigInteger(bitLength, 0, RANDOM); throw new RuntimeException("new BigInteger(bitLength, 0, null).bitLength()=" + actual.bitLength()); } catch (ArithmeticException e) { // expected @@ -621,45 +622,64 @@ private static void testByteValueExact() { } public static void main(String... args) { - testOverflowInMakePositive(); - testBug8021204(); - testOverflowInBitSieve(); - testAdd(); - testSubtract(); - testMultiply(); - testDivide(); - testDivideAndRemainder(); - testBug9005933(); - testRemainder(); - testPow(); - testGcd(); - testAbs(); - testNegate(); - testMod(); - testModPow(); -// testModInverse(); - testShiftLeft(); - testShiftRight(); - testAnd(); - testOr(); - testXor(); - testNot(); - testSetBit(); - testClearBit(); - testFlipBit(); - testGetLowestSetBit(); - testBitLength(); - testBitCount(); - testToString(); - testToByteArrayWithConstructor(); - testIntValue(); - testLongValue(); - testFloatValue(); - testDoubleValue(); - testSerialization(); - testLongValueExact(); - testIntValueExact(); - testShortValueExact(); - testByteValueExact(); + // subset zero indicates to run all subsets + int subset = Integer.valueOf(System.getProperty("subset", + String.valueOf(1 + RANDOM.nextInt(4)))); + if (subset < 0 || subset > 4) { + throw new RuntimeException("Unknown subset " + subset); + } + if (subset == 0) + System.out.println("Testing all subsets"); + else + System.out.println("Testing subset " + subset); + + if (subset == 0 || subset == 1) { + testOverflowInMakePositive(); + testBug8021204(); + testOverflowInBitSieve(); + testAdd(); + testSubtract(); + } + if (subset == 0 || subset == 2) { + testMultiply(); + testDivide(); + testDivideAndRemainder(); + testBug9005933(); + } + if (subset == 0 || subset == 3) { + testRemainder(); + testPow(); + testGcd(); + testAbs(); + testNegate(); + testMod(); + testModPow(); + // testModInverse(); + testShiftLeft(); + testShiftRight(); + testAnd(); + testOr(); + testXor(); + testNot(); + testSetBit(); + testClearBit(); + testFlipBit(); + testGetLowestSetBit(); + testBitLength(); + testBitCount(); + } + if (subset == 0 || subset == 4) { + testToString(); + testToByteArrayWithConstructor(); + testIntValue(); + testLongValue(); + testFloatValue(); + testDoubleValue(); + testSerialization(); + testLongValueExact(); + testIntValueExact(); + testShortValueExact(); + testByteValueExact(); + } } } diff --git a/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java b/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java index 073b56d0ea0..c9b8bc85b70 100644 --- a/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java +++ b/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, 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,8 +27,11 @@ * @summary Verify that expect 100-continue doesn't hang * @library /test/lib * @run junit/othervm HttpURLConnectionExpectContinueTest + * @run junit/othervm -Djava.net.preferIPv4Stack=true HttpURLConnectionExpectContinueTest + * @run junit/othervm -Djava.net.preferIPv6Addresses=true HttpURLConnectionExpectContinueTest */ +import jdk.test.lib.net.URIBuilder; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -73,7 +76,7 @@ public void startServerSocket() throws Exception { control.serverSocket = new ServerSocket(); control.serverSocket.setReuseAddress(true); - control.serverSocket.bind(new InetSocketAddress("127.0.0.1", 54321)); + control.serverSocket.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); Runnable runnable = () -> { while (!control.stop) { try { @@ -419,12 +422,15 @@ public void testFixedLengthRequestWithDoubleExpect100ContinueResponse() throws E } // Creates a connection with all the common settings used in each test - private HttpURLConnection createConnection() throws IOException { - URL url = new URL("http://localhost:" + control.serverSocket.getLocalPort()); + private HttpURLConnection createConnection() throws Exception { + URL url = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(control.serverSocket.getLocalPort()) + .toURL(); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); - connection.setConnectTimeout(1000); connection.setReadTimeout(5000); connection.setUseCaches(false); connection.setInstanceFollowRedirects(false); diff --git a/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPSetAuthenticatorTest.java b/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPSetAuthenticatorTest.java index 48492099cc9..f4a408ae62b 100644 --- a/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPSetAuthenticatorTest.java +++ b/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPSetAuthenticatorTest.java @@ -191,25 +191,25 @@ public int run(HTTPTestServer server, // Now tries with explicitly setting the default authenticator: it should // be invoked again. // Uncomment the code below when 8169068 is available. -// System.out.println("\nClient: Explicitly setting the default authenticator: " -// + toString(Authenticator.getDefault())); -// HTTPTestClient.connect(protocol, server, mode, Authenticator.getDefault()); -// count = authOne.count.get(); -// if (count != expectedIncrement) { -// throw new AssertionError("Authenticator #1 called " + count(count) -// + " expected it to be called " + expected(expectedIncrement)); -// } -// count = authTwo.count.get(); -// if (count != expectedIncrement) { -// throw new AssertionError("Authenticator #2 called " + count(count) -// + " expected it to be called " + expected(expectedIncrement)); -// } -// count = AUTHENTICATOR.count.get(); -// if (count != defaultCount + 2 * expectedIncrement) { -// throw new AssertionError("Default Authenticator called " + count(count) -// + " expected it to be called " -// + expected(defaultCount + 2 * expectedIncrement)); -// } + System.out.println("\nClient: Explicitly setting the default authenticator: " + + toString(Authenticator.getDefault())); + HTTPTestClient.connect(protocol, server, mode, Authenticator.getDefault()); + count = authOne.count.get(); + if (count != expectedIncrement) { + throw new AssertionError("Authenticator #1 called " + count(count) + + " expected it to be called " + expected(expectedIncrement)); + } + count = authTwo.count.get(); + if (count != expectedIncrement) { + throw new AssertionError("Authenticator #2 called " + count(count) + + " expected it to be called " + expected(expectedIncrement)); + } + count = AUTHENTICATOR.count.get(); + if (count != defaultCount + 2 * expectedIncrement) { + throw new AssertionError("Default Authenticator called " + count(count) + + " expected it to be called " + + expected(defaultCount + 2 * expectedIncrement)); + } // Now tries to set an authenticator on a connected connection. URL url = url(protocol, server.getAddress(), "/"); @@ -238,16 +238,16 @@ public int run(HTTPTestServer server, + ise); } // Uncomment the code below when 8169068 is available. -// try { -// conn.setAuthenticator(Authenticator.getDefault()); -// throw new RuntimeException("Expected IllegalStateException" -// + " trying to set an authenticator after connect" -// + " not raised."); -// } catch (IllegalStateException ise) { -// System.out.println("Client: caught expected ISE" -// + " trying to set an authenticator after connect: " -// + ise); -// } + try { + conn.setAuthenticator(Authenticator.getDefault()); + throw new RuntimeException("Expected IllegalStateException" + + " trying to set an authenticator after connect" + + " not raised."); + } catch (IllegalStateException ise) { + System.out.println("Client: caught expected ISE" + + " trying to set an authenticator after connect: " + + ise); + } try { conn.setAuthenticator(null); throw new RuntimeException("Expected" @@ -279,7 +279,7 @@ public int run(HTTPTestServer server, // All good! // return the number of times the default authenticator is supposed // to have been called. - return scheme == HttpSchemeType.NONE ? 0 : 1 * EXPECTED_AUTH_CALLS_PER_TEST; + return scheme == HttpSchemeType.NONE ? 0 : 2 * EXPECTED_AUTH_CALLS_PER_TEST; } static String toString(Authenticator a) { diff --git a/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestClient.java b/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestClient.java index 4d1f5c52a78..3f436ef6d02 100644 --- a/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestClient.java +++ b/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestClient.java @@ -23,10 +23,12 @@ import java.io.IOException; import java.net.Authenticator; +import java.net.BindException; import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.URL; +import java.time.Duration; import javax.net.ssl.HttpsURLConnection; /** @@ -35,11 +37,39 @@ */ public class HTTPTestClient extends HTTPTest { + public static final long DELAY_BEFORE_RETRY = 2500; // milliseconds + public static void connect(HttpProtocolType protocol, HTTPTestServer server, HttpAuthType authType, Authenticator auth) throws IOException { + try { + doConnect(protocol, server, authType, auth); + } catch (BindException ex) { + // sleep a bit then try again once + System.out.println("WARNING: Unexpected BindException: " + ex); + System.out.println("\tSleeping a bit and try again..."); + long start = System.nanoTime(); + System.gc(); + try { + Thread.sleep(DELAY_BEFORE_RETRY); + } catch (InterruptedException iex) { + // ignore + } + System.gc(); + System.out.println("\tRetrying after " + + Duration.ofNanos(System.nanoTime() - start).toMillis() + + " milliseconds"); + doConnect(protocol, server, authType, auth); + } + } + + public static void doConnect(HttpProtocolType protocol, + HTTPTestServer server, + HttpAuthType authType, + Authenticator auth) + throws IOException { InetSocketAddress address = server.getAddress(); final URL url = url(protocol, address, "/"); diff --git a/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestServer.java b/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestServer.java index 91efe8d736b..53774681211 100644 --- a/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestServer.java +++ b/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -1004,13 +1004,14 @@ private synchronized Thread pipe(InputStream is, OutputStream os, char tag) { public void run() { try { try { - int c; - while ((c = is.read()) != -1) { - os.write(c); + int len; + byte[] buf = new byte[16 * 1024]; + while ((len = is.read(buf)) != -1) { + os.write(buf, 0, len); os.flush(); // if DEBUG prints a + or a - for each transferred // character. - if (DEBUG) System.out.print(tag); + if (DEBUG) System.out.print(String.valueOf(tag).repeat(len)); } is.close(); } finally { diff --git a/test/jdk/java/net/httpclient/ALPNProxyFailureTest.java b/test/jdk/java/net/httpclient/ALPNProxyFailureTest.java index 30489b6c453..ca2e95b70fe 100644 --- a/test/jdk/java/net/httpclient/ALPNProxyFailureTest.java +++ b/test/jdk/java/net/httpclient/ALPNProxyFailureTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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,17 +27,10 @@ * when a 'Connection reset by peer' exception is raised * during the handshake. * @bug 8217094 - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters DigestEchoServer + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext DigestEchoServer + * jdk.httpclient.test.lib.common.HttpServerAdapters * ALPNFailureTest ALPNProxyFailureTest - * @modules java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * java.base/sun.net.www.http - * java.base/sun.net.www - * java.base/sun.net - * @build ALPNFailureTest * @run main/othervm -Djdk.internal.httpclient.debug=true -Dtest.nolinger=true ALPNProxyFailureTest HTTP_1_1 * @run main/othervm -Dtest.nolinger=true ALPNProxyFailureTest HTTP_2 */ diff --git a/test/jdk/java/net/httpclient/AbstractNoBody.java b/test/jdk/java/net/httpclient/AbstractNoBody.java index 38ae9b758f6..479094e21ee 100644 --- a/test/jdk/java/net/httpclient/AbstractNoBody.java +++ b/test/jdk/java/net/httpclient/AbstractNoBody.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -35,6 +35,9 @@ import com.sun.net.httpserver.HttpsServer; import java.net.http.HttpClient; import javax.net.ssl.SSLContext; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; diff --git a/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java b/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java index 646a5cff2a5..f2a47734e40 100644 --- a/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java +++ b/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -72,9 +72,13 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.String.format; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -690,16 +694,13 @@ public void setup() throws Exception { // HTTP/1.1 HttpTestHandler h1_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h1_chunkHandler = new HTTP_ChunkedHandler(); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(h1_fixedLengthHandler, "/http1/fixed"); httpTestServer.addHandler(h1_chunkHandler, "/http1/chunk"); httpURI_fixed = "http://" + httpTestServer.serverAuthority() + "/http1/fixed/x"; httpURI_chunk = "http://" + httpTestServer.serverAuthority() + "/http1/chunk/x"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(h1_fixedLengthHandler, "/https1/fixed"); httpsTestServer.addHandler(h1_chunkHandler, "/https1/chunk"); httpsURI_fixed = "https://" + httpsTestServer.serverAuthority() + "/https1/fixed/x"; @@ -709,13 +710,13 @@ public void setup() throws Exception { HttpTestHandler h2_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h2_chunkedHandler = new HTTP_ChunkedHandler(); - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(h2_fixedLengthHandler, "/http2/fixed"); http2TestServer.addHandler(h2_chunkedHandler, "/http2/chunk"); http2URI_fixed = "http://" + http2TestServer.serverAuthority() + "/http2/fixed/x"; http2URI_chunk = "http://" + http2TestServer.serverAuthority() + "/http2/chunk/x"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(h2_fixedLengthHandler, "/https2/fixed"); https2TestServer.addHandler(h2_chunkedHandler, "/https2/chunk"); https2URI_fixed = "https://" + https2TestServer.serverAuthority() + "/https2/fixed/x"; diff --git a/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java b/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java index 1bdbf6dc22a..a9d1906430d 100644 --- a/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java +++ b/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -30,14 +30,11 @@ * Concrete tests that extend this abstract class will need to include * the following jtreg tags: * - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext * ReferenceTracker AbstractThrowingPushPromises + * jdk.httpclient.test.lib.common.HttpServerAdapters * - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack * @run testng/othervm -Djdk.internal.httpclient.debug=true */ @@ -90,10 +87,13 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.out; import static java.lang.System.err; import static java.lang.String.format; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -706,13 +706,13 @@ public void setup() throws Exception { HttpTestHandler h2_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h2_chunkedHandler = new HTTP_ChunkedHandler(); - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(h2_fixedLengthHandler, "/http2/fixed"); http2TestServer.addHandler(h2_chunkedHandler, "/http2/chunk"); http2URI_fixed = "http://" + http2TestServer.serverAuthority() + "/http2/fixed/x"; http2URI_chunk = "http://" + http2TestServer.serverAuthority() + "/http2/chunk/x"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(h2_fixedLengthHandler, "/https2/fixed"); https2TestServer.addHandler(h2_chunkedHandler, "/https2/chunk"); https2URI_fixed = "https://" + https2TestServer.serverAuthority() + "/https2/fixed/x"; diff --git a/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java b/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java index f6682b73f47..893950608b1 100644 --- a/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java +++ b/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -71,9 +71,13 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.out; import static java.lang.String.format; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -681,16 +685,13 @@ public void setup() throws Exception { // HTTP/1.1 HttpTestHandler h1_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h1_chunkHandler = new HTTP_ChunkedHandler(); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(h1_fixedLengthHandler, "/http1/fixed"); httpTestServer.addHandler(h1_chunkHandler, "/http1/chunk"); httpURI_fixed = "http://" + httpTestServer.serverAuthority() + "/http1/fixed/x"; httpURI_chunk = "http://" + httpTestServer.serverAuthority() + "/http1/chunk/x"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(h1_fixedLengthHandler, "/https1/fixed"); httpsTestServer.addHandler(h1_chunkHandler, "/https1/chunk"); httpsURI_fixed = "https://" + httpsTestServer.serverAuthority() + "/https1/fixed/x"; @@ -700,13 +701,13 @@ public void setup() throws Exception { HttpTestHandler h2_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h2_chunkedHandler = new HTTP_ChunkedHandler(); - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(h2_fixedLengthHandler, "/http2/fixed"); http2TestServer.addHandler(h2_chunkedHandler, "/http2/chunk"); http2URI_fixed = "http://" + http2TestServer.serverAuthority() + "/http2/fixed/x"; http2URI_chunk = "http://" + http2TestServer.serverAuthority() + "/http2/chunk/x"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(h2_fixedLengthHandler, "/https2/fixed"); https2TestServer.addHandler(h2_chunkedHandler, "/https2/chunk"); https2URI_fixed = "https://" + https2TestServer.serverAuthority() + "/https2/fixed/x"; diff --git a/test/jdk/java/net/httpclient/AggregateRequestBodyTest.java b/test/jdk/java/net/httpclient/AggregateRequestBodyTest.java index 05d27547a15..5f3b7ba8e89 100644 --- a/test/jdk/java/net/httpclient/AggregateRequestBodyTest.java +++ b/test/jdk/java/net/httpclient/AggregateRequestBodyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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,13 +24,9 @@ /* * @test * @bug 8252374 - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.common.HttpServerAdapters * ReferenceTracker AggregateRequestBodyTest - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack * @run testng/othervm -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=requests,responses,errors * AggregateRequestBodyTest @@ -70,6 +66,8 @@ import java.util.stream.Collectors; import java.util.stream.LongStream; import java.util.stream.Stream; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import javax.net.ssl.SSLContext; import com.sun.net.httpserver.HttpServer; @@ -88,6 +86,8 @@ import org.testng.annotations.Test; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; @@ -819,25 +819,20 @@ public void setup() throws Exception { throw new AssertionError("Unexpected null sslContext"); HttpTestHandler handler = new HttpTestEchoHandler(); - InetSocketAddress loopback = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - - HttpServer http1 = HttpServer.create(loopback, 0); - http1TestServer = HttpTestServer.of(http1); + http1TestServer = HttpTestServer.create(HTTP_1_1); http1TestServer.addHandler(handler, "/http1/echo/"); http1URI = "http://" + http1TestServer.serverAuthority() + "/http1/echo/x"; - HttpsServer https1 = HttpsServer.create(loopback, 0); - https1.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - https1TestServer = HttpTestServer.of(https1); + https1TestServer = HttpTestServer.create(HTTP_1_1, sslContext); https1TestServer.addHandler(handler, "/https1/echo/"); https1URI = "https://" + https1TestServer.serverAuthority() + "/https1/echo/x"; // HTTP/2 - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(handler, "/http2/echo/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/echo/x"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(handler, "/https2/echo/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/echo/x"; diff --git a/test/jdk/java/net/httpclient/AsFileDownloadTest.java b/test/jdk/java/net/httpclient/AsFileDownloadTest.java index 890f0701b94..78da28ca28b 100644 --- a/test/jdk/java/net/httpclient/AsFileDownloadTest.java +++ b/test/jdk/java/net/httpclient/AsFileDownloadTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -21,25 +21,6 @@ * questions. */ -/* - * @test - * @summary Basic test for ofFileDownload - * @bug 8196965 8302475 - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext - * @build jdk.test.lib.Platform - * @build jdk.test.lib.util.FileUtils - * @run testng/othervm AsFileDownloadTest - * @run testng/othervm/java.security.policy=AsFileDownloadTest.policy AsFileDownloadTest - */ - import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; @@ -69,6 +50,10 @@ import javax.net.ssl.SSLContext; import jdk.test.lib.net.SimpleSSLContext; import jdk.test.lib.util.FileUtils; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; @@ -81,6 +66,17 @@ import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; +/* + * @test + * @summary Basic test for ofFileDownload + * @bug 8196965 8302475 + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext + * jdk.test.lib.Platform jdk.test.lib.util.FileUtils + * @run testng/othervm AsFileDownloadTest + * @run testng/othervm/java.security.policy=AsFileDownloadTest.policy AsFileDownloadTest + */ + public class AsFileDownloadTest { SSLContext sslContext; @@ -267,8 +263,10 @@ void negativeTest(String uriString, String contentDispositionValue) // -- Infrastructure static String serverAuthority(HttpServer server) { - return InetAddress.getLoopbackAddress().getHostName() + ":" - + server.getAddress().getPort(); + final String hostIP = InetAddress.getLoopbackAddress().getHostAddress(); + // escape for ipv6 + final String h = hostIP.contains(":") ? "[" + hostIP + "]" : hostIP; + return h + ":" + server.getAddress().getPort(); } @BeforeTest diff --git a/test/jdk/java/net/httpclient/AsFileDownloadTest.policy b/test/jdk/java/net/httpclient/AsFileDownloadTest.policy index 0f38171503d..dec2b8bb0a4 100644 --- a/test/jdk/java/net/httpclient/AsFileDownloadTest.policy +++ b/test/jdk/java/net/httpclient/AsFileDownloadTest.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2018, 2023, 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,14 +27,15 @@ grant codeBase "file:${test.classes}/../../../../test/lib/-" { permission java.io.FilePermission "${test.src}/../../../../lib/jdk/test/lib/net/testkeys", "read"; }; -// for JTwork//classes/0/java/net/httpclient/http2/server/* -grant codeBase "file:${test.classes}/../../../../java/net/httpclient/http2/server/*" { +// for classes in JTwork//classes/0/test/jdk/java/net/httpclient/lib/ +grant codeBase "file:${test.classes}/../../../../test/jdk/java/net/httpclient/lib/-" { permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.common"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.frame"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack"; permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http"; - permission java.net.SocketPermission "localhost:*", "accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "accept,resolve"; permission java.lang.RuntimePermission "modifyThread"; }; @@ -42,10 +43,15 @@ grant codeBase "file:${test.classes}/*" { permission java.io.FilePermission "${user.dir}${/}asFileDownloadTest.tmp.dir", "read,write"; permission java.io.FilePermission "${user.dir}${/}asFileDownloadTest.tmp.dir/-", "read,write"; - permission java.net.URLPermission "http://localhost:*/http1/afdt", "POST"; - permission java.net.URLPermission "https://localhost:*/https1/afdt", "POST"; - permission java.net.URLPermission "http://localhost:*/http2/afdt", "POST"; - permission java.net.URLPermission "https://localhost:*/https2/afdt", "POST"; + permission java.net.URLPermission "http://127.0.0.1:*/http1/afdt", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https1/afdt", "POST"; + permission java.net.URLPermission "http://127.0.0.1:*/http2/afdt", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https2/afdt", "POST"; + // ipv6 + permission java.net.URLPermission "http://[::1]:*/http1/afdt", "POST"; + permission java.net.URLPermission "https://[::1]:*/https1/afdt", "POST"; + permission java.net.URLPermission "http://[::1]:*/http2/afdt", "POST"; + permission java.net.URLPermission "https://[::1]:*/https2/afdt", "POST"; // needed to grant permission to the HTTP/2 server @@ -58,7 +64,8 @@ grant codeBase "file:${test.classes}/*" { permission java.util.logging.LoggingPermission "control"; // needed to grant the HTTP servers - permission java.net.SocketPermission "localhost:*", "accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "accept,resolve"; permission java.util.PropertyPermission "*", "read"; permission java.lang.RuntimePermission "modifyThread"; diff --git a/test/jdk/java/net/httpclient/AuthFilterCacheTest.java b/test/jdk/java/net/httpclient/AuthFilterCacheTest.java index 09a97197210..ecdf132f464 100644 --- a/test/jdk/java/net/httpclient/AuthFilterCacheTest.java +++ b/test/jdk/java/net/httpclient/AuthFilterCacheTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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 @@ -31,6 +31,8 @@ import java.util.List; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicLong; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsConfigurator; @@ -42,19 +44,16 @@ import javax.net.ssl.SSLContext; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; + /** * @test * @bug 8232853 * @summary AuthenticationFilter.Cache::remove may throw ConcurrentModificationException - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters DigestEchoServer HttpRedirectTest - * @modules java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * java.base/sun.net.www.http - * java.base/sun.net.www - * java.base/sun.net + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext + * DigestEchoServer * @run testng/othervm -Dtest.requiresHost=true * -Djdk.httpclient.HttpClient.log=headers * -Djdk.internal.httpclient.debug=false @@ -91,7 +90,7 @@ public class AuthFilterCacheTest implements HttpServerAdapters { ProxySelector proxySelector; MyAuthenticator auth; HttpClient client; - Executor executor = Executors.newCachedThreadPool(); + ExecutorService executor = Executors.newCachedThreadPool(); @DataProvider(name = "uris") Object[][] testURIs() { @@ -123,9 +122,7 @@ public void setUp() throws Exception { auth = new MyAuthenticator(); // HTTP/1.1 - HttpServer server1 = HttpServer.create(sa, 0); - server1.setExecutor(executor); - http1Server = HttpTestServer.of(server1); + http1Server = HttpTestServer.create(HTTP_1_1, null, executor); http1Server.addHandler(new TestHandler(), "/AuthFilterCacheTest/http1/"); http1Server.start(); http1URI = new URI("http://" + http1Server.serverAuthority() @@ -142,16 +139,14 @@ public void setUp() throws Exception { + "/AuthFilterCacheTest/https1/"); // HTTP/2.0 - http2Server = HttpTestServer.of( - new Http2TestServer("localhost", false, 0)); + http2Server = HttpTestServer.create(HTTP_2); http2Server.addHandler(new TestHandler(), "/AuthFilterCacheTest/http2/"); http2Server.start(); http2URI = new URI("http://" + http2Server.serverAuthority() + "/AuthFilterCacheTest/http2/"); // HTTPS/2.0 - https2Server = HttpTestServer.of( - new Http2TestServer("localhost", true, 0)); + https2Server = HttpTestServer.create(HTTP_2, SSLContext.getDefault()); https2Server.addHandler(new TestHandler(), "/AuthFilterCacheTest/https2/"); https2Server.start(); https2URI = new URI("https://" + https2Server.serverAuthority() diff --git a/test/jdk/java/net/httpclient/BasicAuthTest.java b/test/jdk/java/net/httpclient/BasicAuthTest.java index f87235fe673..e0aec3b19b7 100644 --- a/test/jdk/java/net/httpclient/BasicAuthTest.java +++ b/test/jdk/java/net/httpclient/BasicAuthTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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,87 +24,102 @@ /** * @test * @bug 8087112 - * @modules java.net.http - * jdk.httpserver + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext * @run main/othervm BasicAuthTest * @summary Basic Authentication Test */ import com.sun.net.httpserver.BasicAuthenticator; -import com.sun.net.httpserver.HttpContext; -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpServer; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.test.lib.net.SimpleSSLContext; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.InetAddress; -import java.net.InetSocketAddress; import java.net.PasswordAuthentication; import java.net.URI; import java.net.http.HttpClient; +import java.net.http.HttpClient.Version; import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublishers; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import javax.net.ssl.SSLContext; + import static java.nio.charset.StandardCharsets.US_ASCII; -public class BasicAuthTest { +public class BasicAuthTest implements HttpServerAdapters { static volatile boolean ok; static final String RESPONSE = "Hello world"; static final String POST_BODY = "This is the POST body 123909090909090"; public static void main(String[] args) throws Exception { - InetSocketAddress addr = new InetSocketAddress(InetAddress.getLoopbackAddress(),0); - HttpServer server = HttpServer.create(addr, 10); + test(Version.HTTP_1_1, false); + test(Version.HTTP_2, false); + test(Version.HTTP_1_1, true); + test(Version.HTTP_2, true); + } + + public static void test(Version version, boolean secure) throws Exception { + ExecutorService e = Executors.newCachedThreadPool(); Handler h = new Handler(); - HttpContext serverContext = server.createContext("/test", h); - int port = server.getAddress().getPort(); - System.out.println("Server port = " + port); - - ClientAuth ca = new ClientAuth(); + SSLContext sslContext = secure ? new SimpleSSLContext().get() : null; + HttpTestServer server = HttpTestServer.create(version, sslContext, e); + HttpTestContext serverContext = server.addHandler(h,"/test/"); ServerAuth sa = new ServerAuth("foo realm"); serverContext.setAuthenticator(sa); - server.setExecutor(e); server.start(); - HttpClient client = HttpClient.newBuilder() - .authenticator(ca) - .build(); + System.out.println("Server auth = " + server.serverAuthority()); + + ClientAuth ca = new ClientAuth(); + var clientBuilder = HttpClient.newBuilder(); + if (sslContext != null) clientBuilder.sslContext(sslContext); + HttpClient client = clientBuilder.authenticator(ca).build(); try { - URI uri = new URI("http://localhost:" + Integer.toString(port) + "/test/foo"); - HttpRequest req = HttpRequest.newBuilder(uri).GET().build(); + String scheme = sslContext == null ? "http" : "https"; + URI uri = new URI(scheme + "://" + server.serverAuthority() + "/test/foo/"+version); + var builder = HttpRequest.newBuilder(uri); + HttpRequest req = builder.copy().GET().build(); + System.out.println("\n\nSending request: " + req); HttpResponse resp = client.send(req, BodyHandlers.ofString()); ok = resp.statusCode() == 200 && resp.body().equals(RESPONSE); - if (!ok || ca.count != 1) - throw new RuntimeException("Test failed"); + var count = ca.count; + if (!ok || count != 1) + throw new RuntimeException("Test failed: ca.count=" + count); // repeat same request, should succeed but no additional authenticator calls + System.out.println("\n\nRepeat request: " + req); resp = client.send(req, BodyHandlers.ofString()); ok = resp.statusCode() == 200 && resp.body().equals(RESPONSE); - if (!ok || ca.count != 1) - throw new RuntimeException("Test failed"); + count = ca.count; + if (!ok || count != 1) + throw new RuntimeException("Test failed: ca.count=" + count); // try a POST - req = HttpRequest.newBuilder(uri) - .POST(BodyPublishers.ofString(POST_BODY)) + req = builder.copy().POST(BodyPublishers.ofString(POST_BODY)) .build(); + System.out.println("\n\nSending POST request: " + req); resp = client.send(req, BodyHandlers.ofString()); ok = resp.statusCode() == 200; - if (!ok || ca.count != 1) - throw new RuntimeException("Test failed"); + count = ca.count; + if (!ok || count != 1) + throw new RuntimeException("Test failed: ca.count=" + count); + + } finally { - server.stop(0); + server.stop(); e.shutdownNow(); } System.out.println("OK"); @@ -136,20 +151,20 @@ protected PasswordAuthentication getPasswordAuthentication() { } } - static class Handler implements HttpHandler { + static class Handler implements HttpTestHandler { static volatile boolean ok; @Override - public void handle(HttpExchange he) throws IOException { + public void handle(HttpTestExchange he) throws IOException { String method = he.getRequestMethod(); InputStream is = he.getRequestBody(); if (method.equalsIgnoreCase("POST")) { String requestBody = new String(is.readAllBytes(), US_ASCII); if (!requestBody.equals(POST_BODY)) { - he.sendResponseHeaders(500, -1); + he.sendResponseHeaders(500, 0); ok = false; } else { - he.sendResponseHeaders(200, -1); + he.sendResponseHeaders(200, 0); ok = true; } } else { // GET diff --git a/test/jdk/java/net/httpclient/BasicRedirectTest.java b/test/jdk/java/net/httpclient/BasicRedirectTest.java index 8fb36b7454b..8ea1653b4d0 100644 --- a/test/jdk/java/net/httpclient/BasicRedirectTest.java +++ b/test/jdk/java/net/httpclient/BasicRedirectTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,15 +24,8 @@ /* * @test * @summary Basic test for redirect and redirect policies - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext * @run testng/othervm * -Djdk.httpclient.HttpClient.log=trace,headers,requests * BasicRedirectTest @@ -51,6 +44,8 @@ import java.net.http.HttpClient.Redirect; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import java.net.http.HttpResponse.BodyHandlers; import javax.net.ssl.SSLContext; import jdk.test.lib.net.SimpleSSLContext; @@ -59,6 +54,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; @@ -214,21 +211,17 @@ public void setup() throws Exception { if (sslContext == null) throw new AssertionError("Unexpected null sslContext"); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new BasicHttpRedirectHandler(), "/http1/same/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/same/redirect"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(new BasicHttpRedirectHandler(),"/https1/same/"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/same/redirect"; - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new BasicHttpRedirectHandler(), "/http2/same/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/same/redirect"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new BasicHttpRedirectHandler(), "/https2/same/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/same/redirect"; diff --git a/test/jdk/java/net/httpclient/BodyProcessorInputStreamTest.java b/test/jdk/java/net/httpclient/BodyProcessorInputStreamTest.java index a344b74cd6f..1f316c2a64d 100644 --- a/test/jdk/java/net/httpclient/BodyProcessorInputStreamTest.java +++ b/test/jdk/java/net/httpclient/BodyProcessorInputStreamTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -80,7 +80,7 @@ public static Optional getCharset(HttpHeaders headers) { public static void main(String[] args) throws Exception { HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest - .newBuilder(new URI("http://hg.openjdk.java.net/jdk9/sandbox/jdk/shortlog/http-client-branch/")) + .newBuilder(new URI("https://hg.openjdk.org/jdk9/sandbox/jdk/shortlog/http-client-branch/")) .GET() .build(); diff --git a/test/jdk/java/net/httpclient/CancelRequestTest.java b/test/jdk/java/net/httpclient/CancelRequestTest.java index de48316a25b..f8fb80aedca 100644 --- a/test/jdk/java/net/httpclient/CancelRequestTest.java +++ b/test/jdk/java/net/httpclient/CancelRequestTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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,14 +25,10 @@ * @test * @bug 8245462 8229822 * @summary Tests cancelling the request. - * @library /test/lib http2/server + * @library /test/lib /test/jdk/java/net/httpclient/lib * @key randomness - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext * ReferenceTracker CancelRequestTest - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack * @run testng/othervm -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.enableAllMethodRetry=true * CancelRequestTest @@ -83,9 +79,13 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.arraycopy; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -549,25 +549,22 @@ public void setup() throws Exception { // HTTP/1.1 HttpTestHandler h1_chunkHandler = new HTTPSlowHandler(); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(h1_chunkHandler, "/http1/x/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/x/"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(h1_chunkHandler, "/https1/x/"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/x/"; // HTTP/2 HttpTestHandler h2_chunkedHandler = new HTTPSlowHandler(); - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(h2_chunkedHandler, "/http2/x/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/x/"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(h2_chunkedHandler, "/https2/x/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/x/"; diff --git a/test/jdk/java/net/httpclient/ConcurrentResponses.java b/test/jdk/java/net/httpclient/ConcurrentResponses.java index 718a1b6aee6..ad1af440b1d 100644 --- a/test/jdk/java/net/httpclient/ConcurrentResponses.java +++ b/test/jdk/java/net/httpclient/ConcurrentResponses.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,15 +26,8 @@ * @bug 8195823 * @summary Buffers given to response body subscribers should not contain * unprocessed HTTP data - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext * @run testng/othervm * -Djdk.httpclient.HttpClient.log=headers,errors,channel * ConcurrentResponses @@ -67,6 +60,10 @@ import java.net.http.HttpResponse.BodyHandlers; import java.net.http.HttpResponse.BodySubscriber; import java.net.http.HttpResponse.BodySubscribers; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; diff --git a/test/jdk/java/net/httpclient/CookieHeaderTest.java b/test/jdk/java/net/httpclient/CookieHeaderTest.java index ae0957337de..d5eca06c0f0 100644 --- a/test/jdk/java/net/httpclient/CookieHeaderTest.java +++ b/test/jdk/java/net/httpclient/CookieHeaderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,15 +25,8 @@ * @test * @bug 8199851 * @summary Test for multiple vs single cookie header for HTTP/2 vs HTTP/1.1 - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext * @run testng/othervm * -Djdk.tls.acknowledgeCloseNotify=true * -Djdk.httpclient.HttpClient.log=trace,headers,requests @@ -82,8 +75,12 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -118,10 +115,10 @@ public static String now() { @DataProvider(name = "positive") public Object[][] positive() { return new Object[][] { - { httpURI, HttpClient.Version.HTTP_1_1 }, - { httpsURI, HttpClient.Version.HTTP_1_1 }, - { httpDummy, HttpClient.Version.HTTP_1_1 }, - { httpsDummy, HttpClient.Version.HTTP_1_1 }, + { httpURI, HTTP_1_1 }, + { httpsURI, HTTP_1_1 }, + { httpDummy, HTTP_1_1 }, + { httpsDummy, HTTP_1_1 }, { httpURI, HttpClient.Version.HTTP_2 }, { httpsURI, HttpClient.Version.HTTP_2 }, { httpDummy, HttpClient.Version.HTTP_2 }, @@ -192,26 +189,23 @@ public void setup() throws Exception { if (sslContext == null) throw new AssertionError("Unexpected null sslContext"); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new CookieValidationHandler(), "/http1/cookie/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/cookie/retry"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(new CookieValidationHandler(),"/https1/cookie/"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/cookie/retry"; - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new CookieValidationHandler(), "/http2/cookie/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/cookie/retry"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new CookieValidationHandler(), "/https2/cookie/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/cookie/retry"; // DummyServer + InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); httpDummyServer = DummyServer.create(sa); httpsDummyServer = DummyServer.create(sa, sslContext); httpDummy = "http://" + httpDummyServer.serverAuthority() + "/http1/dummy/x"; @@ -279,7 +273,7 @@ public void handle(HttpTestExchange t) throws IOException { String uuid = uuids.get(0); // retrying if (closedRequests.putIfAbsent(uuid, t.getRequestURI().toString()) == null) { - if (t.getExchangeVersion() == HttpClient.Version.HTTP_1_1) { + if (t.getExchangeVersion() == HTTP_1_1) { // Throwing an exception here only causes a retry // with HTTP_1_1 - where it forces the server to close // the connection. @@ -307,7 +301,7 @@ public void handle(HttpTestExchange t) throws IOException { try (OutputStream os = t.getResponseBody()) { List cookie = t.getRequestHeaders().get("Cookie"); if (cookie != null) { - if (version == HttpClient.Version.HTTP_1_1 || upgraded) { + if (version == HTTP_1_1 || upgraded) { if (cookie.size() == 1) { cookie = List.of(cookie.get(0).split("; ")); } else if (cookie.size() > 1) { diff --git a/test/jdk/java/net/httpclient/CustomRequestPublisher.java b/test/jdk/java/net/httpclient/CustomRequestPublisher.java index 34c7f8611ac..03bf9643aca 100644 --- a/test/jdk/java/net/httpclient/CustomRequestPublisher.java +++ b/test/jdk/java/net/httpclient/CustomRequestPublisher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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,15 +24,8 @@ /* * @test * @summary Checks correct handling of Publishers that call onComplete without demand - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext * @run testng/othervm CustomRequestPublisher */ @@ -62,6 +55,9 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; diff --git a/test/jdk/java/net/httpclient/CustomResponseSubscriber.java b/test/jdk/java/net/httpclient/CustomResponseSubscriber.java index ff7460ec4d5..e0bee8cc74f 100644 --- a/test/jdk/java/net/httpclient/CustomResponseSubscriber.java +++ b/test/jdk/java/net/httpclient/CustomResponseSubscriber.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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,12 +24,8 @@ /* * @test * @summary Tests response body subscribers's onComplete is not invoked before onSubscribe - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer * @run testng/othervm CustomResponseSubscriber */ @@ -56,6 +52,9 @@ import java.net.http.HttpResponse.BodyHandler; import java.net.http.HttpResponse.BodySubscriber; import java.net.http.HttpResponse.BodySubscribers; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import javax.net.ssl.SSLContext; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; diff --git a/test/jdk/java/net/httpclient/DependentActionsTest.java b/test/jdk/java/net/httpclient/DependentActionsTest.java index ea715a1832b..61d6c5157a6 100644 --- a/test/jdk/java/net/httpclient/DependentActionsTest.java +++ b/test/jdk/java/net/httpclient/DependentActionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,12 +26,9 @@ * @summary Verify that dependent synchronous actions added before the CF * completes are executed either asynchronously in an executor when the * CF later completes, or in the user thread that joins. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters DependentActionsTest - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext + * DependentActionsTest * @run testng/othervm -Djdk.internal.httpclient.debug=true DependentActionsTest * @run testng/othervm/java.security.policy=dependent.policy * -Djdk.internal.httpclient.debug=true DependentActionsTest @@ -86,9 +83,13 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.out; import static java.lang.String.format; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.util.stream.Collectors.toList; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -581,16 +582,13 @@ public void setup() throws Exception { // HTTP/1.1 HttpTestHandler h1_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h1_chunkHandler = new HTTP_ChunkedHandler(); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(h1_fixedLengthHandler, "/http1/fixed"); httpTestServer.addHandler(h1_chunkHandler, "/http1/chunk"); httpURI_fixed = "http://" + httpTestServer.serverAuthority() + "/http1/fixed/x"; httpURI_chunk = "http://" + httpTestServer.serverAuthority() + "/http1/chunk/x"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(h1_fixedLengthHandler, "/https1/fixed"); httpsTestServer.addHandler(h1_chunkHandler, "/https1/chunk"); httpsURI_fixed = "https://" + httpsTestServer.serverAuthority() + "/https1/fixed/x"; @@ -600,13 +598,13 @@ public void setup() throws Exception { HttpTestHandler h2_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h2_chunkedHandler = new HTTP_ChunkedHandler(); - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(h2_fixedLengthHandler, "/http2/fixed"); http2TestServer.addHandler(h2_chunkedHandler, "/http2/chunk"); http2URI_fixed = "http://" + http2TestServer.serverAuthority() + "/http2/fixed/x"; http2URI_chunk = "http://" + http2TestServer.serverAuthority() + "/http2/chunk/x"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(h2_fixedLengthHandler, "/https2/fixed"); https2TestServer.addHandler(h2_chunkedHandler, "/https2/chunk"); https2URI_fixed = "https://" + https2TestServer.serverAuthority() + "/https2/fixed/x"; diff --git a/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java b/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java index 94e7d39e5c8..4e17408ee6f 100644 --- a/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java +++ b/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,12 +26,9 @@ * @summary Verify that dependent synchronous actions added before the promise CF * completes are executed either asynchronously in an executor when the * CF later completes, or in the user thread that joins. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters DependentPromiseActionsTest - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext + * DependentPromiseActionsTest * @run testng/othervm -Djdk.internal.httpclient.debug=true DependentPromiseActionsTest * @run testng/othervm/java.security.policy=dependent.policy * -Djdk.internal.httpclient.debug=true DependentPromiseActionsTest @@ -84,10 +81,13 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.err; import static java.lang.System.out; import static java.lang.String.format; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -666,13 +666,13 @@ public void setup() throws Exception { HttpTestHandler h2_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h2_chunkedHandler = new HTTP_ChunkedHandler(); - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(h2_fixedLengthHandler, "/http2/fixed"); http2TestServer.addHandler(h2_chunkedHandler, "/http2/chunk"); http2URI_fixed = "http://" + http2TestServer.serverAuthority() + "/http2/fixed/y"; http2URI_chunk = "http://" + http2TestServer.serverAuthority() + "/http2/chunk/y"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(h2_fixedLengthHandler, "/https2/fixed"); https2TestServer.addHandler(h2_chunkedHandler, "/https2/chunk"); https2URI_fixed = "https://" + https2TestServer.serverAuthority() + "/https2/fixed/y"; diff --git a/test/jdk/java/net/httpclient/DigestEchoClient.java b/test/jdk/java/net/httpclient/DigestEchoClient.java index a3321dc3b3c..f7bac2038d1 100644 --- a/test/jdk/java/net/httpclient/DigestEchoClient.java +++ b/test/jdk/java/net/httpclient/DigestEchoClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -51,6 +51,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import javax.net.ssl.SSLContext; +import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.test.lib.net.SimpleSSLContext; import sun.net.NetProperties; import sun.net.www.HeaderParser; @@ -62,16 +63,9 @@ * @summary this test verifies that a client may provides authorization * headers directly when connecting with a server. * @bug 8087112 - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters DigestEchoServer - * ReferenceTracker DigestEchoClient - * @modules java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * java.base/sun.net.www.http - * java.base/sun.net.www - * java.base/sun.net + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext + * DigestEchoServer ReferenceTracker DigestEchoClient * @run main/othervm DigestEchoClient * @run main/othervm -Djdk.http.auth.proxying.disabledSchemes= * -Djdk.http.auth.tunneling.disabledSchemes= diff --git a/test/jdk/java/net/httpclient/DigestEchoClientSSL.java b/test/jdk/java/net/httpclient/DigestEchoClientSSL.java index 4803492c1ce..9a7f5acb88a 100644 --- a/test/jdk/java/net/httpclient/DigestEchoClientSSL.java +++ b/test/jdk/java/net/httpclient/DigestEchoClientSSL.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,16 +26,10 @@ * @bug 8087112 * @summary this test verifies that a client may provides authorization * headers directly when connecting with a server over SSL. - * @library /test/lib http2/server + * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext DigestEchoServer * DigestEchoClient ReferenceTracker DigestEchoClientSSL - * @modules java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * java.base/sun.net.www.http - * java.base/sun.net.www - * java.base/sun.net + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run main/othervm/timeout=300 * DigestEchoClientSSL SSL * @run main/othervm/timeout=300 diff --git a/test/jdk/java/net/httpclient/DigestEchoServer.java b/test/jdk/java/net/httpclient/DigestEchoServer.java index 92b96bea51c..a7c300e62cf 100644 --- a/test/jdk/java/net/httpclient/DigestEchoServer.java +++ b/test/jdk/java/net/httpclient/DigestEchoServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -67,8 +67,12 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import javax.net.ssl.SSLContext; + +import jdk.httpclient.test.lib.common.HttpServerAdapters.AbstractHttpAuthFilter.HttpAuthMode; import sun.net.www.HeaderParser; import java.net.http.HttpClient.Version; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; /** * A simple HTTP server that supports Basic or Digest authentication. @@ -86,8 +90,14 @@ public abstract class DigestEchoServer implements HttpServerAdapters { public static final boolean TUNNEL_REQUIRES_HOST = Boolean.parseBoolean(System.getProperty("test.requiresHost", "false")); public enum HttpAuthType { - SERVER, PROXY, SERVER307, PROXY305 + SERVER, PROXY, SERVER307, PROXY305; /* add PROXY_AND_SERVER and SERVER_PROXY_NONE */ + public HttpAuthMode authMode() { + return switch (this) { + case SERVER, SERVER307 -> HttpAuthMode.SERVER; + case PROXY, PROXY305 -> HttpAuthMode.PROXY; + }; + } }; public enum HttpAuthSchemeType { NONE, BASICSERVER, BASIC, DIGEST }; public static final HttpAuthType DEFAULT_HTTP_AUTH_TYPE = HttpAuthType.SERVER; @@ -478,19 +488,21 @@ static HttpsServer configure(HttpsServer server) throws IOException { return server; } + static BasicAuthenticator toBasicAuthenticator(HttpTestAuthenticator auth) { + final String realm = auth.getRealm(); + return new BasicAuthenticator(realm) { + @Override + public boolean checkCredentials(String username, String pwd) { + return auth.getUserName().equals(username) + && new String(auth.getPassword(username)).equals(pwd); + } + }; + } static void setContextAuthenticator(HttpTestContext ctxt, HttpTestAuthenticator auth) { - final String realm = auth.getRealm(); - com.sun.net.httpserver.Authenticator authenticator = - new BasicAuthenticator(realm) { - @Override - public boolean checkCredentials(String username, String pwd) { - return auth.getUserName().equals(username) - && new String(auth.getPassword(username)).equals(pwd); - } - }; - ctxt.setAuthenticator(authenticator); + + ctxt.setAuthenticator(toBasicAuthenticator(auth)); } public static DigestEchoServer createServer(Version version, @@ -657,7 +669,7 @@ void configureAuthentication(HttpTestContext ctxt, HttpAuthType authType) { switch(schemeType) { case DIGEST: - // DIGEST authentication is handled by the handler. + // DIGEST authentication is handled by the filter. ctxt.addFilter(new HttpDigestFilter(key, auth, authType)); break; case BASIC: @@ -703,85 +715,6 @@ private HttpTestHandler create300Handler(String key, URL proxyURL, return new Http3xxHandler(key, proxyURL, type, code300); } - // Abstract HTTP filter class. - private abstract static class AbstractHttpFilter extends HttpTestFilter { - - final HttpAuthType authType; - final String type; - public AbstractHttpFilter(HttpAuthType authType, String type) { - this.authType = authType; - this.type = type; - } - - String getLocation() { - return "Location"; - } - String getAuthenticate() { - return authType == HttpAuthType.PROXY - ? "Proxy-Authenticate" : "WWW-Authenticate"; - } - String getAuthorization() { - return authType == HttpAuthType.PROXY - ? "Proxy-Authorization" : "Authorization"; - } - int getUnauthorizedCode() { - return authType == HttpAuthType.PROXY - ? HttpURLConnection.HTTP_PROXY_AUTH - : HttpURLConnection.HTTP_UNAUTHORIZED; - } - String getKeepAlive() { - return "keep-alive"; - } - String getConnection() { - return authType == HttpAuthType.PROXY - ? "Proxy-Connection" : "Connection"; - } - protected abstract boolean isAuthentified(HttpTestExchange he) throws IOException; - protected abstract void requestAuthentication(HttpTestExchange he) throws IOException; - protected void accept(HttpTestExchange he, HttpChain chain) throws IOException { - chain.doFilter(he); - } - - @Override - public String description() { - return "Filter for " + type; - } - @Override - public void doFilter(HttpTestExchange he, HttpChain chain) throws IOException { - try { - System.out.println(type + ": Got " + he.getRequestMethod() - + ": " + he.getRequestURI() - + "\n" + DigestEchoServer.toString(he.getRequestHeaders())); - - // Assert only a single value for Expect. Not directly related - // to digest authentication, but verifies good client behaviour. - List expectValues = he.getRequestHeaders().get("Expect"); - if (expectValues != null && expectValues.size() > 1) { - throw new IOException("Expect: " + expectValues); - } - - if (!isAuthentified(he)) { - try { - requestAuthentication(he); - he.sendResponseHeaders(getUnauthorizedCode(), -1); - System.out.println(type - + ": Sent back " + getUnauthorizedCode()); - } finally { - he.close(); - } - } else { - accept(he, chain); - } - } catch (RuntimeException | Error | IOException t) { - System.err.println(type - + ": Unexpected exception while handling request: " + t); - t.printStackTrace(System.err); - he.close(); - throw t; - } - } - - } // WARNING: This is not a full fledged implementation of DIGEST. // It does contain bugs and inaccuracy. @@ -916,16 +849,16 @@ public static DigestResponse create(String raw) { } - private static class HttpNoAuthFilter extends AbstractHttpFilter { + private static class HttpNoAuthFilter extends AbstractHttpAuthFilter { static String type(String key, HttpAuthType authType) { - String type = authType == HttpAuthType.SERVER + String type = authType.authMode() == HttpAuthMode.SERVER ? "NoAuth Server Filter" : "NoAuth Proxy Filter"; return "["+type+"]:"+key; } public HttpNoAuthFilter(String key, HttpAuthType authType) { - super(authType, type(key, authType)); + super(authType.authMode(), type(key, authType)); } @Override @@ -946,73 +879,22 @@ public String description() { } // An HTTP Filter that performs Basic authentication - private static class HttpBasicFilter extends AbstractHttpFilter { + private static class HttpBasicFilter extends HttpBasicAuthFilter { static String type(String key, HttpAuthType authType) { - String type = authType == HttpAuthType.SERVER + String type = authType.authMode() == HttpAuthMode.SERVER ? "Basic Server Filter" : "Basic Proxy Filter"; return "["+type+"]:"+key; } - private final HttpTestAuthenticator auth; public HttpBasicFilter(String key, HttpTestAuthenticator auth, HttpAuthType authType) { - super(authType, type(key, authType)); - this.auth = auth; - } - - @Override - protected void requestAuthentication(HttpTestExchange he) - throws IOException - { - String headerName = getAuthenticate(); - String headerValue = "Basic realm=\"" + auth.getRealm() + "\""; - he.getResponseHeaders().addHeader(headerName, headerValue); - System.out.println(type + ": Requesting Basic Authentication, " - + headerName + " : "+ headerValue); - } - - @Override - protected boolean isAuthentified(HttpTestExchange he) { - if (he.getRequestHeaders().containsKey(getAuthorization())) { - List authorization = - he.getRequestHeaders().get(getAuthorization()); - for (String a : authorization) { - System.out.println(type + ": processing " + a); - int sp = a.indexOf(' '); - if (sp < 0) return false; - String scheme = a.substring(0, sp); - if (!"Basic".equalsIgnoreCase(scheme)) { - System.out.println(type + ": Unsupported scheme '" - + scheme +"'"); - return false; - } - if (a.length() <= sp+1) { - System.out.println(type + ": value too short for '" - + scheme +"'"); - return false; - } - a = a.substring(sp+1); - return validate(a); - } - return false; - } - return false; - } - - boolean validate(String a) { - byte[] b = Base64.getDecoder().decode(a); - String userpass = new String (b); - int colon = userpass.indexOf (':'); - String uname = userpass.substring (0, colon); - String pass = userpass.substring (colon+1); - return auth.getUserName().equals(uname) && - new String(auth.getPassword(uname)).equals(pass); + super(toBasicAuthenticator(auth), authType.authMode(), type(key, authType)); } @Override public String description() { - return "Filter for BASIC authentication: " + type; + return "Filter for BASIC authentication: " + type(); } } @@ -1021,10 +903,10 @@ public String description() { // An HTTP Filter that performs Digest authentication // WARNING: This is not a full fledged implementation of DIGEST. // It does contain bugs and inaccuracy. - private static class HttpDigestFilter extends AbstractHttpFilter { + private static class HttpDigestFilter extends AbstractHttpAuthFilter { static String type(String key, HttpAuthType authType) { - String type = authType == HttpAuthType.SERVER + String type = authType.authMode() == HttpAuthMode.SERVER ? "Digest Server Filter" : "Digest Proxy Filter"; return "["+type+"]:"+key; } @@ -1036,12 +918,14 @@ static String type(String key, HttpAuthType authType) { private final HttpTestAuthenticator auth; private final byte[] nonce; private final String ns; + private final String type; public HttpDigestFilter(String key, HttpTestAuthenticator auth, HttpAuthType authType) { - super(authType, type(key, authType)); + super(authType.authMode(), type(key, authType)); this.auth = auth; nonce = new byte[16]; new Random(Instant.now().toEpochMilli()).nextBytes(nonce); ns = new BigInteger(1, nonce).toString(16); + this.type = type(); } @Override @@ -1558,18 +1442,19 @@ private synchronized Thread pipe(InputStream is, OutputStream os, char tag, Comp @Override public void run() { try { - int c = 0; + int len = 0; + byte[] buf = new byte[16 * 1024]; try { - while ((c = is.read()) != -1) { - os.write(c); + while ((len = is.read(buf)) != -1) { + os.write(buf, 0, len); os.flush(); // if DEBUG prints a + or a - for each transferred // character. - if (DEBUG) System.out.print(tag); + if (DEBUG) System.out.print(String.valueOf(tag).repeat(len)); } is.close(); } catch (IOException ex) { - if (DEBUG || !stopped && c > -1) + if (DEBUG || !stopped && len > -1) ex.printStackTrace(System.out); end.completeExceptionally(ex); } finally { diff --git a/test/jdk/java/net/httpclient/EncodedCharsInURI.java b/test/jdk/java/net/httpclient/EncodedCharsInURI.java index 6d7a42e8532..c25fe1b6560 100644 --- a/test/jdk/java/net/httpclient/EncodedCharsInURI.java +++ b/test/jdk/java/net/httpclient/EncodedCharsInURI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,12 +26,9 @@ * @bug 8199683 * @summary Tests that escaped characters in URI are correctly * handled (not re-escaped and not unescaped) - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters EncodedCharsInURI - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext + * EncodedCharsInURI * @run testng/othervm * -Djdk.tls.acknowledgeCloseNotify=true * -Djdk.internal.httpclient.debug=true @@ -76,10 +73,14 @@ import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicLong; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.String.format; import static java.lang.System.in; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.US_ASCII; import static java.nio.charset.StandardCharsets.UTF_8; import static java.net.http.HttpClient.Builder.NO_PROXY; @@ -261,16 +262,13 @@ public void setup() throws Exception { // HTTP/1.1 HttpTestHandler h1_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h1_chunkHandler = new HTTP_ChunkedHandler(); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(h1_fixedLengthHandler, "/http1/fixed"); httpTestServer.addHandler(h1_chunkHandler, "/http1/chunk"); httpURI_fixed = "http://" + httpTestServer.serverAuthority() + "/http1/fixed/x"; httpURI_chunk = "http://" + httpTestServer.serverAuthority() + "/http1/chunk/x"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(h1_fixedLengthHandler, "/https1/fixed"); httpsTestServer.addHandler(h1_chunkHandler, "/https1/chunk"); httpsURI_fixed = "https://" + httpsTestServer.serverAuthority() + "/https1/fixed/x"; @@ -280,19 +278,20 @@ public void setup() throws Exception { HttpTestHandler h2_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h2_chunkedHandler = new HTTP_ChunkedHandler(); - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(h2_fixedLengthHandler, "/http2/fixed"); http2TestServer.addHandler(h2_chunkedHandler, "/http2/chunk"); http2URI_fixed = "http://" + http2TestServer.serverAuthority() + "/http2/fixed/x"; http2URI_chunk = "http://" + http2TestServer.serverAuthority() + "/http2/chunk/x"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(h2_fixedLengthHandler, "/https2/fixed"); https2TestServer.addHandler(h2_chunkedHandler, "/https2/chunk"); https2URI_fixed = "https://" + https2TestServer.serverAuthority() + "/https2/fixed/x"; https2URI_chunk = "https://" + https2TestServer.serverAuthority() + "/https2/chunk/x"; // DummyServer + InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); httpDummyServer = DummyServer.create(sa); httpsDummyServer = DummyServer.create(sa, sslContext); httpDummy = "http://" + httpDummyServer.serverAuthority() + "/http1/dummy/x"; diff --git a/test/jdk/java/net/httpclient/EscapedOctetsInURI.java b/test/jdk/java/net/httpclient/EscapedOctetsInURI.java index 9e44f6aac97..00061c1edf0 100644 --- a/test/jdk/java/net/httpclient/EscapedOctetsInURI.java +++ b/test/jdk/java/net/httpclient/EscapedOctetsInURI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,15 +25,8 @@ * @test * @summary Preserve URI component escaped octets when converting to HTTP headers * @bug 8198716 - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext * @run testng/othervm * -Djdk.httpclient.HttpClient.log=reqeusts,headers * EscapedOctetsInURI @@ -58,6 +51,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; diff --git a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest.java b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest.java index 62623c537de..e75a87c8524 100644 --- a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest.java +++ b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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 @@ -29,14 +29,9 @@ * policy 1: no custom permission * policy 2: custom permission for test classes * policy 3: custom permission for test classes and httpclient - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * jdk.httpserver - * @library /test/lib ../http2/server - * @compile ../HttpServerAdapters.java - * @build jdk.test.lib.net.SimpleSSLContext SecureZipFSProvider + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext + * SecureZipFSProvider * @run testng/othervm/java.security.policy=FilePublisherPermsTest1.policy FilePublisherPermsTest * @run testng/othervm/java.security.policy=FilePublisherPermsTest2.policy FilePublisherPermsTest * @run testng/othervm/java.security.policy=FilePublisherPermsTest3.policy FilePublisherPermsTest @@ -71,9 +66,13 @@ import java.nio.file.Path; import java.security.*; import java.util.Map; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.out; import static java.net.http.HttpClient.Builder.NO_PROXY; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static org.testng.Assert.assertEquals; import static org.testng.Assert.fail; @@ -313,29 +312,22 @@ public void setup() throws Exception { zipFsPath = zipFsFile(zipFs); defaultFsPath = defaultFsFile(); - InetSocketAddress sa = - new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - - httpTestServer = HttpServerAdapters.HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpServerAdapters.HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler( new FilePublisherPermsTest.HttpEchoHandler(), "/http1/echo"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/echo"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpServerAdapters.HttpTestServer.of(httpsServer); + httpsTestServer = HttpServerAdapters.HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler( new FilePublisherPermsTest.HttpEchoHandler(), "/https1/echo"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/echo"; - http2TestServer = HttpServerAdapters.HttpTestServer.of( - new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpServerAdapters.HttpTestServer.create(HTTP_2); http2TestServer.addHandler( new FilePublisherPermsTest.HttpEchoHandler(), "/http2/echo"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/echo"; - https2TestServer = HttpServerAdapters.HttpTestServer.of( - new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpServerAdapters.HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler( new FilePublisherPermsTest.HttpEchoHandler(), "/https2/echo"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/echo"; diff --git a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest1.policy b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest1.policy index a133d4e9247..bbc3e359639 100644 --- a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest1.policy +++ b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest1.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2020, 2023, 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,26 +27,36 @@ grant codeBase "file:${test.classes}/../../../../../test/lib/-" { permission java.io.FilePermission "${test.src}/../../../../../lib/jdk/test/lib/net/testkeys", "read"; }; -// for JTwork/classes/0/java/net/httpclient/http2/server/* -grant codeBase "file:${test.classes}/../../../../../java/net/httpclient/http2/server/*" { +// for jdk/httpclient/test/lib/* classes +grant codeBase "file:${test.classes}/../../../../../test/jdk/java/net/httpclient/lib/-" { permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.common"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.frame"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack"; permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http"; - permission java.net.SocketPermission "localhost:*", "accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "accept,resolve"; permission java.lang.RuntimePermission "modifyThread"; }; grant codeBase "file:${test.classes}/*" { - permission java.net.URLPermission "http://localhost:*/http1/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/https1/echo", "POST"; - permission java.net.URLPermission "http://localhost:*/http2/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/https2/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/http1/echo", "GET"; - permission java.net.URLPermission "https://localhost:*/https1/echo", "GET"; - permission java.net.URLPermission "http://localhost:*/http2/echo", "GET"; - permission java.net.URLPermission "https://localhost:*/https2/echo", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/http1/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "POST"; + permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/http1/echo", "GET"; + permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "GET"; + permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "GET"; + // ipv6 + permission java.net.URLPermission "http://[::1]:*/http1/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/https1/echo", "POST"; + permission java.net.URLPermission "http://[::1]:*/http2/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/https2/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/http1/echo", "GET"; + permission java.net.URLPermission "https://[::1]:*/https1/echo", "GET"; + permission java.net.URLPermission "http://[::1]:*/http2/echo", "GET"; + permission java.net.URLPermission "https://[::1]:*/https2/echo", "GET"; // file permissions permission java.io.FilePermission "${user.dir}${/}defaultFile.txt", "read,write,delete"; @@ -69,7 +79,8 @@ grant codeBase "file:${test.classes}/*" { permission java.util.logging.LoggingPermission "control"; // needed to grant the HTTP servers - permission java.net.SocketPermission "localhost:*", "accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "accept,resolve"; permission java.util.PropertyPermission "*", "read"; permission java.lang.RuntimePermission "modifyThread"; diff --git a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest2.policy b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest2.policy index fdde92b4ea5..0ff462568ba 100644 --- a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest2.policy +++ b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest2.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2020, 2023, 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 @@ -29,26 +29,36 @@ grant codeBase "file:${test.classes}/../../../../../test/lib/-" { permission java.io.FilePermission "${test.src}/../../../../../lib/jdk/test/lib/net/testkeys", "read"; }; -// for JTwork/classes/0/java/net/httpclient/http2/server/* -grant codeBase "file:${test.classes}/../../../../../java/net/httpclient/http2/server/*" { +// for jdk/httpclient/test/lib/* classes +grant codeBase "file:${test.classes}/../../../../../test/jdk/java/net/httpclient/lib/-" { permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.common"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.frame"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack"; permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http"; - permission java.net.SocketPermission "localhost:*", "accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "accept,resolve"; permission java.lang.RuntimePermission "modifyThread"; }; grant codeBase "file:${test.classes}/*" { - permission java.net.URLPermission "http://localhost:*/http1/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/https1/echo", "POST"; - permission java.net.URLPermission "http://localhost:*/http2/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/https2/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/http1/echo", "GET"; - permission java.net.URLPermission "https://localhost:*/https1/echo", "GET"; - permission java.net.URLPermission "http://localhost:*/http2/echo", "GET"; - permission java.net.URLPermission "https://localhost:*/https2/echo", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/http1/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "POST"; + permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/http1/echo", "GET"; + permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "GET"; + permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "GET"; + // ipv6 + permission java.net.URLPermission "http://[::1]:*/http1/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/https1/echo", "POST"; + permission java.net.URLPermission "http://[::1]:*/http2/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/https2/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/http1/echo", "GET"; + permission java.net.URLPermission "https://[::1]:*/https1/echo", "GET"; + permission java.net.URLPermission "http://[::1]:*/http2/echo", "GET"; + permission java.net.URLPermission "https://[::1]:*/https2/echo", "GET"; // file permissions permission java.io.FilePermission "${user.dir}${/}defaultFile.txt", "read,write,delete"; @@ -74,7 +84,8 @@ grant codeBase "file:${test.classes}/*" { permission java.util.logging.LoggingPermission "control"; // needed to grant the HTTP servers - permission java.net.SocketPermission "localhost:*", "accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "accept,resolve"; permission java.util.PropertyPermission "*", "read"; permission java.lang.RuntimePermission "modifyThread"; diff --git a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest3.policy b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest3.policy index 4f7c4fee363..e55aec16ecd 100644 --- a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest3.policy +++ b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest3.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2020, 2023, 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 @@ -34,26 +34,36 @@ grant codeBase "file:${test.classes}/../../../../../test/lib/-" { permission java.io.FilePermission "${test.src}/../../../../../lib/jdk/test/lib/net/testkeys", "read"; }; -// for JTwork/classes/0/java/net/httpclient/http2/server/* -grant codeBase "file:${test.classes}/../../../../../java/net/httpclient/http2/server/*" { +// for jdk/httpclient/test/lib/* classes +grant codeBase "file:${test.classes}/../../../../../test/jdk/java/net/httpclient/lib/-" { permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.common"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.frame"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack"; permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http"; - permission java.net.SocketPermission "localhost:*", "accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "accept,resolve"; permission java.lang.RuntimePermission "modifyThread"; }; grant codeBase "file:${test.classes}/*" { - permission java.net.URLPermission "http://localhost:*/http1/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/https1/echo", "POST"; - permission java.net.URLPermission "http://localhost:*/http2/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/https2/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/http1/echo", "GET"; - permission java.net.URLPermission "https://localhost:*/https1/echo", "GET"; - permission java.net.URLPermission "http://localhost:*/http2/echo", "GET"; - permission java.net.URLPermission "https://localhost:*/https2/echo", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/http1/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "POST"; + permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/http1/echo", "GET"; + permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "GET"; + permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "GET"; + // ipv6 + permission java.net.URLPermission "http://[::1]:*/http1/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/https1/echo", "POST"; + permission java.net.URLPermission "http://[::1]:*/http2/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/https2/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/http1/echo", "GET"; + permission java.net.URLPermission "https://[::1]:*/https1/echo", "GET"; + permission java.net.URLPermission "http://[::1]:*/http2/echo", "GET"; + permission java.net.URLPermission "https://[::1]:*/https2/echo", "GET"; // file permissions permission java.io.FilePermission "${user.dir}${/}defaultFile.txt", "read,write,delete"; @@ -77,7 +87,8 @@ grant codeBase "file:${test.classes}/*" { permission java.util.logging.LoggingPermission "control"; // needed to grant the HTTP servers - permission java.net.SocketPermission "localhost:*", "accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "accept,resolve"; permission java.util.PropertyPermission "*", "read"; permission java.lang.RuntimePermission "modifyThread"; diff --git a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherTest.java b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherTest.java index 9626502ae4d..1e07bca3a8f 100644 --- a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherTest.java +++ b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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,14 +26,9 @@ * @bug 8235459 * @summary Confirm that HttpRequest.BodyPublishers#ofFile(Path) * assumes the default file system - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * jdk.httpserver - * @library /test/lib ../http2/server - * @compile ../HttpServerAdapters.java - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.test.lib.net.SimpleSSLContext * @run testng/othervm FilePublisherTest * @run testng/othervm/java.security.policy=FilePublisherTest.policy FilePublisherTest */ @@ -63,9 +58,13 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.out; import static java.net.http.HttpClient.Builder.NO_PROXY; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static org.testng.Assert.assertEquals; public class FilePublisherTest implements HttpServerAdapters { @@ -202,23 +201,19 @@ public void setup() throws Exception { InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpServerAdapters.HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpServerAdapters.HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new HttpEchoHandler(), "/http1/echo"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/echo"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpServerAdapters.HttpTestServer.of(httpsServer); + httpsTestServer = HttpServerAdapters.HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(new HttpEchoHandler(), "/https1/echo"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/echo"; - http2TestServer = HttpServerAdapters.HttpTestServer.of( - new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpServerAdapters.HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new HttpEchoHandler(), "/http2/echo"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/echo"; - https2TestServer = HttpServerAdapters.HttpTestServer.of( - new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpServerAdapters.HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new HttpEchoHandler(), "/https2/echo"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/echo"; diff --git a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherTest.policy b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherTest.policy index 82f517858bf..6ee4f3abdbf 100644 --- a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherTest.policy +++ b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherTest.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2020, 2023, 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 @@ -28,25 +28,35 @@ grant codeBase "file:${test.classes}/../../../../../test/lib/-" { }; // for JTwork/classes/0/java/net/httpclient/http2/server/* -grant codeBase "file:${test.classes}/../../../../../java/net/httpclient/http2/server/*" { +grant codeBase "file:${test.classes}/../../../../../test/jdk/java/net/httpclient/lib/-" { permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.common"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.frame"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack"; permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http"; - permission java.net.SocketPermission "localhost:*", "accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "accept,resolve"; permission java.lang.RuntimePermission "modifyThread"; }; grant codeBase "file:${test.classes}/*" { - permission java.net.URLPermission "http://localhost:*/http1/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/https1/echo", "POST"; - permission java.net.URLPermission "http://localhost:*/http2/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/https2/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/http1/echo", "GET"; - permission java.net.URLPermission "https://localhost:*/https1/echo", "GET"; - permission java.net.URLPermission "http://localhost:*/http2/echo", "GET"; - permission java.net.URLPermission "https://localhost:*/https2/echo", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/http1/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "POST"; + permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/http1/echo", "GET"; + permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "GET"; + permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "GET"; + // ipv6 + permission java.net.URLPermission "http://[::1]:*/http1/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/https1/echo", "POST"; + permission java.net.URLPermission "http://[::1]:*/http2/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/https2/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/http1/echo", "GET"; + permission java.net.URLPermission "https://[::1]:*/https1/echo", "GET"; + permission java.net.URLPermission "http://[::1]:*/http2/echo", "GET"; + permission java.net.URLPermission "https://[::1]:*/https2/echo", "GET"; // file permissions permission java.io.FilePermission "${user.dir}${/}defaultFile.txt", "read,write,delete"; @@ -62,7 +72,8 @@ grant codeBase "file:${test.classes}/*" { permission java.util.logging.LoggingPermission "control"; // needed to grant the HTTP servers - permission java.net.SocketPermission "localhost:*", "accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "accept,resolve"; permission java.util.PropertyPermission "*", "read"; permission java.lang.RuntimePermission "modifyThread"; diff --git a/test/jdk/java/net/httpclient/FlowAdapterPublisherTest.java b/test/jdk/java/net/httpclient/FlowAdapterPublisherTest.java index 73dea64edfd..1248ef9c71f 100644 --- a/test/jdk/java/net/httpclient/FlowAdapterPublisherTest.java +++ b/test/jdk/java/net/httpclient/FlowAdapterPublisherTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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,6 +43,10 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; @@ -61,15 +65,9 @@ /* * @test * @summary Basic tests for Flow adapter Publishers - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.test.lib.net.SimpleSSLContext * @run testng/othervm FlowAdapterPublisherTest */ diff --git a/test/jdk/java/net/httpclient/FlowAdapterSubscriberTest.java b/test/jdk/java/net/httpclient/FlowAdapterSubscriberTest.java index 8a2796c991f..11e0b8df547 100644 --- a/test/jdk/java/net/httpclient/FlowAdapterSubscriberTest.java +++ b/test/jdk/java/net/httpclient/FlowAdapterSubscriberTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -48,6 +48,10 @@ import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import java.net.http.HttpResponse.BodySubscribers; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; @@ -62,15 +66,8 @@ /* * @test * @summary Basic tests for Flow adapter Subscribers - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext * @run testng/othervm -Djdk.internal.httpclient.debug=true FlowAdapterSubscriberTest */ diff --git a/test/jdk/java/net/httpclient/ForbiddenHeadTest.java b/test/jdk/java/net/httpclient/ForbiddenHeadTest.java index 950676d74c8..0c39b44d7f5 100644 --- a/test/jdk/java/net/httpclient/ForbiddenHeadTest.java +++ b/test/jdk/java/net/httpclient/ForbiddenHeadTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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,18 +25,9 @@ * @test * @summary checks that receiving 403 for a HEAD request after * 401/407 doesn't cause any unexpected behavior. - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * java.base/sun.net.www.http - * java.base/sun.net.www - * java.base/sun.net - * @library /test/lib http2/server - * @build HttpServerAdapters DigestEchoServer Http2TestServer ForbiddenHeadTest - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build DigestEchoServer ForbiddenHeadTest jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.test.lib.net.SimpleSSLContext * @run testng/othervm * -Djdk.http.auth.tunneling.disabledSchemes * -Djdk.httpclient.HttpClient.log=headers,requests @@ -84,9 +75,13 @@ import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.err; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; @@ -338,22 +333,18 @@ public void setup() throws Exception { if (sslContext == null) throw new AssertionError("Unexpected null sslContext"); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new UnauthorizedHandler(), "/http1/"); httpTestServer.addHandler(new UnauthorizedHandler(), "/http2/proxy/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(new UnauthorizedHandler(),"/https1/"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1"; - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new UnauthorizedHandler(), "/http2/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new UnauthorizedHandler(), "/https2/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2"; diff --git a/test/jdk/java/net/httpclient/GZIPInputStreamTest.java b/test/jdk/java/net/httpclient/GZIPInputStreamTest.java index 1ff26a38dde..e2a382dfc5e 100644 --- a/test/jdk/java/net/httpclient/GZIPInputStreamTest.java +++ b/test/jdk/java/net/httpclient/GZIPInputStreamTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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,12 +25,8 @@ * @test * @bug 8217264 * @summary Tests that you can map an InputStream to a GZIPInputStream - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm GZIPInputStreamTest */ @@ -65,8 +61,12 @@ import java.util.function.Supplier; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; @@ -544,26 +544,23 @@ public void setup() throws Exception { HttpTestHandler gzipHandler = new LoremIpsumGZIPHandler(); // HTTP/1.1 - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(plainHandler, "/http1/chunk/txt"); httpTestServer.addHandler(gzipHandler, "/http1/chunk/gz"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/chunk"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(plainHandler, "/https1/chunk/txt"); httpsTestServer.addHandler(gzipHandler, "/https1/chunk/gz"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/chunk"; // HTTP/2 - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(plainHandler, "/http2/chunk/txt"); http2TestServer.addHandler(gzipHandler, "/http2/chunk/gz"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/chunk"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(plainHandler, "/https2/chunk/txt"); https2TestServer.addHandler(gzipHandler, "/https2/chunk/gz"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/chunk"; diff --git a/test/jdk/java/net/httpclient/HeadTest.java b/test/jdk/java/net/httpclient/HeadTest.java index 30fb5741d5d..81eeb612073 100644 --- a/test/jdk/java/net/httpclient/HeadTest.java +++ b/test/jdk/java/net/httpclient/HeadTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,15 +25,8 @@ * @test * @bug 8203433 * @summary (httpclient) Add tests for HEAD and 304 responses. - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext * @run testng/othervm * -Djdk.httpclient.HttpClient.log=trace,headers,requests * HeadTest @@ -79,8 +72,12 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static java.net.HttpURLConnection.HTTP_OK; import static org.testng.Assert.assertEquals; @@ -114,20 +111,20 @@ public class HeadTest implements HttpServerAdapters { @DataProvider(name = "positive") public Object[][] positive() { return new Object[][] { - { httpURI, "GET", HTTP_NOT_MODIFIED, HttpClient.Version.HTTP_1_1 }, - { httpsURI, "GET", HTTP_NOT_MODIFIED, HttpClient.Version.HTTP_1_1 }, + { httpURI, "GET", HTTP_NOT_MODIFIED, HTTP_1_1 }, + { httpsURI, "GET", HTTP_NOT_MODIFIED, HTTP_1_1 }, { httpURI, "GET", HTTP_NOT_MODIFIED, HttpClient.Version.HTTP_2 }, { httpsURI, "GET", HTTP_NOT_MODIFIED, HttpClient.Version.HTTP_2 }, - { httpURI, "HEAD", HTTP_OK, HttpClient.Version.HTTP_1_1 }, - { httpsURI, "HEAD", HTTP_OK, HttpClient.Version.HTTP_1_1 }, + { httpURI, "HEAD", HTTP_OK, HTTP_1_1 }, + { httpsURI, "HEAD", HTTP_OK, HTTP_1_1 }, { httpURI, "HEAD", HTTP_OK, HttpClient.Version.HTTP_2 }, { httpsURI, "HEAD", HTTP_OK, HttpClient.Version.HTTP_2 }, - { httpURI + "transfer/", "GET", HTTP_NOT_MODIFIED, HttpClient.Version.HTTP_1_1 }, - { httpsURI + "transfer/", "GET", HTTP_NOT_MODIFIED, HttpClient.Version.HTTP_1_1 }, + { httpURI + "transfer/", "GET", HTTP_NOT_MODIFIED, HTTP_1_1 }, + { httpsURI + "transfer/", "GET", HTTP_NOT_MODIFIED, HTTP_1_1 }, { httpURI + "transfer/", "GET", HTTP_NOT_MODIFIED, HttpClient.Version.HTTP_2 }, { httpsURI + "transfer/", "GET", HTTP_NOT_MODIFIED, HttpClient.Version.HTTP_2 }, - { httpURI + "transfer/", "HEAD", HTTP_OK, HttpClient.Version.HTTP_1_1 }, - { httpsURI + "transfer/", "HEAD", HTTP_OK, HttpClient.Version.HTTP_1_1 }, + { httpURI + "transfer/", "HEAD", HTTP_OK, HTTP_1_1 }, + { httpsURI + "transfer/", "HEAD", HTTP_OK, HTTP_1_1 }, { httpURI + "transfer/", "HEAD", HTTP_OK, HttpClient.Version.HTTP_2 }, { httpsURI + "transfer/", "HEAD", HTTP_OK, HttpClient.Version.HTTP_2 } }; @@ -175,19 +172,17 @@ public void setup() throws Exception { InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new HeadHandler(), "/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(new HeadHandler(),"/"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/"; - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new HeadHandler(), "/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, 0)); + https2TestServer = HttpTestServer.create(HTTP_2, SSLContext.getDefault()); https2TestServer.addHandler(new HeadHandler(), "/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/"; diff --git a/test/jdk/java/net/httpclient/HttpInputStreamAvailableTest.java b/test/jdk/java/net/httpclient/HttpInputStreamAvailableTest.java new file mode 100644 index 00000000000..3073ca6fccf --- /dev/null +++ b/test/jdk/java/net/httpclient/HttpInputStreamAvailableTest.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2023, 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 8306040 + * @summary HttpResponseInputStream.available() returns 1 on empty stream + * @library /test/lib + * @run junit/othervm HttpInputStreamAvailableTest + * + */ +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import jdk.test.lib.net.URIBuilder; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class HttpInputStreamAvailableTest { + + private HttpServer server; + private int port; + static final String TEST_MESSAGE = "This is test message"; + static final int ZERO = 0; + + @BeforeAll + void setup() throws Exception { + InetAddress loopback = InetAddress.getLoopbackAddress(); + InetSocketAddress addr = new InetSocketAddress(loopback, 0); + server = HttpServer.create(addr, 0); + port = server.getAddress().getPort(); + FirstHandler fHandler = new FirstHandler(); + server.createContext("/NonZeroResponse/", fHandler); + SecondHandler sHandler = new SecondHandler(); + server.createContext("/ZeroResponse/", sHandler); + server.start(); + } + + @AfterAll + void teardown() throws Exception { + server.stop(0); + } + + @Test + public void test() throws Exception { + HttpClient client = HttpClient + .newBuilder() + .proxy(HttpClient.Builder.NO_PROXY) + .build(); + + URI uri = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(port) + .path("/NonZeroResponse/") + .build(); + + HttpRequest request = HttpRequest + .newBuilder(uri) + .GET() + .build(); + + // Send a httpRequest and assert the bytes available + HttpResponse response = client.send(request, + HttpResponse.BodyHandlers.ofInputStream()); + try ( InputStream in = response.body()) { + in.readNBytes(2); + // this is not guaranteed, but a failure here would be surprising + assertEquals(TEST_MESSAGE.length() - 2, in.available()); + //read the remaining data + in.readAllBytes(); + //available should return 0 + assertEquals(ZERO, in.available()); + } + } + + @Test + public void test1() throws Exception { + HttpClient client = HttpClient + .newBuilder() + .proxy(HttpClient.Builder.NO_PROXY) + .build(); + + URI uri = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(port) + .path("/ZeroResponse/") + .build(); + + HttpRequest request = HttpRequest + .newBuilder(uri) + .GET() + .build(); + + // Send a httpRequest and assert the bytes available + HttpResponse response = client.send(request, + HttpResponse.BodyHandlers.ofInputStream()); + try ( InputStream in = response.body()) { + assertEquals(ZERO, in.available()); + in.readAllBytes(); + assertEquals(ZERO, in.available()); + } + } + + static class FirstHandler implements HttpHandler { + + @Override + public void handle(HttpExchange exchange) throws IOException { + try ( OutputStream os = exchange.getResponseBody()) { + byte[] workingResponse = TEST_MESSAGE.getBytes(); + exchange.sendResponseHeaders(200, workingResponse.length); + os.write(workingResponse); + os.flush(); + } + } + } + + static class SecondHandler implements HttpHandler { + + @Override + public void handle(HttpExchange exchange) throws IOException { + exchange.sendResponseHeaders(204, -1); + } + } +} diff --git a/test/jdk/java/net/httpclient/HttpInputStreamTest.java b/test/jdk/java/net/httpclient/HttpInputStreamTest.java index 7f1a2b4815d..2eb7899e1f0 100644 --- a/test/jdk/java/net/httpclient/HttpInputStreamTest.java +++ b/test/jdk/java/net/httpclient/HttpInputStreamTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -286,7 +286,7 @@ public static Optional getCharset(HttpHeaders headers) { public static void main(String[] args) throws Exception { HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest - .newBuilder(new URI("http://hg.openjdk.java.net/jdk9/sandbox/jdk/shortlog/http-client-branch/")) + .newBuilder(new URI("https://hg.openjdk.org/jdk9/sandbox/jdk/shortlog/http-client-branch/")) .GET() .build(); diff --git a/test/jdk/java/net/httpclient/HttpRedirectTest.java b/test/jdk/java/net/httpclient/HttpRedirectTest.java index 34ec95f7770..0cfb009adbf 100644 --- a/test/jdk/java/net/httpclient/HttpRedirectTest.java +++ b/test/jdk/java/net/httpclient/HttpRedirectTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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 @@ -28,6 +28,8 @@ import org.testng.annotations.AfterClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static org.testng.Assert.*; import javax.net.ssl.SSLContext; @@ -57,20 +59,16 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; /** * @test * @bug 8232625 * @summary This test verifies that the HttpClient works correctly when redirecting a post request. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters DigestEchoServer HttpRedirectTest - * @modules java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * java.base/sun.net.www.http - * java.base/sun.net.www - * java.base/sun.net + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext DigestEchoServer HttpRedirectTest + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Dtest.requiresHost=true * -Djdk.httpclient.HttpClient.log=headers * -Djdk.internal.httpclient.debug=false @@ -167,9 +165,7 @@ public void setUp() throws Exception { InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); // HTTP/1.1 - HttpServer server1 = HttpServer.create(sa, 0); - server1.setExecutor(executor); - http1Server = HttpTestServer.of(server1); + http1Server = HttpTestServer.create(HTTP_1_1, null, executor); http1Server.addHandler(new HttpTestRedirectHandler("http", http1Server), "/HttpRedirectTest/http1/"); http1Server.start(); @@ -187,16 +183,14 @@ public void setUp() throws Exception { https1URI = new URI("https://" + https1Server.serverAuthority() + "/HttpRedirectTest/https1/"); // HTTP/2.0 - http2Server = HttpTestServer.of( - new Http2TestServer("localhost", false, 0)); + http2Server = HttpTestServer.create(HTTP_2); http2Server.addHandler(new HttpTestRedirectHandler("http", http2Server), "/HttpRedirectTest/http2/"); http2Server.start(); http2URI = new URI("http://" + http2Server.serverAuthority() + "/HttpRedirectTest/http2/"); // HTTPS/2.0 - https2Server = HttpTestServer.of( - new Http2TestServer("localhost", true, 0)); + https2Server = HttpTestServer.create(HTTP_2, SSLContext.getDefault()); https2Server.addHandler(new HttpTestRedirectHandler("https", https2Server), "/HttpRedirectTest/https2/"); https2Server.start(); diff --git a/test/jdk/java/net/httpclient/HttpSlowServerTest.java b/test/jdk/java/net/httpclient/HttpSlowServerTest.java index 298f3222933..a1c36e9dc16 100644 --- a/test/jdk/java/net/httpclient/HttpSlowServerTest.java +++ b/test/jdk/java/net/httpclient/HttpSlowServerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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 @@ -50,20 +50,18 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; /** * @test * @summary This test verifies that the HttpClient works correctly when connected to a * slow server. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters DigestEchoServer HttpSlowServerTest - * @modules java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * java.base/sun.net.www.http - * java.base/sun.net.www - * java.base/sun.net + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext + * DigestEchoServer HttpSlowServerTest * @run main/othervm -Dtest.requiresHost=true * -Djdk.httpclient.HttpClient.log=headers * -Djdk.internal.httpclient.debug=false @@ -131,9 +129,7 @@ public void setUp() throws Exception { InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); // HTTP/1.1 - HttpServer server1 = HttpServer.create(sa, 0); - server1.setExecutor(executor); - http1Server = HttpTestServer.of(server1); + http1Server = HttpTestServer.create(HTTP_1_1, null, executor); http1Server.addHandler(new HttpTestSlowHandler(), "/HttpSlowServerTest/http1/"); http1Server.start(); http1URI = new URI("http://" + http1Server.serverAuthority() + "/HttpSlowServerTest/http1/"); @@ -149,15 +145,13 @@ public void setUp() throws Exception { https1URI = new URI("https://" + https1Server.serverAuthority() + "/HttpSlowServerTest/https1/"); // HTTP/2.0 - http2Server = HttpTestServer.of( - new Http2TestServer("localhost", false, 0)); + http2Server = HttpTestServer.create(HTTP_2); http2Server.addHandler(new HttpTestSlowHandler(), "/HttpSlowServerTest/http2/"); http2Server.start(); http2URI = new URI("http://" + http2Server.serverAuthority() + "/HttpSlowServerTest/http2/"); // HTTPS/2.0 - https2Server = HttpTestServer.of( - new Http2TestServer("localhost", true, 0)); + https2Server = HttpTestServer.create(HTTP_2, SSLContext.getDefault()); https2Server.addHandler(new HttpTestSlowHandler(), "/HttpSlowServerTest/https2/"); https2Server.start(); https2URI = new URI("https://" + https2Server.serverAuthority() + "/HttpSlowServerTest/https2/"); diff --git a/test/jdk/java/net/httpclient/HttpVersionsTest.java b/test/jdk/java/net/httpclient/HttpVersionsTest.java index f04c1d50ea0..00b0db1af4e 100644 --- a/test/jdk/java/net/httpclient/HttpVersionsTest.java +++ b/test/jdk/java/net/httpclient/HttpVersionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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,15 +25,9 @@ * @test * @summary Checks HTTP versions when interacting with an HTTP/2 server * @bug 8242044 - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext - * @build jdk.test.lib.Platform + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext + * jdk.test.lib.Platform * @run testng/othervm HttpVersionsTest */ @@ -48,6 +42,10 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.net.ssl.SSLContext; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; diff --git a/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java b/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java index 933e0f75efe..f83118adea3 100644 --- a/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java +++ b/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, 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 @@ -36,6 +36,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import javax.net.ssl.SSLContext; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.test.lib.net.SimpleSSLContext; import static java.lang.System.out; @@ -47,15 +49,9 @@ * even when using an HTTPS tunnel. This test uses an authenticating * proxy (basic auth) serving an authenticated server (basic auth). * The test also helps verifying the fix for 8262027. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters ProxyServer HttpsTunnelAuthTest - * @modules java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * java.base/sun.net.www.http - * java.base/sun.net.www - * java.base/sun.net + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext + * ProxyServer HttpsTunnelAuthTest * @run main/othervm -Djdk.httpclient.HttpClient.log=requests,headers,errors * -Djdk.http.auth.tunneling.disabledSchemes * -Djdk.httpclient.allowRestrictedHeaders=connection diff --git a/test/jdk/java/net/httpclient/HttpsTunnelTest.java b/test/jdk/java/net/httpclient/HttpsTunnelTest.java index 60db57d47a4..86666539942 100644 --- a/test/jdk/java/net/httpclient/HttpsTunnelTest.java +++ b/test/jdk/java/net/httpclient/HttpsTunnelTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -38,8 +38,12 @@ import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.String.format; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; /** * @test @@ -50,15 +54,9 @@ * a new h2 connection to the new host. It also verifies that * the stack sends the appropriate "host" header to the proxy. * @bug 8196967 8222527 - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters DigestEchoServer HttpsTunnelTest - * @modules java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * java.base/sun.net.www.http - * java.base/sun.net.www - * java.base/sun.net + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext + * DigestEchoServer HttpsTunnelTest * @run main/othervm -Dtest.requiresHost=true * -Djdk.httpclient.HttpClient.log=headers * -Djdk.internal.httpclient.debug=true HttpsTunnelTest @@ -106,15 +104,11 @@ public HttpClient newHttpClient(ProxySelector ps) { } public static void main(String[] args) throws Exception { - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - HttpsServer server1 = HttpsServer.create(sa, 0); - server1.setHttpsConfigurator(new HttpsConfigurator(context)); HttpTestServer http1Server = - HttpTestServer.of(server1); + HttpTestServer.create(HTTP_1_1, context); http1Server.addHandler(new HttpTestEchoHandler(), "/"); http1Server.start(); - HttpTestServer http2Server = HttpTestServer.of( - new Http2TestServer("localhost", true, 0)); + HttpTestServer http2Server = HttpTestServer.create(HTTP_2, SSLContext.getDefault()); http2Server.addHandler(new HttpTestEchoHandler(), "/"); http2Server.start(); @@ -158,7 +152,7 @@ public static void main(String[] args) throws Exception { if (response.statusCode() != 200) { throw new RuntimeException("Unexpected status code: " + response); } - if (response.version() != Version.HTTP_1_1) { + if (response.version() != HTTP_1_1) { throw new RuntimeException("Unexpected protocol version: " + response.version()); } diff --git a/test/jdk/java/net/httpclient/ISO_8859_1_Test.java b/test/jdk/java/net/httpclient/ISO_8859_1_Test.java index f947d886dbc..4e3f428dbfb 100644 --- a/test/jdk/java/net/httpclient/ISO_8859_1_Test.java +++ b/test/jdk/java/net/httpclient/ISO_8859_1_Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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,13 +24,9 @@ /* * @test * @bug 8252374 - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker AggregateRequestBodyTest - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker * @run testng/othervm -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=requests,responses,errors * ISO_8859_1_Test @@ -81,6 +77,9 @@ import java.util.stream.Stream; import javax.net.ssl.SSLContext; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; + import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; @@ -97,6 +96,8 @@ import org.testng.annotations.Test; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; @@ -413,23 +414,20 @@ public void setup() throws Exception { http1DummyServer = new DummyServer(); http1Dummy = "http://" + http1DummyServer.serverAuthority() +"/http1/dummy/x"; - HttpServer http1 = HttpServer.create(loopback, 0); - http1TestServer = HttpServerAdapters.HttpTestServer.of(http1); + http1TestServer = HttpServerAdapters.HttpTestServer.create(HTTP_1_1); http1TestServer.addHandler(handler, "/http1/server/"); http1URI = "http://" + http1TestServer.serverAuthority() + "/http1/server/x"; - HttpsServer https1 = HttpsServer.create(loopback, 0); - https1.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - https1TestServer = HttpServerAdapters.HttpTestServer.of(https1); + https1TestServer = HttpServerAdapters.HttpTestServer.create(HTTP_1_1, sslContext); https1TestServer.addHandler(handler, "/https1/server/"); https1URI = "https://" + https1TestServer.serverAuthority() + "/https1/server/x"; // HTTP/2 - http2TestServer = HttpServerAdapters.HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpServerAdapters.HttpTestServer.create(HTTP_2); http2TestServer.addHandler(handler, "/http2/server/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/server/x"; - https2TestServer = HttpServerAdapters.HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpServerAdapters.HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(handler, "/https2/server/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/server/x"; diff --git a/test/jdk/java/net/httpclient/ImmutableFlowItems.java b/test/jdk/java/net/httpclient/ImmutableFlowItems.java index 9a22a34bfe0..d917d178538 100644 --- a/test/jdk/java/net/httpclient/ImmutableFlowItems.java +++ b/test/jdk/java/net/httpclient/ImmutableFlowItems.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,12 +25,8 @@ * @test * @summary Tests response body subscribers's onNext's Lists are unmodifiable, * and that the buffers are read-only - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer * @run testng/othervm ImmutableFlowItems */ @@ -57,6 +53,9 @@ import java.net.http.HttpResponse.BodySubscriber; import java.net.http.HttpResponse.BodySubscribers; import javax.net.ssl.SSLContext; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; diff --git a/test/jdk/java/net/httpclient/InvalidInputStreamSubscriptionRequest.java b/test/jdk/java/net/httpclient/InvalidInputStreamSubscriptionRequest.java index 1a7791f336a..2f4f96e8b9b 100644 --- a/test/jdk/java/net/httpclient/InvalidInputStreamSubscriptionRequest.java +++ b/test/jdk/java/net/httpclient/InvalidInputStreamSubscriptionRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,12 +26,9 @@ * @summary Tests an asynchronous BodySubscriber that completes * immediately with an InputStream which issues bad * requests - * @library /test/lib http2/server + * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext ReferenceTracker - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm InvalidInputStreamSubscriptionRequest */ @@ -73,8 +70,12 @@ import java.util.concurrent.Flow.Publisher; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Supplier; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; @@ -229,7 +230,7 @@ public void testNoBody(String uri, boolean sameClient, BHS handlers) String body = new String(is.readAllBytes(), UTF_8); assertEquals(body, ""); if (uri.endsWith("/chunk") - && response.version() == HttpClient.Version.HTTP_1_1) { + && response.version() == HTTP_1_1) { // with /fixed and 0 length // there's no need for any call to request() throw new RuntimeException("Expected IAE not thrown"); @@ -279,7 +280,7 @@ public void testNoBodyAsync(String uri, boolean sameClient, BHS handlers) // Get the final result and compare it with the expected body assertEquals(result.get(), ""); if (uri.endsWith("/chunk") - && response.get().version() == HttpClient.Version.HTTP_1_1) { + && response.get().version() == HTTP_1_1) { // with /fixed and 0 length // there's no need for any call to request() throw new RuntimeException("Expected IAE not thrown"); @@ -447,16 +448,13 @@ public void setup() throws Exception { // HTTP/1.1 HttpTestHandler h1_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h1_chunkHandler = new HTTP_VariableLengthHandler(); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler( h1_fixedLengthHandler, "/http1/fixed"); httpTestServer.addHandler(h1_chunkHandler,"/http1/chunk"); httpURI_fixed = "http://" + httpTestServer.serverAuthority() + "/http1/fixed"; httpURI_chunk = "http://" + httpTestServer.serverAuthority() + "/http1/chunk"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(h1_fixedLengthHandler, "/https1/fixed"); httpsTestServer.addHandler(h1_chunkHandler, "/https1/chunk"); httpsURI_fixed = "https://" + httpsTestServer.serverAuthority() + "/https1/fixed"; @@ -466,13 +464,13 @@ public void setup() throws Exception { HttpTestHandler h2_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h2_chunkedHandler = new HTTP_VariableLengthHandler(); - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(h2_fixedLengthHandler, "/http2/fixed"); http2TestServer.addHandler(h2_chunkedHandler, "/http2/chunk"); http2URI_fixed = "http://" + http2TestServer.serverAuthority() + "/http2/fixed"; http2URI_chunk = "http://" + http2TestServer.serverAuthority() + "/http2/chunk"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(h2_fixedLengthHandler, "/https2/fixed"); https2TestServer.addHandler(h2_chunkedHandler, "/https2/chunk"); https2URI_fixed = "https://" + https2TestServer.serverAuthority() + "/https2/fixed"; diff --git a/test/jdk/java/net/httpclient/InvalidSubscriptionRequest.java b/test/jdk/java/net/httpclient/InvalidSubscriptionRequest.java index adcf169730c..3cd7cb629ea 100644 --- a/test/jdk/java/net/httpclient/InvalidSubscriptionRequest.java +++ b/test/jdk/java/net/httpclient/InvalidSubscriptionRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,12 +27,9 @@ * @summary Tests an asynchronous BodySubscriber that completes * immediately with a Publisher> whose * subscriber issues bad requests - * @library /test/lib http2/server + * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext ReferenceTracker - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm InvalidSubscriptionRequest */ @@ -71,7 +68,12 @@ import java.util.concurrent.Flow.Publisher; import java.util.function.Supplier; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; + import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; @@ -176,7 +178,7 @@ public void testNoBody(String uri, boolean sameClient, BHS handlers) throws Exce String body = ofString.getBody().toCompletableFuture().get(); assertEquals(body, ""); if (uri.endsWith("/chunk") - && response.version() == HttpClient.Version.HTTP_1_1) { + && response.version() == HTTP_1_1) { // with /fixed and 0 length // there's no need for any call to request() throw new RuntimeException("Expected IAE not thrown"); @@ -220,7 +222,7 @@ public void testNoBodyAsync(String uri, boolean sameClient, BHS handlers) throws // Get the final result and compare it with the expected body assertEquals(result.get(), ""); if (uri.endsWith("/chunk") - && response.get().version() == HttpClient.Version.HTTP_1_1) { + && response.get().version() == HTTP_1_1) { // with /fixed and 0 length // there's no need for any call to request() throw new RuntimeException("Expected IAE not thrown"); @@ -379,16 +381,13 @@ public void setup() throws Exception { // HTTP/1.1 HttpTestHandler h1_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h1_chunkHandler = new HTTP_VariableLengthHandler(); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler( h1_fixedLengthHandler, "/http1/fixed"); httpTestServer.addHandler(h1_chunkHandler,"/http1/chunk"); httpURI_fixed = "http://" + httpTestServer.serverAuthority() + "/http1/fixed"; httpURI_chunk = "http://" + httpTestServer.serverAuthority() + "/http1/chunk"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(h1_fixedLengthHandler, "/https1/fixed"); httpsTestServer.addHandler(h1_chunkHandler, "/https1/chunk"); httpsURI_fixed = "https://" + httpsTestServer.serverAuthority() + "/https1/fixed"; @@ -398,13 +397,13 @@ public void setup() throws Exception { HttpTestHandler h2_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h2_chunkedHandler = new HTTP_VariableLengthHandler(); - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(h2_fixedLengthHandler, "/http2/fixed"); http2TestServer.addHandler(h2_chunkedHandler, "/http2/chunk"); http2URI_fixed = "http://" + http2TestServer.serverAuthority() + "/http2/fixed"; http2URI_chunk = "http://" + http2TestServer.serverAuthority() + "/http2/chunk"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(h2_fixedLengthHandler, "/https2/fixed"); https2TestServer.addHandler(h2_chunkedHandler, "/https2/chunk"); https2URI_fixed = "https://" + https2TestServer.serverAuthority() + "/https2/fixed"; diff --git a/test/jdk/java/net/httpclient/LargeHandshakeTest.java b/test/jdk/java/net/httpclient/LargeHandshakeTest.java index 2c798012efa..b5c3dfefe8c 100644 --- a/test/jdk/java/net/httpclient/LargeHandshakeTest.java +++ b/test/jdk/java/net/httpclient/LargeHandshakeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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 @@ -60,6 +60,10 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; /** * @test @@ -75,15 +79,9 @@ * as first argument, and copy paste the new values of the COMMAND and * BASE64_CERT constant printed by the test into the test. * Then restore the original at run line and test again. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters DigestEchoServer LargeHandshakeTest - * @modules java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * java.base/sun.net.www.http - * java.base/sun.net.www - * java.base/sun.net + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext + * DigestEchoServer * @run main/othervm -Dtest.requiresHost=true * -Djdk.httpclient.HttpClient.log=headers * -Djdk.internal.httpclient.debug=true @@ -1004,9 +1002,7 @@ public void setUp() throws Exception { InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); // HTTP/1.1 - HttpServer server1 = HttpServer.create(sa, 0); - server1.setExecutor(executor); - http1Server = HttpTestServer.of(server1); + http1Server = HttpTestServer.create(HTTP_1_1, null, executor); http1Server.addHandler(new HttpTestLargeHandler(), "/LargeHandshakeTest/http1/"); http1Server.start(); http1URI = new URI("http://" + http1Server.serverAuthority() + "/LargeHandshakeTest/http1/"); @@ -1022,15 +1018,13 @@ public void setUp() throws Exception { https1URI = new URI("https://" + https1Server.serverAuthority() + "/LargeHandshakeTest/https1/"); // HTTP/2.0 - http2Server = HttpTestServer.of( - new Http2TestServer("localhost", false, 0)); + http2Server = HttpTestServer.create(HTTP_2); http2Server.addHandler(new HttpTestLargeHandler(), "/LargeHandshakeTest/http2/"); http2Server.start(); http2URI = new URI("http://" + http2Server.serverAuthority() + "/LargeHandshakeTest/http2/"); // HTTPS/2.0 - https2Server = HttpTestServer.of( - new Http2TestServer("localhost", true, 0)); + https2Server = HttpTestServer.create(HTTP_2, SSLContext.getDefault()); https2Server.addHandler(new HttpTestLargeHandler(), "/LargeHandshakeTest/https2/"); https2Server.start(); https2URI = new URI("https://" + https2Server.serverAuthority() + "/LargeHandshakeTest/https2/"); diff --git a/test/jdk/java/net/httpclient/LargeResponseTest.java b/test/jdk/java/net/httpclient/LargeResponseTest.java index 6dd7ca3479f..1d788f62f4c 100644 --- a/test/jdk/java/net/httpclient/LargeResponseTest.java +++ b/test/jdk/java/net/httpclient/LargeResponseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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 @@ -50,6 +50,10 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; /** * @test @@ -57,15 +61,9 @@ * @summary This test verifies that the HttpClient works correctly when the server * sends large amount of data. Note that this test will pass even without * the fix for JDK-8231449, which is unfortunate. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters DigestEchoServer LargeResponseTest - * @modules java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * java.base/sun.net.www.http - * java.base/sun.net.www - * java.base/sun.net + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.test.lib.net.SimpleSSLContext DigestEchoServer * @run main/othervm -Dtest.requiresHost=true * -Djdk.httpclient.HttpClient.log=headers * -Djdk.internal.httpclient.debug=true @@ -129,9 +127,7 @@ public void setUp() throws Exception { InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); // HTTP/1.1 - HttpServer server1 = HttpServer.create(sa, 0); - server1.setExecutor(executor); - http1Server = HttpTestServer.of(server1); + http1Server = HttpTestServer.create(HTTP_1_1, null, executor); http1Server.addHandler(new HttpTestLargeHandler(), "/LargeResponseTest/http1/"); http1Server.start(); http1URI = new URI("http://" + http1Server.serverAuthority() + "/LargeResponseTest/http1/"); @@ -147,15 +143,13 @@ public void setUp() throws Exception { https1URI = new URI("https://" + https1Server.serverAuthority() + "/LargeResponseTest/https1/"); // HTTP/2.0 - http2Server = HttpTestServer.of( - new Http2TestServer("localhost", false, 0)); + http2Server = HttpTestServer.create(HTTP_2); http2Server.addHandler(new HttpTestLargeHandler(), "/LargeResponseTest/http2/"); http2Server.start(); http2URI = new URI("http://" + http2Server.serverAuthority() + "/LargeResponseTest/http2/"); // HTTPS/2.0 - https2Server = HttpTestServer.of( - new Http2TestServer("localhost", true, 0)); + https2Server = HttpTestServer.create(HTTP_2, SSLContext.getDefault()); https2Server.addHandler(new HttpTestLargeHandler(), "/LargeResponseTest/https2/"); https2Server.start(); https2URI = new URI("https://" + https2Server.serverAuthority() + "/LargeResponseTest/https2/"); diff --git a/test/jdk/java/net/httpclient/LightWeightHttpServer.java b/test/jdk/java/net/httpclient/LightWeightHttpServer.java index 54fa174296f..92603d55d0a 100644 --- a/test/jdk/java/net/httpclient/LightWeightHttpServer.java +++ b/test/jdk/java/net/httpclient/LightWeightHttpServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -119,14 +119,21 @@ public static void initServer() throws IOException { System.out.println("HTTP server port = " + port); httpsport = httpsServer.getAddress().getPort(); System.out.println("HTTPS server port = " + httpsport); - httproot = "http://localhost:" + port + "/"; - httpsroot = "https://localhost:" + httpsport + "/"; + httproot = "http://" + makeServerAuthority(httpServer.getAddress()) + "/"; + httpsroot = "https://" + makeServerAuthority(httpsServer.getAddress()) + "/"; proxy = new ProxyServer(0, false); proxyPort = proxy.getPort(); System.out.println("Proxy port = " + proxyPort); } + private static String makeServerAuthority(final InetSocketAddress addr) { + final String hostIP = addr.getAddress().getHostAddress(); + // escape for ipv6 + final String h = hostIP.contains(":") ? "[" + hostIP + "]" : hostIP; + return h + ":" + addr.getPort(); + } + public static void stop() throws IOException { if (httpServer != null) { httpServer.stop(0); diff --git a/test/jdk/java/net/httpclient/LineBodyHandlerTest.java b/test/jdk/java/net/httpclient/LineBodyHandlerTest.java index 10717a848bd..3271f21a130 100644 --- a/test/jdk/java/net/httpclient/LineBodyHandlerTest.java +++ b/test/jdk/java/net/httpclient/LineBodyHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -54,6 +54,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import javax.net.ssl.SSLContext; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; @@ -63,6 +65,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_16; import static java.nio.charset.StandardCharsets.UTF_8; import static java.net.http.HttpRequest.BodyPublishers.ofString; @@ -77,15 +81,9 @@ * the BodyHandlers returned by BodyHandler::fromLineSubscriber * and BodyHandler::asLines * @bug 8256459 - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer LineBodyHandlerTest HttpServerAdapters ReferenceTracker - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build ReferenceTracker jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.test.lib.net.SimpleSSLContext * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:DiagnoseSyncOnValueBasedClasses=1 LineBodyHandlerTest */ @@ -674,24 +672,21 @@ public void setup() throws Exception { if (sslContext == null) throw new AssertionError("Unexpected null sslContext"); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0), + httpTestServer = HttpTestServer.create(HTTP_1_1, null, executorFor("HTTP/1.1 Server Thread")); httpTestServer.addHandler(new HttpTestEchoHandler(), "/http1/echo"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/echo"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer, + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext, executorFor("HTTPS/1.1 Server Thread")); httpsTestServer.addHandler(new HttpTestEchoHandler(),"/https1/echo"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/echo"; - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new HttpTestEchoHandler(), "/http2/echo"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/echo"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new HttpTestEchoHandler(), "/https2/echo"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/echo"; diff --git a/test/jdk/java/net/httpclient/ManyRequests.java b/test/jdk/java/net/httpclient/ManyRequests.java index 296377441a7..36b5c35000c 100644 --- a/test/jdk/java/net/httpclient/ManyRequests.java +++ b/test/jdk/java/net/httpclient/ManyRequests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, 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 @@ -176,7 +176,7 @@ static void test(HttpsServer server, HttpClient client) throws Exception { URI baseURI = URIBuilder.newBuilder() .scheme("https") - .host(InetAddress.getLoopbackAddress().getHostName()) + .loopback() .port(port) .path("/foo/x").build(); server.createContext("/foo", new TestEchoHandler()); diff --git a/test/jdk/java/net/httpclient/MappingResponseSubscriber.java b/test/jdk/java/net/httpclient/MappingResponseSubscriber.java index cbe936afe93..db74fb05663 100644 --- a/test/jdk/java/net/httpclient/MappingResponseSubscriber.java +++ b/test/jdk/java/net/httpclient/MappingResponseSubscriber.java @@ -24,12 +24,8 @@ /* * @test * @summary Tests mapped response subscriber - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer * @run testng/othervm * -Djdk.internal.httpclient.debug=true * MappingResponseSubscriber @@ -62,6 +58,9 @@ import java.net.http.HttpResponse.BodySubscriber; import java.util.function.Function; import javax.net.ssl.SSLContext; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; diff --git a/test/jdk/java/net/httpclient/MaxStreams.java b/test/jdk/java/net/httpclient/MaxStreams.java index 191a3a2d697..3d7f579ab61 100644 --- a/test/jdk/java/net/httpclient/MaxStreams.java +++ b/test/jdk/java/net/httpclient/MaxStreams.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,9 @@ * @test * @bug 8196389 * @summary Should HttpClient support SETTINGS_MAX_CONCURRENT_STREAMS from the server - * - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext - * @run testng/othervm -ea -esa MaxStreams + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext + * @run testng/othervm MaxStreams */ import java.io.IOException; @@ -53,13 +45,15 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Semaphore; import javax.net.ssl.SSLContext; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandler; import java.net.http.HttpResponse.BodyHandlers; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; @@ -79,9 +73,7 @@ public class MaxStreams { SSLContext ctx; String http2FixedURI; String https2FixedURI; - volatile CountDownLatch latch; ExecutorService exec; - final Semaphore canStartTestRun = new Semaphore(1); // we send an initial warm up request, then MAX_STREAMS+1 requests // in parallel. The last of them should hit the limit. @@ -103,11 +95,9 @@ public Object[][] variants() { } - @Test(dataProvider = "uris", timeOut=20000) + @Test(dataProvider = "uris") void testAsString(String uri) throws Exception { - System.err.println("Semaphore acquire"); - canStartTestRun.acquire(); - latch = new CountDownLatch(1); + CountDownLatch latch = new CountDownLatch(1); handler.setLatch(latch); HttpClient client = HttpClient.newBuilder().sslContext(ctx).build(); List>> responses = new LinkedList<>(); @@ -214,12 +204,11 @@ synchronized CountDownLatch getLatch() { @Override public void handle(Http2TestExchange t) throws IOException { - int c = -1; try (InputStream is = t.getRequestBody(); OutputStream os = t.getResponseBody()) { is.readAllBytes(); - c = counter.getAndIncrement(); + int c = counter.getAndIncrement(); if (c > 0 && c <= MAX_STREAMS) { // Wait for latch. try { @@ -228,18 +217,15 @@ public void handle(Http2TestExchange t) throws IOException { getLatch().await(); System.err.println("Latch resume"); } catch (InterruptedException ee) {} + } else if (c == MAX_STREAMS + 1) { + // client issues MAX_STREAMS + 3 requests in total + // but server should only see MAX_STREAMS + 2 in total. One is rejected by client + // counter c captured before increment so final value is MAX_STREAMS + 1 + System.err.println("Counter reset"); + counter.set(0); } t.sendResponseHeaders(200, RESPONSE.length()); os.write(RESPONSE.getBytes()); - } finally { - // client issues MAX_STREAMS + 3 requests in total - // but server should only see MAX_STREAMS + 2 in total. One is rejected by client - // counter c captured before increment so final value is MAX_STREAMS + 1 - if (c == MAX_STREAMS + 1) { - System.err.println("Semaphore release"); - counter.set(0); - canStartTestRun.release(); - } } } } diff --git a/test/jdk/java/net/httpclient/NoBodyPartOne.java b/test/jdk/java/net/httpclient/NoBodyPartOne.java index 66aaa2fc0e0..1edd9c9655b 100644 --- a/test/jdk/java/net/httpclient/NoBodyPartOne.java +++ b/test/jdk/java/net/httpclient/NoBodyPartOne.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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,12 +25,8 @@ * @test * @bug 8161157 * @summary Test response body handlers/subscribers when there is no body - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer * @run testng/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=all diff --git a/test/jdk/java/net/httpclient/NoBodyPartTwo.java b/test/jdk/java/net/httpclient/NoBodyPartTwo.java index ba4843e2901..67d7f2bcb88 100644 --- a/test/jdk/java/net/httpclient/NoBodyPartTwo.java +++ b/test/jdk/java/net/httpclient/NoBodyPartTwo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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,12 +25,8 @@ * @test * @bug 8161157 * @summary Test response body handlers/subscribers when there is no body - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer * @run testng/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=all diff --git a/test/jdk/java/net/httpclient/NonAsciiCharsInURI.java b/test/jdk/java/net/httpclient/NonAsciiCharsInURI.java index e3701a826f2..84519feeac1 100644 --- a/test/jdk/java/net/httpclient/NonAsciiCharsInURI.java +++ b/test/jdk/java/net/httpclient/NonAsciiCharsInURI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,15 +26,8 @@ * @summary Verify that non-US-ASCII chars are replaced with a sequence of * escaped octets that represent that char in the UTF-8 character set. * @bug 8201238 - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext * @compile -encoding utf-8 NonAsciiCharsInURI.java * @run testng/othervm * -Djdk.httpclient.HttpClient.log=reqeusts,headers @@ -58,6 +51,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; @@ -65,6 +60,8 @@ import org.testng.annotations.Test; import static java.lang.System.err; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.US_ASCII; import static java.net.http.HttpClient.Builder.NO_PROXY; import static org.testng.Assert.assertEquals; @@ -201,22 +198,19 @@ public void setup() throws Exception { throw new AssertionError("Unexpected null sslContext"); HttpTestHandler handler = new HttpUriStringHandler(); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(handler, "/http1"); httpURI = "http://" + serverAuthority(httpTestServer) + "/http1"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(handler, "/https1"); httpsURI = "https://" + serverAuthority(httpsTestServer) + "/https1"; - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(handler, "/http2"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(handler, "/https2"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2"; diff --git a/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileDownloadTest.java b/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileDownloadTest.java index f95beec3ddc..c2927987d4c 100644 --- a/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileDownloadTest.java +++ b/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileDownloadTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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,18 +26,17 @@ * @bug 8237470 * @summary Confirm HttpResponse.BodySubscribers#ofFileDownload(Path) * works only with the default file system - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * jdk.httpserver - * @library /test/lib ../http2/server - * @build Http2TestServer Http2TestServerConnection Http2TestExchange - * Http2Handler OutgoingPushPromise Queue - * @build jdk.test.lib.net.SimpleSSLContext - * @build jdk.test.lib.Platform - * @build jdk.test.lib.util.FileUtils - * @compile ../HttpServerAdapters.java + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.httpclient.test.lib.http2.Http2TestServerConnection + * jdk.httpclient.test.lib.http2.Http2TestExchange + * jdk.httpclient.test.lib.http2.Http2Handler + * jdk.httpclient.test.lib.http2.OutgoingPushPromise + * jdk.httpclient.test.lib.http2.Queue + * jdk.test.lib.net.SimpleSSLContext + * jdk.test.lib.Platform + * jdk.test.lib.util.FileUtils * @run testng/othervm BodyHandlerOfFileDownloadTest * @run testng/othervm/java.security.policy=ofFileDownload.policy BodyHandlerOfFileDownloadTest */ @@ -69,9 +68,17 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; - +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestServerConnection; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; +import jdk.httpclient.test.lib.http2.OutgoingPushPromise; +import jdk.httpclient.test.lib.http2.Queue; import static java.lang.System.out; import static java.net.http.HttpClient.Builder.NO_PROXY; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.file.StandardOpenOption.CREATE; import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING; import static java.nio.file.StandardOpenOption.WRITE; @@ -192,26 +199,19 @@ public void setup() throws Exception { zipFs = newZipFs(); zipFsPath = zipFsDir(zipFs); - InetSocketAddress sa = - new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - - httpTestServer = HttpServerAdapters.HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpServerAdapters.HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new HttpEchoHandler(), "/http1/echo"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/echo"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpServerAdapters.HttpTestServer.of(httpsServer); + httpsTestServer = HttpServerAdapters.HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(new HttpEchoHandler(), "/https1/echo"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/echo"; - http2TestServer = HttpServerAdapters.HttpTestServer.of( - new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpServerAdapters.HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new HttpEchoHandler(), "/http2/echo"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/echo"; - https2TestServer = HttpServerAdapters.HttpTestServer.of( - new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpServerAdapters.HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new HttpEchoHandler(), "/https2/echo"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/echo"; diff --git a/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileTest.java b/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileTest.java index 3535df14c7f..4bb529aaf74 100644 --- a/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileTest.java +++ b/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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,18 +27,16 @@ * @summary Confirm HttpResponse.BodyHandlers#ofFile(Path) * works with default and non-default file systems * when SecurityManager is enabled - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * jdk.httpserver - * @library /test/lib ../http2/server - * @build Http2TestServer Http2TestServerConnection Http2TestExchange - * Http2Handler OutgoingPushPromise Queue - * @build jdk.test.lib.net.SimpleSSLContext - * @build jdk.test.lib.Platform - * @build jdk.test.lib.util.FileUtils - * @compile ../HttpServerAdapters.java + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.httpclient.test.lib.http2.Http2TestServerConnection + * jdk.httpclient.test.lib.http2.Http2TestExchange + * jdk.httpclient.test.lib.http2.Http2Handler + * jdk.httpclient.test.lib.http2.OutgoingPushPromise + * jdk.httpclient.test.lib.http2.Queue + * jdk.test.lib.net.SimpleSSLContext + * jdk.test.lib.Platform jdk.test.lib.util.FileUtils * @run testng/othervm BodyHandlerOfFileTest * @run testng/othervm/java.security.policy=ofFile.policy BodyHandlerOfFileTest */ @@ -67,9 +65,17 @@ import java.nio.charset.StandardCharsets; import java.nio.file.*; import java.util.Map; - +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestServerConnection; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; +import jdk.httpclient.test.lib.http2.OutgoingPushPromise; +import jdk.httpclient.test.lib.http2.Queue; import static java.lang.System.out; import static java.net.http.HttpClient.Builder.NO_PROXY; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static org.testng.Assert.assertEquals; public class BodyHandlerOfFileTest implements HttpServerAdapters { @@ -199,26 +205,19 @@ public void setup() throws Exception { zipFs = newZipFs(); zipFsPath = zipFsFile(zipFs); - InetSocketAddress sa = - new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - - httpTestServer = HttpServerAdapters.HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpServerAdapters.HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new HttpEchoHandler(), "/http1/echo"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/echo"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpServerAdapters.HttpTestServer.of(httpsServer); + httpsTestServer = HttpServerAdapters.HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(new HttpEchoHandler(), "/https1/echo"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/echo"; - http2TestServer = HttpServerAdapters.HttpTestServer.of( - new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpServerAdapters.HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new HttpEchoHandler(), "/http2/echo"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/echo"; - https2TestServer = HttpServerAdapters.HttpTestServer.of( - new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpServerAdapters.HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new HttpEchoHandler(), "/https2/echo"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/echo"; diff --git a/test/jdk/java/net/httpclient/PathSubscriber/BodySubscriberOfFileTest.java b/test/jdk/java/net/httpclient/PathSubscriber/BodySubscriberOfFileTest.java index 7f361b8cf52..2868ca24796 100644 --- a/test/jdk/java/net/httpclient/PathSubscriber/BodySubscriberOfFileTest.java +++ b/test/jdk/java/net/httpclient/PathSubscriber/BodySubscriberOfFileTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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,18 +27,15 @@ * @summary Confirm HttpResponse.BodySubscribers#ofFile(Path) * works with default and non-default file systems * when SecurityManager is enabled - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * jdk.httpserver - * @library /test/lib ../http2/server - * @build Http2TestServer Http2TestServerConnection Http2TestExchange - * Http2Handler OutgoingPushPromise Queue - * @build jdk.test.lib.net.SimpleSSLContext - * @build jdk.test.lib.Platform - * @build jdk.test.lib.util.FileUtils - * @compile ../HttpServerAdapters.java + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.httpclient.test.lib.http2.Http2TestServerConnection + * jdk.httpclient.test.lib.http2.Http2TestExchange + * jdk.httpclient.test.lib.http2.Http2Handler + * jdk.httpclient.test.lib.http2.OutgoingPushPromise + * jdk.httpclient.test.lib.http2.Queue jdk.test.lib.net.SimpleSSLContext + * jdk.test.lib.Platform jdk.test.lib.util.FileUtils * @run testng/othervm BodySubscriberOfFileTest * @run testng/othervm/java.security.policy=ofFile.policy BodySubscriberOfFileTest */ @@ -75,9 +72,17 @@ import java.util.Map; import java.util.concurrent.Flow; import java.util.stream.IntStream; - +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestServerConnection; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; +import jdk.httpclient.test.lib.http2.OutgoingPushPromise; +import jdk.httpclient.test.lib.http2.Queue; import static java.lang.System.out; import static java.net.http.HttpClient.Builder.NO_PROXY; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static org.testng.Assert.assertEquals; public class BodySubscriberOfFileTest implements HttpServerAdapters { @@ -237,26 +242,19 @@ public void setup() throws Exception { zipFs = newZipFs(); zipFsPath = zipFsFile(zipFs); - InetSocketAddress sa = - new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - - httpTestServer = HttpServerAdapters.HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpServerAdapters.HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new HttpEchoHandler(), "/http1/echo"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/echo"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpServerAdapters.HttpTestServer.of(httpsServer); + httpsTestServer = HttpServerAdapters.HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(new HttpEchoHandler(), "/https1/echo"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/echo"; - http2TestServer = HttpServerAdapters.HttpTestServer.of( - new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpServerAdapters.HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new HttpEchoHandler(), "/http2/echo"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/echo"; - https2TestServer = HttpServerAdapters.HttpTestServer.of( - new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpServerAdapters.HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new HttpEchoHandler(), "/https2/echo"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/echo"; diff --git a/test/jdk/java/net/httpclient/PathSubscriber/ofFile.policy b/test/jdk/java/net/httpclient/PathSubscriber/ofFile.policy index c5df09ae865..cc6fe61814d 100644 --- a/test/jdk/java/net/httpclient/PathSubscriber/ofFile.policy +++ b/test/jdk/java/net/httpclient/PathSubscriber/ofFile.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2020, 2023, 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 @@ -38,26 +38,36 @@ grant codeBase "file:${test.classes}/../../../../../test/lib/-" { permission java.io.FilePermission "${user.dir}${/}defaultDir", "delete"; }; -// for java/net/httpclient/http2/server/* -grant codeBase "file:${test.classes}/../../../../../java/net/httpclient/http2/server/*" { +// for jdk/httpclient/test/lib/* classes +grant codeBase "file:${test.classes}/../../../../../test/jdk/java/net/httpclient/lib/-" { permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.common"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.frame"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack"; permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http"; - permission java.net.SocketPermission "localhost:*", "accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "accept,resolve"; permission java.lang.RuntimePermission "modifyThread"; }; grant codeBase "file:${test.classes}/*" { - permission java.net.URLPermission "http://localhost:*/http1/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/https1/echo", "POST"; - permission java.net.URLPermission "http://localhost:*/http2/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/https2/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/http1/echo", "GET"; - permission java.net.URLPermission "https://localhost:*/https1/echo", "GET"; - permission java.net.URLPermission "http://localhost:*/http2/echo", "GET"; - permission java.net.URLPermission "https://localhost:*/https2/echo", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/http1/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "POST"; + permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/http1/echo", "GET"; + permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "GET"; + permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "GET"; + // ipv6 + permission java.net.URLPermission "http://[::1]:*/http1/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/https1/echo", "POST"; + permission java.net.URLPermission "http://[::1]:*/http2/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/https2/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/http1/echo", "GET"; + permission java.net.URLPermission "https://[::1]:*/https1/echo", "GET"; + permission java.net.URLPermission "http://[::1]:*/http2/echo", "GET"; + permission java.net.URLPermission "https://[::1]:*/https2/echo", "GET"; // file permissions for test files permission java.io.FilePermission "${user.dir}${/}defaultFile.txt", "read,write,delete"; @@ -77,7 +87,8 @@ grant codeBase "file:${test.classes}/*" { permission java.util.logging.LoggingPermission "control"; // needed to grant the HTTP servers - permission java.net.SocketPermission "localhost:*", "accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "accept,resolve"; permission java.util.PropertyPermission "*", "read"; permission java.lang.RuntimePermission "modifyThread"; diff --git a/test/jdk/java/net/httpclient/PathSubscriber/ofFileDownload.policy b/test/jdk/java/net/httpclient/PathSubscriber/ofFileDownload.policy index a9dc8816241..e211981f78e 100644 --- a/test/jdk/java/net/httpclient/PathSubscriber/ofFileDownload.policy +++ b/test/jdk/java/net/httpclient/PathSubscriber/ofFileDownload.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2020, 2023, 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 @@ -38,26 +38,36 @@ grant codeBase "file:${test.classes}/../../../../../test/lib/-" { permission java.io.FilePermission "${user.dir}${/}defaultDir/*", "read,delete"; }; -// for java/net/httpclient/http2/server/* -grant codeBase "file:${test.classes}/../../../../../java/net/httpclient/http2/server/*" { +// for jdk/httpclient/test/lib/* classes +grant codeBase "file:${test.classes}/../../../../../test/jdk/java/net/httpclient/lib/-" { permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.common"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.frame"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack"; permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http"; - permission java.net.SocketPermission "localhost:*", "accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "accept,resolve"; permission java.lang.RuntimePermission "modifyThread"; }; grant codeBase "file:${test.classes}/*" { - permission java.net.URLPermission "http://localhost:*/http1/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/https1/echo", "POST"; - permission java.net.URLPermission "http://localhost:*/http2/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/https2/echo", "POST"; - permission java.net.URLPermission "https://localhost:*/http1/echo", "GET"; - permission java.net.URLPermission "https://localhost:*/https1/echo", "GET"; - permission java.net.URLPermission "http://localhost:*/http2/echo", "GET"; - permission java.net.URLPermission "https://localhost:*/https2/echo", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/http1/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "POST"; + permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/http1/echo", "GET"; + permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "GET"; + permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "GET"; + // ipv6 + permission java.net.URLPermission "http://[::1]:*/http1/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/https1/echo", "POST"; + permission java.net.URLPermission "http://[::1]:*/http2/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/https2/echo", "POST"; + permission java.net.URLPermission "https://[::1]:*/http1/echo", "GET"; + permission java.net.URLPermission "https://[::1]:*/https1/echo", "GET"; + permission java.net.URLPermission "http://[::1]:*/http2/echo", "GET"; + permission java.net.URLPermission "https://[::1]:*/https2/echo", "GET"; // file permissions for test files permission java.io.FilePermission "${user.dir}${/}file.zip", "read,write"; @@ -74,7 +84,8 @@ grant codeBase "file:${test.classes}/*" { permission java.util.logging.LoggingPermission "control"; // needed to grant the HTTP servers - permission java.net.SocketPermission "localhost:*", "accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "accept,resolve"; permission java.util.PropertyPermission "*", "read"; permission java.lang.RuntimePermission "modifyThread"; diff --git a/test/jdk/java/net/httpclient/ProxyAuthDisabledSchemes.java b/test/jdk/java/net/httpclient/ProxyAuthDisabledSchemes.java index 4de6a295a96..5776e240ba8 100644 --- a/test/jdk/java/net/httpclient/ProxyAuthDisabledSchemes.java +++ b/test/jdk/java/net/httpclient/ProxyAuthDisabledSchemes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -28,16 +28,10 @@ * it verifies that the client honor the jdk.http.auth.*.disabledSchemes * net properties. * @bug 8087112 - * @library /test/lib http2/server + * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext DigestEchoServer DigestEchoClient * ReferenceTracker ProxyAuthDisabledSchemes - * @modules java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * java.base/sun.net.www.http - * java.base/sun.net.www - * java.base/sun.net + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run main/othervm -Djdk.http.auth.proxying.disabledSchemes=Basic,Digest * -Djdk.http.auth.tunneling.disabledSchemes=Digest,Basic * ProxyAuthDisabledSchemes diff --git a/test/jdk/java/net/httpclient/ProxyAuthDisabledSchemesSSL.java b/test/jdk/java/net/httpclient/ProxyAuthDisabledSchemesSSL.java index e9bb6f8d98f..f0eb63f2a40 100644 --- a/test/jdk/java/net/httpclient/ProxyAuthDisabledSchemesSSL.java +++ b/test/jdk/java/net/httpclient/ProxyAuthDisabledSchemesSSL.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -28,16 +28,10 @@ * headers directly when connecting with a server over SSL, and * it verifies that the client honor the jdk.http.auth.*.disabledSchemes * net properties. - * @library /test/lib http2/server + * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext DigestEchoServer DigestEchoClient * ReferenceTracker ProxyAuthDisabledSchemesSSL - * @modules java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * java.base/sun.net.www.http - * java.base/sun.net.www - * java.base/sun.net + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run main/othervm/timeout=300 * -Djdk.http.auth.proxying.disabledSchemes=Basic,Digest * -Djdk.http.auth.tunneling.disabledSchemes=Digest,Basic diff --git a/test/jdk/java/net/httpclient/ProxySelectorTest.java b/test/jdk/java/net/httpclient/ProxySelectorTest.java index 7b4a3c8ed43..bb3ddc84017 100644 --- a/test/jdk/java/net/httpclient/ProxySelectorTest.java +++ b/test/jdk/java/net/httpclient/ProxySelectorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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,18 +26,9 @@ * @bug 8244205 * @summary checks that a different proxy returned for * the same host:port is taken into account - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * java.base/sun.net.www.http - * java.base/sun.net.www - * java.base/sun.net - * @library /test/lib http2/server - * @build HttpServerAdapters DigestEchoServer Http2TestServer ProxySelectorTest - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build DigestEchoServer ProxySelectorTest jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.test.lib.net.SimpleSSLContext * @run testng/othervm * -Djdk.http.auth.tunneling.disabledSchemes * -Djdk.httpclient.HttpClient.log=headers,requests @@ -83,9 +74,13 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.err; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; @@ -216,13 +211,13 @@ enum Schemes { @DataProvider(name = "all") public Object[][] positive() { return new Object[][] { - { Schemes.HTTP, HttpClient.Version.HTTP_1_1, httpURI, true}, + { Schemes.HTTP, HTTP_1_1, httpURI, true}, { Schemes.HTTP, HttpClient.Version.HTTP_2, http2URI, true}, - { Schemes.HTTPS, HttpClient.Version.HTTP_1_1, httpsURI, true}, + { Schemes.HTTPS, HTTP_1_1, httpsURI, true}, { Schemes.HTTPS, HttpClient.Version.HTTP_2, https2URI, true}, - { Schemes.HTTP, HttpClient.Version.HTTP_1_1, httpURI, false}, + { Schemes.HTTP, HTTP_1_1, httpURI, false}, { Schemes.HTTP, HttpClient.Version.HTTP_2, http2URI, false}, - { Schemes.HTTPS, HttpClient.Version.HTTP_1_1, httpsURI, false}, + { Schemes.HTTPS, HTTP_1_1, httpsURI, false}, { Schemes.HTTPS, HttpClient.Version.HTTP_2, https2URI, false}, }; } @@ -329,30 +324,26 @@ public void setup() throws Exception { if (sslContext == null) throw new AssertionError("Unexpected null sslContext"); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new PlainServerHandler("plain-server"), "/http1/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1"; - proxyHttpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + proxyHttpTestServer = HttpTestServer.create(HTTP_1_1); proxyHttpTestServer.addHandler(new PlainServerHandler("proxy-server"), "/http1/proxy/"); proxyHttpTestServer.addHandler(new PlainServerHandler("proxy-server"), "/http2/proxy/"); proxyHttpURI = "http://" + httpTestServer.serverAuthority() + "/http1"; - authProxyHttpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + authProxyHttpTestServer = HttpTestServer.create(HTTP_1_1); authProxyHttpTestServer.addHandler(new UnauthorizedHandler("auth-proxy-server"), "/http1/proxy/"); authProxyHttpTestServer.addHandler(new UnauthorizedHandler("auth-proxy-server"), "/http2/proxy/"); proxyHttpURI = "http://" + httpTestServer.serverAuthority() + "/http1"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(new PlainServerHandler("https-server"),"/https1/"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1"; - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new PlainServerHandler("plain-server"), "/http2/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new PlainServerHandler("https-server"), "/https2/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2"; diff --git a/test/jdk/java/net/httpclient/ProxyTest.java b/test/jdk/java/net/httpclient/ProxyTest.java index aa2faeff327..8763e168a06 100644 --- a/test/jdk/java/net/httpclient/ProxyTest.java +++ b/test/jdk/java/net/httpclient/ProxyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -256,13 +256,14 @@ private synchronized Thread pipe(InputStream is, OutputStream os, public void run() { try { try { - int c; - while ((c = is.read()) != -1) { - os.write(c); + int len; + byte[] buf = new byte[16 * 1024]; + while ((len = is.read(buf)) != -1) { + os.write(buf, 0, len); os.flush(); // if DEBUG prints a + or a - for each transferred // character. - if (DEBUG) System.out.print(tag); + if (DEBUG) System.out.print(String.valueOf(tag).repeat(len)); } is.close(); } finally { diff --git a/test/jdk/java/net/httpclient/RedirectMethodChange.java b/test/jdk/java/net/httpclient/RedirectMethodChange.java index c5d4aef8676..7e5971c4002 100644 --- a/test/jdk/java/net/httpclient/RedirectMethodChange.java +++ b/test/jdk/java/net/httpclient/RedirectMethodChange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,14 +24,8 @@ /* * @test * @summary Method change during redirection - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext * @run testng/othervm RedirectMethodChange */ @@ -50,11 +44,15 @@ import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.US_ASCII; import static org.testng.Assert.assertEquals; @@ -190,29 +188,25 @@ public void setup() throws Exception { .sslContext(sslContext) .build(); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); String targetURI = "http://" + httpTestServer.serverAuthority() + "/http1/redirect/rmt"; RedirMethodChgeHandler handler = new RedirMethodChgeHandler(targetURI); httpTestServer.addHandler(handler, "/http1/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/test/rmt"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); targetURI = "https://" + httpsTestServer.serverAuthority() + "/https1/redirect/rmt"; handler = new RedirMethodChgeHandler(targetURI); httpsTestServer.addHandler(handler,"/https1/"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/test/rmt"; - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); targetURI = "http://" + http2TestServer.serverAuthority() + "/http2/redirect/rmt"; handler = new RedirMethodChgeHandler(targetURI); http2TestServer.addHandler(handler, "/http2/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/test/rmt"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); targetURI = "https://" + https2TestServer.serverAuthority() + "/https2/redirect/rmt"; handler = new RedirMethodChgeHandler(targetURI); https2TestServer.addHandler(handler, "/https2/"); diff --git a/test/jdk/java/net/httpclient/RedirectWithCookie.java b/test/jdk/java/net/httpclient/RedirectWithCookie.java index 14d971b9165..13dfe766647 100644 --- a/test/jdk/java/net/httpclient/RedirectWithCookie.java +++ b/test/jdk/java/net/httpclient/RedirectWithCookie.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,15 +24,8 @@ /* * @test * @summary Test for cookie handling when redirecting - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext * @run testng/othervm * -Djdk.httpclient.HttpClient.log=trace,headers,requests * RedirectWithCookie @@ -55,12 +48,16 @@ import java.net.http.HttpResponse.BodyHandlers; import java.util.List; import javax.net.ssl.SSLContext; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -153,21 +150,17 @@ public void setup() throws Exception { if (sslContext == null) throw new AssertionError("Unexpected null sslContext"); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new CookieRedirectHandler(), "/http1/cookie/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/cookie/redirect"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(new CookieRedirectHandler(),"/https1/cookie/"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/cookie/redirect"; - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new CookieRedirectHandler(), "/http2/cookie/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/cookie/redirect"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new CookieRedirectHandler(), "/https2/cookie/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/cookie/redirect"; diff --git a/test/jdk/java/net/httpclient/RequestBodyTest.java b/test/jdk/java/net/httpclient/RequestBodyTest.java index b323efd86e5..805a5b490db 100644 --- a/test/jdk/java/net/httpclient/RequestBodyTest.java +++ b/test/jdk/java/net/httpclient/RequestBodyTest.java @@ -21,24 +21,6 @@ * questions. */ -/* - * @test - * @bug 8087112 - * @modules java.net.http - * java.logging - * jdk.httpserver - * @library /test/lib - * @compile ../../../com/sun/net/httpserver/LogFilter.java - * @compile ../../../com/sun/net/httpserver/EchoHandler.java - * @compile ../../../com/sun/net/httpserver/FileServerHandler.java - * @build jdk.test.lib.net.SimpleSSLContext - * @build LightWeightHttpServer - * @build jdk.test.lib.Platform - * @build jdk.test.lib.util.FileUtils - * @run testng/othervm RequestBodyTest - * @run testng/othervm/java.security.policy=RequestBodyTest.policy RequestBodyTest - */ - import java.io.*; import java.net.URI; import java.net.http.HttpClient; @@ -74,6 +56,23 @@ import org.testng.annotations.Test; import static org.testng.Assert.*; +/* + * @test + * @bug 8087112 + * @modules java.net.http + * java.logging + * jdk.httpserver + * @library /test/lib + * @compile ../../../com/sun/net/httpserver/LogFilter.java + * @compile ../../../com/sun/net/httpserver/EchoHandler.java + * @compile ../../../com/sun/net/httpserver/FileServerHandler.java + * @build jdk.test.lib.net.SimpleSSLContext + * @build LightWeightHttpServer + * @build jdk.test.lib.Platform + * @build jdk.test.lib.util.FileUtils + * @run testng/othervm RequestBodyTest + * @run testng/othervm/java.security.policy=RequestBodyTest.policy RequestBodyTest + */ public class RequestBodyTest { static final String fileroot = System.getProperty("test.src", ".") + "/docs"; diff --git a/test/jdk/java/net/httpclient/RequestBodyTest.policy b/test/jdk/java/net/httpclient/RequestBodyTest.policy index d3797cf472d..0bfedf22b84 100644 --- a/test/jdk/java/net/httpclient/RequestBodyTest.policy +++ b/test/jdk/java/net/httpclient/RequestBodyTest.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2018, 2023, 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 @@ -38,14 +38,17 @@ grant codeBase "file:${test.classes}/*" { permission java.io.FilePermission "${test.src}${/}docs${/}files${/}notsobigfile.txt", "read"; permission java.io.FilePermission "RequestBodyTest.tmp", "read,write,delete"; - permission java.net.URLPermission "http://localhost:*/echo/foo", "POST"; - permission java.net.URLPermission "https://localhost:*/echo/foo", "POST"; + permission java.net.URLPermission "http://127.0.0.1:*/echo/foo", "POST"; + permission java.net.URLPermission "https://127.0.0.1:*/echo/foo", "POST"; + permission java.net.URLPermission "http://[::1]:*/echo/foo", "POST"; + permission java.net.URLPermission "https://[::1]:*/echo/foo", "POST"; // for HTTP/1.1 server logging permission java.util.logging.LoggingPermission "control"; // needed to grant the HTTP server - permission java.net.SocketPermission "localhost:*", "accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "accept,resolve"; permission java.util.PropertyPermission "*", "read"; permission java.lang.RuntimePermission "modifyThread"; diff --git a/test/jdk/java/net/httpclient/Response204V2Test.java b/test/jdk/java/net/httpclient/Response204V2Test.java index 869fe7da78c..610c312b667 100644 --- a/test/jdk/java/net/httpclient/Response204V2Test.java +++ b/test/jdk/java/net/httpclient/Response204V2Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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,13 +24,9 @@ /* * @test * @bug 8238270 - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker Response204V2Test - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=requests,responses,errors * Response204V2Test @@ -57,6 +53,8 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.test.lib.net.SimpleSSLContext; import org.testng.ITestContext; @@ -72,6 +70,7 @@ import javax.net.ssl.SSLContext; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_2; public class Response204V2Test implements HttpServerAdapters { @@ -272,11 +271,11 @@ public void setup() throws Exception { // HTTP/2 HttpTestHandler handler204 = new Handler204(); - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(handler204, "/http2/test204/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/test204/x"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(handler204, "/https2/test204/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/test204/x"; diff --git a/test/jdk/java/net/httpclient/ResponsePublisher.java b/test/jdk/java/net/httpclient/ResponsePublisher.java index 862b6c18043..b74329e1360 100644 --- a/test/jdk/java/net/httpclient/ResponsePublisher.java +++ b/test/jdk/java/net/httpclient/ResponsePublisher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,12 +26,8 @@ * @bug 8201186 * @summary Tests an asynchronous BodySubscriber that completes * immediately with a Publisher> - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm ResponsePublisher */ @@ -73,8 +69,12 @@ import java.util.concurrent.Flow.Publisher; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; @@ -401,16 +401,13 @@ public void setup() throws Exception { // HTTP/1.1 HttpTestHandler h1_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h1_chunkHandler = new HTTP_VariableLengthHandler(); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler( h1_fixedLengthHandler, "/http1/fixed"); httpTestServer.addHandler(h1_chunkHandler,"/http1/chunk"); httpURI_fixed = "http://" + httpTestServer.serverAuthority() + "/http1/fixed"; httpURI_chunk = "http://" + httpTestServer.serverAuthority() + "/http1/chunk"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(h1_fixedLengthHandler, "/https1/fixed"); httpsTestServer.addHandler(h1_chunkHandler, "/https1/chunk"); httpsURI_fixed = "https://" + httpsTestServer.serverAuthority() + "/https1/fixed"; @@ -420,13 +417,13 @@ public void setup() throws Exception { HttpTestHandler h2_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h2_chunkedHandler = new HTTP_VariableLengthHandler(); - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(h2_fixedLengthHandler, "/http2/fixed"); http2TestServer.addHandler(h2_chunkedHandler, "/http2/chunk"); http2URI_fixed = "http://" + http2TestServer.serverAuthority() + "/http2/fixed"; http2URI_chunk = "http://" + http2TestServer.serverAuthority() + "/http2/chunk"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(h2_fixedLengthHandler, "/https2/fixed"); https2TestServer.addHandler(h2_chunkedHandler, "/https2/chunk"); https2URI_fixed = "https://" + https2TestServer.serverAuthority() + "/https2/fixed"; diff --git a/test/jdk/java/net/httpclient/RetryWithCookie.java b/test/jdk/java/net/httpclient/RetryWithCookie.java index 9e7442412b7..ec83fa5df89 100644 --- a/test/jdk/java/net/httpclient/RetryWithCookie.java +++ b/test/jdk/java/net/httpclient/RetryWithCookie.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,15 +25,10 @@ * @test * @bug 8199943 * @summary Test for cookie handling when retrying after close - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext ReferenceTracker + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker * @run testng/othervm * -Djdk.httpclient.HttpClient.log=trace,headers,requests * RetryWithCookie @@ -67,9 +62,13 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.out; import static java.net.http.HttpClient.Builder.NO_PROXY; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -151,21 +150,17 @@ public void setup() throws Exception { if (sslContext == null) throw new AssertionError("Unexpected null sslContext"); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new CookieRetryHandler(), "/http1/cookie/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/cookie/retry"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(new CookieRetryHandler(),"/https1/cookie/"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/cookie/retry"; - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new CookieRetryHandler(), "/http2/cookie/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/cookie/retry"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new CookieRetryHandler(), "/https2/cookie/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/cookie/retry"; @@ -211,7 +206,7 @@ public void handle(HttpTestExchange t) throws IOException { String uuid = uuids.get(0); // retrying if (closedRequests.putIfAbsent(uuid, t.getRequestURI().toString()) == null) { - if (t.getExchangeVersion() == HttpClient.Version.HTTP_1_1) { + if (t.getExchangeVersion() == HTTP_1_1) { // Throwing an exception here only causes a retry // with HTTP_1_1 - where it forces the server to close // the connection. diff --git a/test/jdk/java/net/httpclient/ServerCloseTest.java b/test/jdk/java/net/httpclient/ServerCloseTest.java index ac169fae68b..10fb8ca94d1 100644 --- a/test/jdk/java/net/httpclient/ServerCloseTest.java +++ b/test/jdk/java/net/httpclient/ServerCloseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,12 +25,9 @@ * @test * @summary Tests that our client deals correctly with servers that * close the connection right after sending the last byte. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters EncodedCharsInURI - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.tls.acknowledgeCloseNotify=true ServerCloseTest */ //* -Djdk.internal.httpclient.debug=true @@ -72,6 +69,8 @@ import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicLong; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.out; import static java.nio.charset.StandardCharsets.UTF_8; diff --git a/test/jdk/java/net/httpclient/SpecialHeadersTest.java b/test/jdk/java/net/httpclient/SpecialHeadersTest.java index da9e9648a32..4f6e5ad2b54 100644 --- a/test/jdk/java/net/httpclient/SpecialHeadersTest.java +++ b/test/jdk/java/net/httpclient/SpecialHeadersTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,15 +26,10 @@ * @summary Verify that some special headers - such as User-Agent * can be specified by the caller. * @bug 8203771 8218546 - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer HttpServerAdapters SpecialHeadersTest - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.test.lib.net.SimpleSSLContext * @requires (vm.compMode != "Xcomp") * @run testng/othervm * -Djdk.httpclient.HttpClient.log=requests,headers,errors @@ -88,10 +83,13 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.stream.Collectors; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.err; import static java.lang.System.out; import static java.net.http.HttpClient.Builder.NO_PROXY; +import static java.net.http.HttpClient.Version.HTTP_1_1; import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.US_ASCII; import org.testng.Assert; @@ -523,22 +521,19 @@ public void setup() throws Exception { throw new AssertionError("Unexpected null sslContext"); HttpTestHandler handler = new HttpUriStringHandler(); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(handler, "/http1"); httpURI = "http://" + serverAuthority(httpTestServer) + "/http1"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(handler, "/https1"); httpsURI = "https://" + serverAuthority(httpsTestServer) + "/https1"; - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(handler, "/http2"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(handler, "/https2"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2"; diff --git a/test/jdk/java/net/httpclient/StreamCloseTest.java b/test/jdk/java/net/httpclient/StreamCloseTest.java index d42fb0bb05c..2d00a539e80 100644 --- a/test/jdk/java/net/httpclient/StreamCloseTest.java +++ b/test/jdk/java/net/httpclient/StreamCloseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, NTT DATA. * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -26,14 +26,9 @@ /* * @test * @bug 8257736 - * @modules java.net.http - * java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * @library http2/server - * @build Http2TestServer Http2TestExchange - * @compile HttpServerAdapters.java + * @library /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.httpclient.test.lib.http2.Http2TestServer * @run testng/othervm StreamCloseTest */ @@ -50,6 +45,8 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.URI; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; @@ -91,8 +88,7 @@ public void close() throws IOException { @BeforeTest public void setup() throws Exception { - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpServerAdapters.HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpServerAdapters.HttpTestServer.create(Version.HTTP_1_1); httpTestServer.addHandler(new HttpServerAdapters.HttpTestEchoHandler(), "/"); URI uri = URI.create("http://" + httpTestServer.serverAuthority() + "/"); httpTestServer.start(); diff --git a/test/jdk/java/net/httpclient/StreamingBody.java b/test/jdk/java/net/httpclient/StreamingBody.java index 9572d14a81c..7943968d239 100644 --- a/test/jdk/java/net/httpclient/StreamingBody.java +++ b/test/jdk/java/net/httpclient/StreamingBody.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,15 +25,8 @@ * @test * @summary Exercise a streaming subscriber ( InputStream ) without holding a * strong (or any ) reference to the client. - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext * @run testng/othervm * -Djdk.httpclient.HttpClient.log=trace,headers,requests * StreamingBody @@ -53,12 +46,16 @@ import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import javax.net.ssl.SSLContext; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static java.net.http.HttpClient.Builder.NO_PROXY; import static org.testng.Assert.assertEquals; @@ -121,22 +118,18 @@ public void setup() throws Exception { if (sslContext == null) throw new AssertionError("Unexpected null sslContext"); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new MessageHandler(), "/http1/streamingbody/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/streamingbody/w"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(new MessageHandler(),"/https1/streamingbody/"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/streamingbody/x"; - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new MessageHandler(), "/http2/streamingbody/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/streamingbody/y"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new MessageHandler(), "/https2/streamingbody/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/streamingbody/z"; diff --git a/test/jdk/java/net/httpclient/TEST.properties b/test/jdk/java/net/httpclient/TEST.properties index 132f8f4012c..654acd91c83 100644 --- a/test/jdk/java/net/httpclient/TEST.properties +++ b/test/jdk/java/net/httpclient/TEST.properties @@ -1 +1,8 @@ -modules = java.net.http +modules=java.base/sun.net.www.http \ + java.base/sun.net.www \ + java.base/sun.net \ + java.net.http/jdk.internal.net.http.common \ + java.net.http/jdk.internal.net.http.frame \ + java.net.http/jdk.internal.net.http.hpack \ + java.logging \ + jdk.httpserver diff --git a/test/jdk/java/net/httpclient/ThrowingPublishersCustomAfterCancel.java b/test/jdk/java/net/httpclient/ThrowingPublishersCustomAfterCancel.java index 318b4622b50..796c0b8df02 100644 --- a/test/jdk/java/net/httpclient/ThrowingPublishersCustomAfterCancel.java +++ b/test/jdk/java/net/httpclient/ThrowingPublishersCustomAfterCancel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +25,10 @@ * @test * @summary Tests what happens when request publishers * throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext * ReferenceTracker AbstractThrowingPublishers ThrowingPublishersCustomAfterCancel - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.enableAllMethodRetry=true * ThrowingPublishersCustomAfterCancel diff --git a/test/jdk/java/net/httpclient/ThrowingPublishersCustomBeforeCancel.java b/test/jdk/java/net/httpclient/ThrowingPublishersCustomBeforeCancel.java index aaf05ee2a55..06343d222b8 100644 --- a/test/jdk/java/net/httpclient/ThrowingPublishersCustomBeforeCancel.java +++ b/test/jdk/java/net/httpclient/ThrowingPublishersCustomBeforeCancel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +25,10 @@ * @test * @summary Tests what happens when request publishers * throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext * ReferenceTracker AbstractThrowingPublishers ThrowingPublishersCustomBeforeCancel - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.enableAllMethodRetry=true * ThrowingPublishersCustomBeforeCancel diff --git a/test/jdk/java/net/httpclient/ThrowingPublishersIOAfterCancel.java b/test/jdk/java/net/httpclient/ThrowingPublishersIOAfterCancel.java index 4af4827bdd3..7ed649b2546 100644 --- a/test/jdk/java/net/httpclient/ThrowingPublishersIOAfterCancel.java +++ b/test/jdk/java/net/httpclient/ThrowingPublishersIOAfterCancel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +25,10 @@ * @test * @summary Tests what happens when request publishers * throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext * ReferenceTracker AbstractThrowingPublishers ThrowingPublishersIOAfterCancel - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.enableAllMethodRetry=true * ThrowingPublishersIOAfterCancel diff --git a/test/jdk/java/net/httpclient/ThrowingPublishersIOBeforeCancel.java b/test/jdk/java/net/httpclient/ThrowingPublishersIOBeforeCancel.java index 63c36072509..3be2eb061cc 100644 --- a/test/jdk/java/net/httpclient/ThrowingPublishersIOBeforeCancel.java +++ b/test/jdk/java/net/httpclient/ThrowingPublishersIOBeforeCancel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +25,10 @@ * @test * @summary Tests what happens when request publishers * throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext * ReferenceTracker AbstractThrowingPublishers ThrowingPublishersIOBeforeCancel - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.enableAllMethodRetry=true * ThrowingPublishersIOBeforeCancel diff --git a/test/jdk/java/net/httpclient/ThrowingPublishersInNextRequest.java b/test/jdk/java/net/httpclient/ThrowingPublishersInNextRequest.java index 7ffc09da042..eb07b359fc9 100644 --- a/test/jdk/java/net/httpclient/ThrowingPublishersInNextRequest.java +++ b/test/jdk/java/net/httpclient/ThrowingPublishersInNextRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +25,10 @@ * @test * @summary Tests what happens when request publishers * throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext * ReferenceTracker AbstractThrowingPublishers ThrowingPublishersInNextRequest - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.enableAllMethodRetry=true * ThrowingPublishersInNextRequest diff --git a/test/jdk/java/net/httpclient/ThrowingPublishersInRequest.java b/test/jdk/java/net/httpclient/ThrowingPublishersInRequest.java index 60e0e2aa147..ef05e4e0da6 100644 --- a/test/jdk/java/net/httpclient/ThrowingPublishersInRequest.java +++ b/test/jdk/java/net/httpclient/ThrowingPublishersInRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +25,10 @@ * @test * @summary Tests what happens when request publishers * throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext * ReferenceTracker AbstractThrowingPublishers ThrowingPublishersInRequest - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.enableAllMethodRetry=true * ThrowingPublishersInRequest diff --git a/test/jdk/java/net/httpclient/ThrowingPublishersInSubscribe.java b/test/jdk/java/net/httpclient/ThrowingPublishersInSubscribe.java index 5b1dd9d36ff..f14c5167024 100644 --- a/test/jdk/java/net/httpclient/ThrowingPublishersInSubscribe.java +++ b/test/jdk/java/net/httpclient/ThrowingPublishersInSubscribe.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +25,10 @@ * @test * @summary Tests what happens when request publishers * throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext * ReferenceTracker AbstractThrowingPublishers ThrowingPublishersInSubscribe - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.enableAllMethodRetry=true * ThrowingPublishersInSubscribe diff --git a/test/jdk/java/net/httpclient/ThrowingPublishersSanity.java b/test/jdk/java/net/httpclient/ThrowingPublishersSanity.java index 48f6fc913d3..30549083310 100644 --- a/test/jdk/java/net/httpclient/ThrowingPublishersSanity.java +++ b/test/jdk/java/net/httpclient/ThrowingPublishersSanity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +25,10 @@ * @test * @summary Tests what happens when request publishers * throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext * ReferenceTracker AbstractThrowingPublishers ThrowingPublishersSanity - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.enableAllMethodRetry=true * ThrowingPublishersSanity diff --git a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamCustom.java b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamCustom.java index 95671d6a3ff..0b66a8e913e 100644 --- a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamCustom.java +++ b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamCustom.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +26,10 @@ * @bug 8229822 * @summary Tests what happens when push promise handlers and their * response body handlers and subscribers throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsInputStreamCustom - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsInputStreamCustom + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsInputStreamCustom */ diff --git a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamIO.java b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamIO.java index 7f22bdf4961..89cf1162bc3 100644 --- a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamIO.java +++ b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamIO.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +26,10 @@ * @bug 8229822 * @summary Tests what happens when push promise handlers and their * response body handlers and subscribers throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsInputStreamIO - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsInputStreamIO + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsInputStreamIO */ diff --git a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesCustom.java b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesCustom.java index e17a72a21dc..d1fb7d34258 100644 --- a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesCustom.java +++ b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesCustom.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +26,10 @@ * @bug 8229822 * @summary Tests what happens when push promise handlers and their * response body handlers and subscribers throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsLinesCustom - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsLinesCustom + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsLinesCustom */ diff --git a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesIO.java b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesIO.java index 678a58530c1..88afaf3dbd5 100644 --- a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesIO.java +++ b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesIO.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +26,10 @@ * @bug 8229822 * @summary Tests what happens when push promise handlers and their * response body handlers and subscribers throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsLinesIO - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsLinesIO + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsLinesIO */ diff --git a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringCustom.java b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringCustom.java index be94c2fa4ff..c40af0ab0b0 100644 --- a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringCustom.java +++ b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringCustom.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +26,10 @@ * @bug 8229822 * @summary Tests what happens when push promise handlers and their * response body handlers and subscribers throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsStringCustom - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsStringCustom + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsStringCustom */ diff --git a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringIO.java b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringIO.java index a7120964869..6485e82af8f 100644 --- a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringIO.java +++ b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringIO.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +26,10 @@ * @bug 8229822 * @summary Tests what happens when push promise handlers and their * response body handlers and subscribers throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsStringIO - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsStringIO + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsStringIO */ diff --git a/test/jdk/java/net/httpclient/ThrowingPushPromisesSanity.java b/test/jdk/java/net/httpclient/ThrowingPushPromisesSanity.java index d064c322599..7fdb6dcb19d 100644 --- a/test/jdk/java/net/httpclient/ThrowingPushPromisesSanity.java +++ b/test/jdk/java/net/httpclient/ThrowingPushPromisesSanity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +26,10 @@ * @bug 8229822 * @summary Tests what happens when push promise handlers and their * response body handlers and subscribers throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesSanity - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesSanity + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesSanity */ diff --git a/test/jdk/java/net/httpclient/ThrowingSubscribersAsInputStream.java b/test/jdk/java/net/httpclient/ThrowingSubscribersAsInputStream.java index eb2636f3159..35ac1fd3f9c 100644 --- a/test/jdk/java/net/httpclient/ThrowingSubscribersAsInputStream.java +++ b/test/jdk/java/net/httpclient/ThrowingSubscribersAsInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +25,10 @@ * @test * @summary Tests what happens when response body handlers and subscribers * throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker ThrowingSubscribersAsInputStream AbstractThrowingSubscribers - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker ThrowingSubscribersAsInputStream AbstractThrowingSubscribers + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingSubscribersAsInputStream */ diff --git a/test/jdk/java/net/httpclient/ThrowingSubscribersAsInputStreamAsync.java b/test/jdk/java/net/httpclient/ThrowingSubscribersAsInputStreamAsync.java index 98baae29ec2..db25ebaca3e 100644 --- a/test/jdk/java/net/httpclient/ThrowingSubscribersAsInputStreamAsync.java +++ b/test/jdk/java/net/httpclient/ThrowingSubscribersAsInputStreamAsync.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +25,10 @@ * @test * @summary Tests what happens when response body handlers and subscribers * throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker ThrowingSubscribersAsInputStreamAsync AbstractThrowingSubscribers - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker ThrowingSubscribersAsInputStreamAsync AbstractThrowingSubscribers + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingSubscribersAsInputStreamAsync */ diff --git a/test/jdk/java/net/httpclient/ThrowingSubscribersAsLines.java b/test/jdk/java/net/httpclient/ThrowingSubscribersAsLines.java index eccdf54f398..f303ef12b54 100644 --- a/test/jdk/java/net/httpclient/ThrowingSubscribersAsLines.java +++ b/test/jdk/java/net/httpclient/ThrowingSubscribersAsLines.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +25,10 @@ * @test * @summary Tests what happens when response body handlers and subscribers * throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker ThrowingSubscribersAsLines AbstractThrowingSubscribers - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker ThrowingSubscribersAsLines AbstractThrowingSubscribers + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingSubscribersAsLines */ diff --git a/test/jdk/java/net/httpclient/ThrowingSubscribersAsLinesAsync.java b/test/jdk/java/net/httpclient/ThrowingSubscribersAsLinesAsync.java index ba3583244b6..2e1fc942a73 100644 --- a/test/jdk/java/net/httpclient/ThrowingSubscribersAsLinesAsync.java +++ b/test/jdk/java/net/httpclient/ThrowingSubscribersAsLinesAsync.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +25,10 @@ * @test * @summary Tests what happens when response body handlers and subscribers * throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker ThrowingSubscribersAsLinesAsync AbstractThrowingSubscribers - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker ThrowingSubscribersAsLinesAsync AbstractThrowingSubscribers + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingSubscribersAsLinesAsync */ diff --git a/test/jdk/java/net/httpclient/ThrowingSubscribersAsString.java b/test/jdk/java/net/httpclient/ThrowingSubscribersAsString.java index 43ec0756842..56e444f09c2 100644 --- a/test/jdk/java/net/httpclient/ThrowingSubscribersAsString.java +++ b/test/jdk/java/net/httpclient/ThrowingSubscribersAsString.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +25,10 @@ * @test * @summary Tests what happens when response body handlers and subscribers * throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker ThrowingSubscribersAsString AbstractThrowingSubscribers - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker ThrowingSubscribersAsString AbstractThrowingSubscribers + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingSubscribersAsString */ diff --git a/test/jdk/java/net/httpclient/ThrowingSubscribersAsStringAsync.java b/test/jdk/java/net/httpclient/ThrowingSubscribersAsStringAsync.java index 9620bf20f52..563fe39bd69 100644 --- a/test/jdk/java/net/httpclient/ThrowingSubscribersAsStringAsync.java +++ b/test/jdk/java/net/httpclient/ThrowingSubscribersAsStringAsync.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +25,10 @@ * @test * @summary Tests what happens when response body handlers and subscribers * throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker ThrowingSubscribersAsStringAsync AbstractThrowingSubscribers - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker ThrowingSubscribersAsStringAsync AbstractThrowingSubscribers + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingSubscribersAsStringAsync */ diff --git a/test/jdk/java/net/httpclient/ThrowingSubscribersSanity.java b/test/jdk/java/net/httpclient/ThrowingSubscribersSanity.java index 7e4d600f0fc..c480d55e147 100644 --- a/test/jdk/java/net/httpclient/ThrowingSubscribersSanity.java +++ b/test/jdk/java/net/httpclient/ThrowingSubscribersSanity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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,13 +25,10 @@ * @test * @summary Tests what happens when response body handlers and subscribers * throw unexpected exceptions. - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters - * ReferenceTracker ThrowingSubscribersSanity AbstractThrowingSubscribers - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext + * ReferenceTracker ThrowingSubscribersSanity AbstractThrowingSubscribers + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingSubscribersSanity */ diff --git a/test/jdk/java/net/httpclient/TlsContextTest.java b/test/jdk/java/net/httpclient/TlsContextTest.java index ccccadcc175..707a2e2d7c7 100644 --- a/test/jdk/java/net/httpclient/TlsContextTest.java +++ b/test/jdk/java/net/httpclient/TlsContextTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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 @@ -31,6 +31,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.net.ssl.SSLContext; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; @@ -48,15 +50,9 @@ * @test * @bug 8239594 * @summary This test verifies that the TLS version handshake respects ssl context - * @library /test/lib http2/server - * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters TlsContextTest - * @modules java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * java.base/sun.net.www.http - * java.base/sun.net.www - * java.base/sun.net + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext TlsContextTest + * jdk.httpclient.test.lib.common.HttpServerAdapters * @run testng/othervm -Dtest.requiresHost=true * -Djdk.httpclient.HttpClient.log=headers * -Djdk.internal.httpclient.disableHostnameVerification diff --git a/test/jdk/java/net/httpclient/UnauthorizedTest.java b/test/jdk/java/net/httpclient/UnauthorizedTest.java index 7f183620de2..389a79761dd 100644 --- a/test/jdk/java/net/httpclient/UnauthorizedTest.java +++ b/test/jdk/java/net/httpclient/UnauthorizedTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -29,15 +29,8 @@ * header only in the case where an authenticator is configured * for the client. If no authenticator is configured the client * should simply let the caller deal with the unauthorized response. - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext * @run testng/othervm * -Djdk.httpclient.HttpClient.log=headers * UnauthorizedTest @@ -66,8 +59,12 @@ import java.net.http.HttpResponse.BodyHandlers; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicLong; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -193,21 +190,17 @@ public void setup() throws Exception { if (sslContext == null) throw new AssertionError("Unexpected null sslContext"); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new UnauthorizedHandler(), "/http1/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(new UnauthorizedHandler(),"/https1/"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1"; - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new UnauthorizedHandler(), "/http2/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new UnauthorizedHandler(), "/https2/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2"; diff --git a/test/jdk/java/net/httpclient/UserCookieTest.java b/test/jdk/java/net/httpclient/UserCookieTest.java index 9c1c6cc139f..b8de5f97955 100644 --- a/test/jdk/java/net/httpclient/UserCookieTest.java +++ b/test/jdk/java/net/httpclient/UserCookieTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, 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,15 +26,8 @@ * @bug 8276774 * @summary Test that user-supplied cookies are appended to * server-cookies for HTTP/2 vs HTTP/1.1 - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * java.logging - * jdk.httpserver - * @library /test/lib http2/server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext * @run testng/othervm * -Djdk.tls.acknowledgeCloseNotify=true * -Djdk.httpclient.HttpClient.log=trace,headers,requests @@ -72,6 +65,8 @@ import java.util.stream.Stream; import javax.net.ServerSocketFactory; import javax.net.ssl.SSLContext; +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.http2.Http2TestServer; import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsConfigurator; @@ -83,6 +78,8 @@ import org.testng.annotations.Test; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.UTF_8; import static org.testng.Assert.assertEquals; @@ -116,14 +113,14 @@ public static String now() { @DataProvider(name = "positive") public Object[][] positive() { return new Object[][] { - { httpURI, HttpClient.Version.HTTP_1_1 }, - { httpsURI, HttpClient.Version.HTTP_1_1 }, - { httpDummy, HttpClient.Version.HTTP_1_1 }, - { httpsDummy, HttpClient.Version.HTTP_1_1 }, - { httpURI, HttpClient.Version.HTTP_2 }, - { httpsURI, HttpClient.Version.HTTP_2 }, - { httpDummy, HttpClient.Version.HTTP_2 }, - { httpsDummy, HttpClient.Version.HTTP_2 }, + { httpURI, HTTP_1_1 }, + { httpsURI, HTTP_1_1 }, + { httpDummy, HTTP_1_1 }, + { httpsDummy, HTTP_1_1 }, + { httpURI, HTTP_2 }, + { httpsURI, HTTP_2 }, + { httpDummy, HTTP_2 }, + { httpsDummy, HTTP_2 }, { http2URI, null }, { https2URI, null }, }; @@ -197,25 +194,21 @@ public void setup() throws Exception { if (sslContext == null) throw new AssertionError("Unexpected null sslContext"); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - - httpTestServer = HttpTestServer.of(HttpServer.create(sa, 0)); + httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new CookieValidationHandler(), "/http1/cookie/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/cookie/retry"; - HttpsServer httpsServer = HttpsServer.create(sa, 0); - httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer = HttpTestServer.of(httpsServer); + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); httpsTestServer.addHandler(new CookieValidationHandler(),"/https1/cookie/"); httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/cookie/retry"; - http2TestServer = HttpTestServer.of(new Http2TestServer("localhost", false, 0)); + http2TestServer = HttpTestServer.create(HTTP_2); http2TestServer.addHandler(new CookieValidationHandler(), "/http2/cookie/"); http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/cookie/retry"; - https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); https2TestServer.addHandler(new CookieValidationHandler(), "/https2/cookie/"); https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/cookie/retry"; - + InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); // DummyServer httpDummyServer = DummyServer.create(sa); httpsDummyServer = DummyServer.create(sa, sslContext); @@ -284,7 +277,7 @@ public void handle(HttpTestExchange t) throws IOException { String uuid = uuids.get(0); // retrying if (closedRequests.putIfAbsent(uuid, t.getRequestURI().toString()) == null) { - if (t.getExchangeVersion() == HttpClient.Version.HTTP_1_1) { + if (t.getExchangeVersion() == HTTP_1_1) { // Throwing an exception here only causes a retry // with HTTP_1_1 - where it forces the server to close // the connection. @@ -304,7 +297,7 @@ public void handle(HttpTestExchange t) throws IOException { HttpClient.Version version = t.getExchangeVersion(); List upgrade = t.getRequestHeaders().get("Upgrade"); if (upgrade == null) upgrade = List.of(); - boolean upgraded = version == HttpClient.Version.HTTP_2 + boolean upgraded = version == HTTP_2 && upgrade.stream().anyMatch("h2c"::equalsIgnoreCase); // not retrying @@ -312,7 +305,7 @@ public void handle(HttpTestExchange t) throws IOException { try (OutputStream os = t.getResponseBody()) { List cookie = t.getRequestHeaders().get("Cookie"); if (cookie != null) { - if (version == HttpClient.Version.HTTP_1_1 || upgraded) { + if (version == HTTP_1_1 || upgraded) { if (cookie.size() == 1) { cookie = List.of(cookie.get(0).split("; ")); } else if (cookie.size() > 1) { diff --git a/test/jdk/java/net/httpclient/dependent.policy b/test/jdk/java/net/httpclient/dependent.policy index 2396a118b20..6cfbc1c1e3b 100644 --- a/test/jdk/java/net/httpclient/dependent.policy +++ b/test/jdk/java/net/httpclient/dependent.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2018, 2023, 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,14 +27,15 @@ grant codeBase "file:${test.classes}/../../../../test/lib/-" { permission java.io.FilePermission "${test.src}/../../../../lib/jdk/test/lib/net/testkeys", "read"; }; -// for JTwork//classes/0/java/net/httpclient/http2/server/* -grant codeBase "file:${test.classes}/../../../../java/net/httpclient/http2/server/*" { +// for jdk/httpclient/test/lib/* classes +grant codeBase "file:${test.classes}/../../../../test/jdk/java/net/httpclient/lib/-" { permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.common"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.frame"; permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack"; permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http"; - permission java.net.SocketPermission "localhost:*", "listen,accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "listen,accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "listen,accept,resolve"; permission java.lang.RuntimePermission "modifyThread"; }; @@ -42,11 +43,15 @@ grant codeBase "file:${test.classes}/*" { permission java.io.FilePermission "${user.dir}${/}asFileDownloadTest.tmp.dir", "read,write"; permission java.io.FilePermission "${user.dir}${/}asFileDownloadTest.tmp.dir/-", "read,write"; - permission java.net.URLPermission "http://localhost:*/http1/-", "GET,POST"; - permission java.net.URLPermission "https://localhost:*/https1/-", "GET,POST"; - permission java.net.URLPermission "http://localhost:*/http2/-", "GET,POST"; - permission java.net.URLPermission "https://localhost:*/https2/-", "GET,POST"; - + permission java.net.URLPermission "http://127.0.0.1:*/http1/-", "GET,POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https1/-", "GET,POST"; + permission java.net.URLPermission "http://127.0.0.1:*/http2/-", "GET,POST"; + permission java.net.URLPermission "https://127.0.0.1:*/https2/-", "GET,POST"; + // ipv6 + permission java.net.URLPermission "http://[::1]:*/http1/-", "GET,POST"; + permission java.net.URLPermission "https://[::1]:*/https1/-", "GET,POST"; + permission java.net.URLPermission "http://[::1]:*/http2/-", "GET,POST"; + permission java.net.URLPermission "https://[::1]:*/https2/-", "GET,POST"; // needed to grant permission to the HTTP/2 server permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.common"; @@ -58,7 +63,8 @@ grant codeBase "file:${test.classes}/*" { permission java.util.logging.LoggingPermission "control"; // needed to grant the HTTP servers - permission java.net.SocketPermission "localhost:*", "listen,accept,resolve"; + permission java.net.SocketPermission "127.0.0.1:*", "listen,accept,resolve"; + permission java.net.SocketPermission "[::1]:*", "listen,accept,resolve"; permission java.util.PropertyPermission "*", "read"; permission java.lang.RuntimePermission "modifyThread"; diff --git a/test/jdk/java/net/httpclient/http2/BadHeadersTest.java b/test/jdk/java/net/httpclient/http2/BadHeadersTest.java index 2e4765fdf1b..0179317d6e5 100644 --- a/test/jdk/java/net/httpclient/http2/BadHeadersTest.java +++ b/test/jdk/java/net/httpclient/http2/BadHeadersTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -23,13 +23,8 @@ /* * @test - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * @library /test/lib server - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext * @run testng/othervm -Djdk.internal.httpclient.debug=true BadHeadersTest */ @@ -61,6 +56,12 @@ import java.util.Map.Entry; import java.util.concurrent.ExecutionException; import java.util.function.BiFunction; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2TestExchangeImpl; +import jdk.httpclient.test.lib.http2.Http2Handler; +import jdk.httpclient.test.lib.http2.BodyOutputStream; +import jdk.httpclient.test.lib.http2.Http2TestServerConnection; import static java.util.List.of; import static java.util.Map.entry; import static org.testng.Assert.assertTrue; @@ -302,11 +303,12 @@ public void sendResponseHeaders(int rCode, long responseLength) throws IOExcepti if (responseLength < 0) { headerFrames.get(headerFrames.size() -1).setFlag(HeadersFrame.END_STREAM); - os.closeInternal(); + os.markClosed(); } - for (Http2Frame f : headerFrames) - conn.outputQ.put(f); + for (Http2Frame f : headerFrames) { + conn.addToOutputQ(f); + } os.goodToGo(); System.err.println("Sent response headers " + rCode); diff --git a/test/jdk/java/net/httpclient/http2/BasicTest.java b/test/jdk/java/net/httpclient/http2/BasicTest.java index 00e4d80c12d..39cad481749 100644 --- a/test/jdk/java/net/httpclient/http2/BasicTest.java +++ b/test/jdk/java/net/httpclient/http2/BasicTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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,12 +24,9 @@ /* * @test * @bug 8087112 - * @library /test/lib server - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.common.TestUtil + * jdk.httpclient.test.lib.http2.Http2TestServer * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors BasicTest */ @@ -47,6 +44,11 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; +import jdk.httpclient.test.lib.common.TestUtil; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; +import jdk.httpclient.test.lib.http2.Http2EchoHandler; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.Test; import static java.net.http.HttpClient.Version.HTTP_2; diff --git a/test/jdk/java/net/httpclient/http2/ConnectionReuseTest.java b/test/jdk/java/net/httpclient/http2/ConnectionReuseTest.java new file mode 100644 index 00000000000..044035fecc5 --- /dev/null +++ b/test/jdk/java/net/httpclient/http2/ConnectionReuseTest.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2023, 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.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandlers; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import javax.net.ssl.SSLContext; + +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestExchange; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestHandler; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestServer; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.test.lib.net.IPSupport; +import jdk.test.lib.net.SimpleSSLContext; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import static java.net.http.HttpClient.Builder.NO_PROXY; +import static java.net.http.HttpClient.Version.HTTP_2; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/* + * @test + * @bug 8305906 + * @summary verify that the HttpClient pools and reuses a connection for HTTP/2 requests + * @library /test/lib /test/jdk/java/net/httpclient/lib ../ + * @build jdk.test.lib.net.SimpleSSLContext + * jdk.test.lib.net.IPSupport + * jdk.httpclient.test.lib.common.HttpServerAdapters + * ReferenceTracker + * + * @run junit/othervm ConnectionReuseTest + * @run junit/othervm -Djava.net.preferIPv6Addresses=true ConnectionReuseTest + */ +public class ConnectionReuseTest implements HttpServerAdapters { + + private static SSLContext sslContext; + private static HttpTestServer http2_Server; // h2 server over HTTP + private static HttpTestServer https2_Server; // h2 server over HTTPS + + @BeforeAll + public static void beforeAll() throws Exception { + if (IPSupport.preferIPv6Addresses()) { + IPSupport.printPlatformSupport(System.err); // for debug purposes + // this test is run with -Djava.net.preferIPv6Addresses=true, so skip (all) tests + // if IPv6 isn't supported on this host + Assumptions.assumeTrue(IPSupport.hasIPv6(), "Skipping tests - IPv6 is not supported"); + } + sslContext = new SimpleSSLContext().get(); + assertNotNull(sslContext, "Unexpected null sslContext"); + + http2_Server = HttpTestServer.of( + new Http2TestServer("localhost", false, 0)); + http2_Server.addHandler(new Handler(), "/"); + http2_Server.start(); + System.out.println("Started HTTP v2 server at " + http2_Server.serverAuthority()); + + https2_Server = HttpTestServer.of( + new Http2TestServer("localhost", true, sslContext)); + https2_Server.addHandler(new Handler(), "/"); + https2_Server.start(); + System.out.println("Started HTTPS v2 server at " + https2_Server.serverAuthority()); + } + + @AfterAll + public static void afterAll() { + if (https2_Server != null) { + System.out.println("Stopping server " + https2_Server); + https2_Server.stop(); + } + if (http2_Server != null) { + System.out.println("Stopping server " + http2_Server); + http2_Server.stop(); + } + } + + private static Stream requestURIs() throws Exception { + final List arguments = new ArrayList<>(); + // h2 over HTTPS + arguments.add(Arguments.of(new URI("https://" + https2_Server.serverAuthority() + "/"))); + // h2 over HTTP + arguments.add(Arguments.of(new URI("http://" + http2_Server.serverAuthority() + "/"))); + if (IPSupport.preferIPv6Addresses()) { + if (http2_Server.getAddress().getAddress().isLoopbackAddress()) { + // h2 over HTTP, use the short form of the host, in the request URI + arguments.add(Arguments.of(new URI("http://[::1]:" + + http2_Server.getAddress().getPort() + "/"))); + } + } + return arguments.stream(); + } + + /** + * Uses a single instance of a HttpClient and issues multiple requests to {@code requestURI} + * and expects that each of the request internally uses the same connection + */ + @ParameterizedTest + @MethodSource("requestURIs") + public void testConnReuse(final URI requestURI) throws Throwable { + final HttpClient.Builder builder = HttpClient.newBuilder() + .proxy(NO_PROXY).sslContext(sslContext); + final HttpRequest req = HttpRequest.newBuilder().uri(requestURI) + .GET().version(HTTP_2).build(); + final ReferenceTracker tracker = ReferenceTracker.INSTANCE; + Throwable testFailure = null; + HttpClient client = tracker.track(builder.build()); + try { + String clientConnAddr = null; + for (int i = 1; i <= 5; i++) { + System.out.println("Issuing request(" + i + ") " + req); + final HttpResponse resp = client.send(req, BodyHandlers.ofString()); + assertEquals(200, resp.statusCode(), "unexpected response code"); + final String respBody = resp.body(); + System.out.println("Server side handler responded to a request from " + respBody); + assertNotEquals(Handler.UNKNOWN_CLIENT_ADDR, respBody, + "server handler couldn't determine client address in request"); + if (i == 1) { + // for the first request we just keep track of the client connection address + // that got used for this request + clientConnAddr = respBody; + } else { + // verify that the client connection used to issue the request is the same + // as the previous request's client connection + assertEquals(clientConnAddr, respBody, "HttpClient unexpectedly used a" + + " different connection for request(" + i + ")"); + } + } + } catch (Throwable t) { + testFailure = t; + } finally { + // dereference the client to allow the tracker to verify the resources + // have been released + client = null; + // wait for the client to be shutdown + final AssertionError trackerFailure = tracker.check(2000); + if (testFailure != null) { + if (trackerFailure != null) { + // add the failure reported by the tracker as a suppressed + // exception and throw the original test failure + testFailure.addSuppressed(trackerFailure); + } + throw testFailure; + } + if (trackerFailure != null) { + // the test itself didn't fail but the tracker check failed. + // fail the test with this exception + throw trackerFailure; + } + } + } + + private static final class Handler implements HttpTestHandler { + + private static final String UNKNOWN_CLIENT_ADDR = "unknown"; + + @Override + public void handle(final HttpTestExchange t) throws IOException { + final InetSocketAddress clientAddr = t.getRemoteAddress(); + System.out.println("Handling request " + t.getRequestURI() + " from " + clientAddr); + // we write out the client address into the response body + final byte[] responseBody = clientAddr == null + ? UNKNOWN_CLIENT_ADDR.getBytes(StandardCharsets.UTF_8) + : clientAddr.toString().getBytes(StandardCharsets.UTF_8); + t.sendResponseHeaders(200, responseBody.length); + try (final OutputStream os = t.getResponseBody()) { + os.write(responseBody); + } + } + } +} diff --git a/test/jdk/java/net/httpclient/http2/ContinuationFrameTest.java b/test/jdk/java/net/httpclient/http2/ContinuationFrameTest.java index 0ca77044296..04ce8f4f4a4 100644 --- a/test/jdk/java/net/httpclient/http2/ContinuationFrameTest.java +++ b/test/jdk/java/net/httpclient/http2/ContinuationFrameTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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,14 +24,9 @@ /* * @test * @summary Test for CONTINUATION frame handling - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * @library /test/lib server + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext * @compile ../ReferenceTracker.java - * @build Http2TestServer - * @build jdk.test.lib.net.SimpleSSLContext * @run testng/othervm ContinuationFrameTest */ @@ -56,6 +51,13 @@ import jdk.internal.net.http.frame.HeaderFrame; import jdk.internal.net.http.frame.HeadersFrame; import jdk.internal.net.http.frame.Http2Frame; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2TestExchangeImpl; +import jdk.httpclient.test.lib.http2.Http2Handler; +import jdk.httpclient.test.lib.http2.BodyOutputStream; +import jdk.httpclient.test.lib.http2.Http2TestServerConnection; + import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; @@ -297,10 +299,11 @@ public void sendResponseHeaders(int rCode, long responseLength) throws IOExcepti assert headerFrames.size() > 0; // there must always be at least 1 if(headerFrames.get(0).getFlag(HeaderFrame.END_STREAM)) - os.closeInternal(); + os.markClosed(); - for (Http2Frame f : headerFrames) - conn.outputQ.put(f); + for (Http2Frame f : headerFrames) { + conn.addToOutputQ(f); + } os.goodToGo(); System.err.println("Sent response headers " + rCode); diff --git a/test/jdk/java/net/httpclient/http2/ErrorTest.java b/test/jdk/java/net/httpclient/http2/ErrorTest.java index 54143e91bbc..061fd5cd350 100644 --- a/test/jdk/java/net/httpclient/http2/ErrorTest.java +++ b/test/jdk/java/net/httpclient/http2/ErrorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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,8 +24,8 @@ /* * @test * @bug 8157105 - * @library /test/lib server - * @build jdk.test.lib.net.SimpleSSLContext + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer * @modules java.base/sun.net.www.http * java.net.http/jdk.internal.net.http.common * java.net.http/jdk.internal.net.http.frame @@ -46,6 +46,10 @@ import javax.net.ssl.SSLParameters; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2EchoHandler; + import jdk.test.lib.net.SimpleSSLContext; import static java.net.http.HttpClient.Version.HTTP_2; diff --git a/test/jdk/java/net/httpclient/http2/FixedThreadPoolTest.java b/test/jdk/java/net/httpclient/http2/FixedThreadPoolTest.java index 1db21bf7805..cef7bf7df65 100644 --- a/test/jdk/java/net/httpclient/http2/FixedThreadPoolTest.java +++ b/test/jdk/java/net/httpclient/http2/FixedThreadPoolTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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,12 +24,9 @@ /* * @test * @bug 8087112 8177935 - * @library /test/lib server - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.common.TestUtil + * jdk.httpclient.test.lib.http2.Http2TestServer * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors FixedThreadPoolTest */ @@ -40,6 +37,10 @@ import javax.net.ssl.*; import java.nio.file.*; import java.util.concurrent.*; +import jdk.httpclient.test.lib.common.TestUtil; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2EchoHandler; import jdk.test.lib.net.SimpleSSLContext; import static java.net.http.HttpClient.Version.HTTP_2; import org.testng.annotations.Test; diff --git a/test/jdk/java/net/httpclient/http2/ImplicitPushCancel.java b/test/jdk/java/net/httpclient/http2/ImplicitPushCancel.java index 69d9123203d..4d9ce835cdd 100644 --- a/test/jdk/java/net/httpclient/http2/ImplicitPushCancel.java +++ b/test/jdk/java/net/httpclient/http2/ImplicitPushCancel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -23,12 +23,8 @@ /* * @test - * @library /test/lib server - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer * @run testng/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=errors,requests,responses,trace @@ -52,6 +48,9 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; diff --git a/test/jdk/java/net/httpclient/http2/NoBodyTest.java b/test/jdk/java/net/httpclient/http2/NoBodyTest.java index 95629d79d16..2dc7508f5ee 100644 --- a/test/jdk/java/net/httpclient/http2/NoBodyTest.java +++ b/test/jdk/java/net/httpclient/http2/NoBodyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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,12 +24,8 @@ /* * @test * @bug 8087112 - * @library /test/lib server - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors NoBodyTest */ @@ -45,6 +41,9 @@ import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import java.util.concurrent.*; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.Test; import static java.net.http.HttpClient.Version.HTTP_2; diff --git a/test/jdk/java/net/httpclient/http2/ProxyTest2.java b/test/jdk/java/net/httpclient/http2/ProxyTest2.java index 41ab317d4c9..733c21ffe68 100644 --- a/test/jdk/java/net/httpclient/http2/ProxyTest2.java +++ b/test/jdk/java/net/httpclient/http2/ProxyTest2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -52,6 +52,9 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.test.lib.net.SimpleSSLContext; import java.util.concurrent.*; @@ -60,13 +63,8 @@ * @bug 8181422 * @summary Verifies that you can access an HTTP/2 server over HTTPS by * tunnelling through an HTTP/1.1 proxy. - * @modules java.net.http - * @library /test/lib server - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack - * @build jdk.test.lib.net.SimpleSSLContext ProxyTest2 + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer * @run main/othervm ProxyTest2 * @author danielfuchs */ @@ -189,13 +187,14 @@ private synchronized Thread pipe(InputStream is, OutputStream os, public void run() { try { try { - int c; - while ((c = is.read()) != -1) { - os.write(c); + int len; + byte[] buf = new byte[16 * 1024]; + while ((len = is.read(buf)) != -1) { + os.write(buf, 0, len); os.flush(); // if DEBUG prints a + or a - for each transferred // character. - if (DEBUG) System.out.print(tag); + if (DEBUG) System.out.print(String.valueOf(tag).repeat(len)); } is.close(); } finally { diff --git a/test/jdk/java/net/httpclient/http2/RedirectTest.java b/test/jdk/java/net/httpclient/http2/RedirectTest.java index b51c4df42ea..2d7701c5e37 100644 --- a/test/jdk/java/net/httpclient/http2/RedirectTest.java +++ b/test/jdk/java/net/httpclient/http2/RedirectTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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,12 +24,10 @@ /* * @test * @bug 8156514 - * @library /test/lib server - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.httpclient.test.lib.http2.Http2EchoHandler + * jdk.httpclient.test.lib.http2.Http2RedirectHandler * @run testng/othervm * -Djdk.httpclient.HttpClient.log=frames,ssl,requests,responses,errors * -Djdk.internal.httpclient.debug=true @@ -47,6 +45,11 @@ import java.util.function.*; import java.util.Arrays; import java.util.Iterator; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; +import jdk.httpclient.test.lib.http2.Http2EchoHandler; +import jdk.httpclient.test.lib.http2.Http2RedirectHandler; import org.testng.annotations.Test; import static java.net.http.HttpClient.Version.HTTP_2; diff --git a/test/jdk/java/net/httpclient/http2/ServerPush.java b/test/jdk/java/net/httpclient/http2/ServerPush.java index 5652dae79c5..60958dce696 100644 --- a/test/jdk/java/net/httpclient/http2/ServerPush.java +++ b/test/jdk/java/net/httpclient/http2/ServerPush.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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,12 +24,9 @@ /* * @test * @bug 8087112 8159814 - * @library /test/lib server - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.httpclient.test.lib.common.TestUtil jdk.httpclient.test.lib.http2.PushHandler * @run testng/othervm * -Djdk.httpclient.HttpClient.log=errors,requests,responses * ServerPush @@ -47,6 +44,11 @@ import java.util.*; import java.util.concurrent.*; import java.util.function.Consumer; +import jdk.httpclient.test.lib.common.TestUtil; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; +import jdk.httpclient.test.lib.http2.PushHandler; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; diff --git a/test/jdk/java/net/httpclient/http2/ServerPushWithDiffTypes.java b/test/jdk/java/net/httpclient/http2/ServerPushWithDiffTypes.java index 8b5426d70d6..3e12a20c15e 100644 --- a/test/jdk/java/net/httpclient/http2/ServerPushWithDiffTypes.java +++ b/test/jdk/java/net/httpclient/http2/ServerPushWithDiffTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -23,12 +23,8 @@ /* * @test - * @library /test/lib server - * @build jdk.test.lib.net.SimpleSSLContext - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer * @run testng/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=errors,requests,responses @@ -47,6 +43,9 @@ import java.util.*; import java.util.concurrent.*; import java.util.function.BiPredicate; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; import org.testng.annotations.Test; import static java.nio.charset.StandardCharsets.UTF_8; diff --git a/test/jdk/java/net/httpclient/http2/TLSConnection.java b/test/jdk/java/net/httpclient/http2/TLSConnection.java index 933ca784cb9..fd9cff38371 100644 --- a/test/jdk/java/net/httpclient/http2/TLSConnection.java +++ b/test/jdk/java/net/httpclient/http2/TLSConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -35,16 +35,16 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLSession; +import jdk.httpclient.test.lib.http2.Http2TestServer; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2Handler; /* * @test * @bug 8150769 8157107 - * @library server + * @library /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer * @summary Checks that SSL parameters can be set for HTTP/2 connection - * @modules java.base/sun.net.www.http - * java.net.http/jdk.internal.net.http.common - * java.net.http/jdk.internal.net.http.frame - * java.net.http/jdk.internal.net.http.hpack * @run main/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=all diff --git a/test/jdk/java/net/httpclient/http2/server/ExceptionallyCloseable.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ExceptionallyCloseable.java similarity index 95% rename from test/jdk/java/net/httpclient/http2/server/ExceptionallyCloseable.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ExceptionallyCloseable.java index 338af80c59e..f0727d80136 100644 --- a/test/jdk/java/net/httpclient/http2/server/ExceptionallyCloseable.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ExceptionallyCloseable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.httpclient.test.lib.common; + import java.io.Closeable; import java.io.IOException; diff --git a/test/jdk/java/net/httpclient/HttpServerAdapters.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/HttpServerAdapters.java similarity index 66% rename from test/jdk/java/net/httpclient/HttpServerAdapters.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/HttpServerAdapters.java index 3029d374028..623644df5a6 100644 --- a/test/jdk/java/net/httpclient/HttpServerAdapters.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/HttpServerAdapters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -20,13 +20,21 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ +package jdk.httpclient.test.lib.common; +import com.sun.net.httpserver.Authenticator; +import com.sun.net.httpserver.BasicAuthenticator; import com.sun.net.httpserver.Filter; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpContext; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsServer; +import jdk.httpclient.test.lib.http2.Http2Handler; +import jdk.httpclient.test.lib.http2.Http2TestExchange; +import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.internal.net.http.common.HttpHeadersBuilder; import java.net.InetAddress; @@ -42,6 +50,7 @@ import java.net.InetSocketAddress; import java.net.URI; import java.net.http.HttpHeaders; +import java.util.Base64; import java.util.List; import java.util.ListIterator; import java.util.Map; @@ -52,8 +61,11 @@ import java.util.concurrent.ExecutorService; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.net.ssl.SSLContext; + /** * Defines an adaptation layers so that a test server handlers and filters * can be implemented independently of the underlying server version. @@ -227,6 +239,7 @@ public static abstract class HttpTestExchange implements AutoCloseable { public abstract URI getRequestURI(); public abstract String getRequestMethod(); public abstract void close(); + public abstract InetSocketAddress getRemoteAddress(); public void serverPush(URI uri, HttpHeaders headers, byte[] body) { ByteArrayInputStream bais = new ByteArrayInputStream(body); serverPush(uri, headers, bais); @@ -284,6 +297,12 @@ void doFilter(Filter.Chain chain) throws IOException { } @Override public void close() { exchange.close(); } + + @Override + public InetSocketAddress getRemoteAddress() { + return exchange.getRemoteAddress(); + } + @Override public URI getRequestURI() { return exchange.getRequestURI(); } @Override @@ -339,6 +358,12 @@ void doFilter(Filter.Chain filter) throws IOException { } @Override public void close() { exchange.close();} + + @Override + public InetSocketAddress getRemoteAddress() { + return exchange.getRemoteAddress(); + } + @Override public URI getRequestURI() { return exchange.getRequestURI(); } @Override @@ -485,6 +510,175 @@ public String description() { } } + static String toString(HttpTestRequestHeaders headers) { + return headers.entrySet().stream() + .map((e) -> e.getKey() + ": " + e.getValue()) + .collect(Collectors.joining("\n")); + } + + abstract static class AbstractHttpAuthFilter extends HttpTestFilter { + + public static final int HTTP_PROXY_AUTH = 407; + public static final int HTTP_UNAUTHORIZED = 401; + public enum HttpAuthMode {PROXY, SERVER} + final HttpAuthMode authType; + final String type; + + public AbstractHttpAuthFilter(HttpAuthMode authType, String type) { + this.authType = authType; + this.type = type; + } + + public final String type() { + return type; + } + + protected String getLocation() { + return "Location"; + } + protected String getKeepAlive() { + return "keep-alive"; + } + protected String getConnection() { + return authType == HttpAuthMode.PROXY ? "Proxy-Connection" : "Connection"; + } + + protected String getAuthenticate() { + return authType == HttpAuthMode.PROXY + ? "Proxy-Authenticate" : "WWW-Authenticate"; + } + protected String getAuthorization() { + return authType == HttpAuthMode.PROXY + ? "Proxy-Authorization" : "Authorization"; + } + protected int getUnauthorizedCode() { + return authType == HttpAuthMode.PROXY + ? HTTP_PROXY_AUTH + : HTTP_UNAUTHORIZED; + } + protected abstract boolean isAuthentified(HttpTestExchange he) throws IOException; + protected abstract void requestAuthentication(HttpTestExchange he) throws IOException; + protected void accept(HttpTestExchange he, HttpChain chain) throws IOException { + chain.doFilter(he); + } + + @Override + public void doFilter(HttpTestExchange he, HttpChain chain) throws IOException { + try { + System.out.println(type + ": Got " + he.getRequestMethod() + + ": " + he.getRequestURI() + + "\n" + HttpServerAdapters.toString(he.getRequestHeaders())); + + // Assert only a single value for Expect. Not directly related + // to digest authentication, but verifies good client behaviour. + List expectValues = he.getRequestHeaders().get("Expect"); + if (expectValues != null && expectValues.size() > 1) { + throw new IOException("Expect: " + expectValues); + } + + if (!isAuthentified(he)) { + try { + requestAuthentication(he); + he.sendResponseHeaders(getUnauthorizedCode(), -1); + System.out.println(type + + ": Sent back " + getUnauthorizedCode()); + } finally { + he.close(); + } + } else { + accept(he, chain); + } + } catch (RuntimeException | Error | IOException t) { + System.err.println(type + + ": Unexpected exception while handling request: " + t); + t.printStackTrace(System.err); + he.close(); + throw t; + } + } + + } + + public static class HttpBasicAuthFilter extends AbstractHttpAuthFilter { + + static String type(HttpAuthMode authType) { + String type = authType == HttpAuthMode.SERVER + ? "BasicAuth Server Filter" : "BasicAuth Proxy Filter"; + return "["+type+"]"; + } + + final BasicAuthenticator auth; + public HttpBasicAuthFilter(BasicAuthenticator auth) { + this(auth, HttpAuthMode.SERVER); + } + + public HttpBasicAuthFilter(BasicAuthenticator auth, HttpAuthMode authType) { + this(auth, authType, type(authType)); + } + + public HttpBasicAuthFilter(BasicAuthenticator auth, HttpAuthMode authType, String typeDesc) { + super(authType, typeDesc); + this.auth = auth; + } + + protected String getAuthValue() { + return "Basic realm=\"" + auth.getRealm() + "\""; + } + + @Override + protected void requestAuthentication(HttpTestExchange he) + throws IOException + { + String headerName = getAuthenticate(); + String headerValue = getAuthValue(); + he.getResponseHeaders().addHeader(headerName, headerValue); + System.out.println(type + ": Requesting Basic Authentication, " + + headerName + " : "+ headerValue); + } + + @Override + protected boolean isAuthentified(HttpTestExchange he) { + if (he.getRequestHeaders().containsKey(getAuthorization())) { + List authorization = + he.getRequestHeaders().get(getAuthorization()); + for (String a : authorization) { + System.out.println(type + ": processing " + a); + int sp = a.indexOf(' '); + if (sp < 0) return false; + String scheme = a.substring(0, sp); + if (!"Basic".equalsIgnoreCase(scheme)) { + System.out.println(type + ": Unsupported scheme '" + + scheme +"'"); + return false; + } + if (a.length() <= sp+1) { + System.out.println(type + ": value too short for '" + + scheme +"'"); + return false; + } + a = a.substring(sp+1); + return validate(a); + } + return false; + } + return false; + } + + boolean validate(String a) { + byte[] b = Base64.getDecoder().decode(a); + String userpass = new String (b); + int colon = userpass.indexOf (':'); + String uname = userpass.substring (0, colon); + String pass = userpass.substring (colon+1); + return auth.checkCredentials(uname, pass); + } + + @Override + public String description() { + return "HttpBasicAuthFilter"; + } + } + /** * A version agnostic adapter class for HTTP Server Context. */ @@ -493,7 +687,7 @@ public static abstract class HttpTestContext { public abstract void addFilter(HttpTestFilter filter); public abstract Version getVersion(); - // will throw UOE if the server is HTTP/2 + // will throw UOE if the server is HTTP/2 or Authenticator is not a BasicAuthenticator public abstract void setAuthenticator(com.sun.net.httpserver.Authenticator authenticator); } @@ -517,8 +711,15 @@ static void enableLogging() { public abstract Version getVersion(); public String serverAuthority() { - return InetAddress.getLoopbackAddress().getHostName() + ":" - + getAddress().getPort(); + InetSocketAddress address = getAddress(); + String hostString = address.getHostString(); + hostString = address.getAddress().isLoopbackAddress() || hostString.equals("localhost") + ? address.getAddress().getHostAddress() // use the raw IP address, if loopback + : hostString; // use whatever host string was used to construct the address + hostString = hostString.contains(":") + ? "[" + hostString + "]" + : hostString; + return hostString + ":" + address.getPort(); } public static HttpTestServer of(HttpServer server) { @@ -533,6 +734,90 @@ public static HttpTestServer of(Http2TestServer server) { return new Http2TestServerImpl(server); } + /** + * Creates a {@link HttpTestServer} which supports the {@code serverVersion}. The server + * will only be available on {@code http} protocol. {@code https} will not be supported + * by the returned server + * + * @param serverVersion The HTTP version of the server + * @return The newly created server + * @throws IllegalArgumentException if {@code serverVersion} is not supported by this method + * @throws IOException if any exception occurs during the server creation + */ + public static HttpTestServer create(Version serverVersion) throws IOException { + Objects.requireNonNull(serverVersion); + return create(serverVersion, null); + } + + /** + * Creates a {@link HttpTestServer} which supports the {@code serverVersion}. If the + * {@code sslContext} is null, then only {@code http} protocol will be supported by the + * server. Else, the server will be configured with the {@code sslContext} and will support + * {@code https} protocol. + * + * @param serverVersion The HTTP version of the server + * @param sslContext The SSLContext to use. Can be null + * @return The newly created server + * @throws IllegalArgumentException if {@code serverVersion} is not supported by this method + * @throws IOException if any exception occurs during the server creation + */ + public static HttpTestServer create(Version serverVersion, SSLContext sslContext) + throws IOException { + Objects.requireNonNull(serverVersion); + return create(serverVersion, sslContext, null); + } + + /** + * Creates a {@link HttpTestServer} which supports the {@code serverVersion}. If the + * {@code sslContext} is null, then only {@code http} protocol will be supported by the + * server. Else, the server will be configured with the {@code sslContext} and will support + * {@code https} protocol. + * + * @param serverVersion The HTTP version of the server + * @param sslContext The SSLContext to use. Can be null + * @param executor The executor to be used by the server. Can be null + * @return The newly created server + * @throws IllegalArgumentException if {@code serverVersion} is not supported by this method + * @throws IOException if any exception occurs during the server creation + */ + public static HttpTestServer create(Version serverVersion, SSLContext sslContext, + ExecutorService executor) throws IOException { + Objects.requireNonNull(serverVersion); + switch (serverVersion) { + case HTTP_2 -> { + Http2TestServer underlying; + try { + underlying = sslContext == null + ? new Http2TestServer("localhost", false, 0, executor, null) // HTTP + : new Http2TestServer("localhost", true, 0, executor, sslContext); // HTTPS + } catch (IOException ioe) { + throw ioe; + } catch (Exception e) { + throw new IOException(e); + } + return HttpTestServer.of(underlying); + } + case HTTP_1_1 -> { + InetSocketAddress sa = new InetSocketAddress( + InetAddress.getLoopbackAddress(), 0); + HttpServer underlying; + if (sslContext == null) { + underlying = HttpServer.create(sa, 0); // HTTP + } else { + HttpsServer https = HttpsServer.create(sa, 0); // HTTPS + https.setHttpsConfigurator(new HttpsConfigurator(sslContext)); + underlying = https; + } + if (executor != null) { + underlying.setExecutor(executor); + } + return HttpTestServer.of(underlying); + } + default -> throw new IllegalArgumentException("Unsupported HTTP version " + + serverVersion); + } + } + private static class Http1TestServer extends HttpTestServer { private final HttpServer impl; private final ExecutorService executor; @@ -647,8 +932,13 @@ public void handle(HttpTestExchange exchange) throws IOException { HttpChain.of(filters, handler).doFilter(exchange); } @Override - public void setAuthenticator(com.sun.net.httpserver.Authenticator authenticator) { - throw new UnsupportedOperationException("Can't set HTTP/1.1 authenticator on HTTP/2 context"); + public void setAuthenticator(final Authenticator authenticator) { + if (authenticator instanceof BasicAuthenticator basicAuth) { + addFilter(new HttpBasicAuthFilter(basicAuth)); + } else { + throw new UnsupportedOperationException( + "only BasicAuthenticator is supported on HTTP/2 context"); + } } @Override public Version getVersion() { return Version.HTTP_2; } } diff --git a/test/jdk/java/net/httpclient/http2/server/TestUtil.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/TestUtil.java similarity index 96% rename from test/jdk/java/net/httpclient/http2/server/TestUtil.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/TestUtil.java index db03c218bc2..2b2dacff57b 100644 --- a/test/jdk/java/net/httpclient/http2/server/TestUtil.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/TestUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.httpclient.test.lib.common; + import java.io.*; import java.nio.file.*; import java.util.Arrays; diff --git a/test/jdk/java/net/httpclient/http2/server/BodyInputStream.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/BodyInputStream.java similarity index 97% rename from test/jdk/java/net/httpclient/http2/server/BodyInputStream.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/BodyInputStream.java index 4ffca293ded..71372d5e95f 100644 --- a/test/jdk/java/net/httpclient/http2/server/BodyInputStream.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/BodyInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.httpclient.test.lib.http2; + import java.io.*; import java.nio.ByteBuffer; import java.util.List; diff --git a/test/jdk/java/net/httpclient/http2/server/BodyOutputStream.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/BodyOutputStream.java similarity index 94% rename from test/jdk/java/net/httpclient/http2/server/BodyOutputStream.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/BodyOutputStream.java index 008d9bdffc1..d043f81390e 100644 --- a/test/jdk/java/net/httpclient/http2/server/BodyOutputStream.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/BodyOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.httpclient.test.lib.http2; + import java.io.*; import java.nio.ByteBuffer; @@ -31,7 +33,7 @@ * reader thread. */ @SuppressWarnings({"rawtypes","unchecked"}) -class BodyOutputStream extends OutputStream { +public class BodyOutputStream extends OutputStream { final static byte[] EMPTY_BARRAY = new byte[0]; final int streamid; @@ -72,7 +74,7 @@ void waitForWindow(int demand) throws InterruptedException { } } - void goodToGo() { + public void goodToGo() { goodToGo = true; } @@ -116,7 +118,7 @@ public void write(int b) throws IOException { write(one, 0, 1); } - void closeInternal() { + public void markClosed() { closed = true; } diff --git a/test/jdk/java/net/httpclient/http2/server/EchoHandler.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/EchoHandler.java similarity index 96% rename from test/jdk/java/net/httpclient/http2/server/EchoHandler.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/EchoHandler.java index 58cc22943d6..24ac59d96dc 100644 --- a/test/jdk/java/net/httpclient/http2/server/EchoHandler.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/EchoHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.httpclient.test.lib.http2; + import java.io.*; import java.nio.file.Files; import java.nio.file.Path; diff --git a/test/jdk/java/net/httpclient/http2/server/Http2EchoHandler.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2EchoHandler.java similarity index 97% rename from test/jdk/java/net/httpclient/http2/server/Http2EchoHandler.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2EchoHandler.java index c7b9a21c5cb..7b13724ac51 100644 --- a/test/jdk/java/net/httpclient/http2/server/Http2EchoHandler.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2EchoHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, 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 @@ -20,6 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ +package jdk.httpclient.test.lib.http2; import java.io.*; import java.net.http.HttpHeaders; diff --git a/test/jdk/java/net/httpclient/http2/server/Http2Handler.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2Handler.java similarity index 93% rename from test/jdk/java/net/httpclient/http2/server/Http2Handler.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2Handler.java index 03af49e8b07..8871f0c2cd5 100644 --- a/test/jdk/java/net/httpclient/http2/server/Http2Handler.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2Handler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -21,6 +21,7 @@ * questions. */ +package jdk.httpclient.test.lib.http2; import java.io.IOException; diff --git a/test/jdk/java/net/httpclient/http2/server/Http2RedirectHandler.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2RedirectHandler.java similarity index 95% rename from test/jdk/java/net/httpclient/http2/server/Http2RedirectHandler.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2RedirectHandler.java index 97ea94b7b91..69e4344aff2 100644 --- a/test/jdk/java/net/httpclient/http2/server/Http2RedirectHandler.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2RedirectHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.httpclient.test.lib.http2; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; diff --git a/test/jdk/java/net/httpclient/http2/server/Http2TestExchange.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestExchange.java similarity index 95% rename from test/jdk/java/net/httpclient/http2/server/Http2TestExchange.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestExchange.java index 30aad46b178..208a8d54e08 100644 --- a/test/jdk/java/net/httpclient/http2/server/Http2TestExchange.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestExchange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.httpclient.test.lib.http2; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; diff --git a/test/jdk/java/net/httpclient/http2/server/Http2TestExchangeImpl.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestExchangeImpl.java similarity index 93% rename from test/jdk/java/net/httpclient/http2/server/Http2TestExchangeImpl.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestExchangeImpl.java index 7bb8ad57e45..87f67e76356 100644 --- a/test/jdk/java/net/httpclient/http2/server/Http2TestExchangeImpl.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestExchangeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.httpclient.test.lib.http2; + import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; @@ -39,21 +41,21 @@ public class Http2TestExchangeImpl implements Http2TestExchange { static final String HEAD = "HEAD"; final HttpHeaders reqheaders; - final HttpHeadersBuilder rspheadersBuilder; + protected final HttpHeadersBuilder rspheadersBuilder; final URI uri; final String method; final InputStream is; - final BodyOutputStream os; + protected final BodyOutputStream os; final SSLSession sslSession; - final int streamid; + protected final int streamid; final boolean pushAllowed; - final Http2TestServerConnection conn; + protected final Http2TestServerConnection conn; final Http2TestServer server; int responseCode = -1; - long responseLength; + protected long responseLength; - Http2TestExchangeImpl(int streamid, + public Http2TestExchangeImpl(int streamid, String method, HttpHeaders reqheaders, HttpHeadersBuilder rspheadersBuilder, @@ -146,7 +148,7 @@ public void sendResponseHeaders(int rCode, long responseLength) throws IOExcepti if (responseLength < 0 || rCode == 204) { response.setFlag(HeadersFrame.END_STREAM); - os.closeInternal(); + os.markClosed(); } conn.outputQ.put(response); os.goodToGo(); diff --git a/test/jdk/java/net/httpclient/http2/server/Http2TestExchangeSupplier.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestExchangeSupplier.java similarity index 95% rename from test/jdk/java/net/httpclient/http2/server/Http2TestExchangeSupplier.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestExchangeSupplier.java index 7f96a86bc0a..c423632e565 100644 --- a/test/jdk/java/net/httpclient/http2/server/Http2TestExchangeSupplier.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestExchangeSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.httpclient.test.lib.http2; + import javax.net.ssl.SSLSession; import java.io.InputStream; import java.net.URI; diff --git a/test/jdk/java/net/httpclient/http2/server/Http2TestServer.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServer.java similarity index 90% rename from test/jdk/java/net/httpclient/http2/server/Http2TestServer.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServer.java index 33e5ade4f83..912288df226 100644 --- a/test/jdk/java/net/httpclient/http2/server/Http2TestServer.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.httpclient.test.lib.http2; + import java.io.IOException; import java.net.*; import java.util.*; @@ -81,8 +83,11 @@ public InetSocketAddress getAddress() { } public String serverAuthority() { - return InetAddress.getLoopbackAddress().getHostName() + ":" - + getAddress().getPort(); + final InetSocketAddress inetSockAddr = getAddress(); + final String hostIP = inetSockAddr.getAddress().getHostAddress(); + // escape for ipv6 + final String h = hostIP.contains(":") ? "[" + hostIP + "]" : hostIP; + return h + ":" + inetSockAddr.getPort(); } public Http2TestServer(boolean secure, @@ -124,6 +129,20 @@ public Http2TestServer(String serverName, this(serverName, secure, port, exec, backlog, properties, context, false); } + public Http2TestServer(String serverName, + boolean secure, + int port, + ExecutorService exec, + int backlog, + Properties properties, + SSLContext context, + boolean supportsHTTP11) + throws Exception + { + this(InetAddress.getLoopbackAddress(), serverName, secure, port, exec, + backlog, properties, context, supportsHTTP11); + } + /** * Create a Http2Server listening on the given port. Currently needs * to know in advance whether incoming connections are plain TCP "h2c" @@ -134,6 +153,7 @@ public Http2TestServer(String serverName, * "X-Magic", "HTTP/1.1 request received by HTTP/2 server", * "X-Received-Body", ); * + * @param localAddr local address to bind to * @param serverName SNI servername * @param secure https or http * @param port listen port @@ -146,7 +166,8 @@ public Http2TestServer(String serverName, * connection without the h2 ALPN. Otherwise, false to operate in * HTTP/2 mode exclusively. */ - public Http2TestServer(String serverName, + public Http2TestServer(InetAddress localAddr, + String serverName, boolean secure, int port, ExecutorService exec, @@ -163,7 +184,7 @@ public Http2TestServer(String serverName, this.sslContext = context; else this.sslContext = SSLContext.getDefault(); - server = initSecure(port, backlog); + server = initSecure(localAddr, port, backlog); } else { this.sslContext = context; server = initPlaintext(port, backlog); @@ -236,14 +257,14 @@ public synchronized void stop() { } - final ServerSocket initSecure(int port, int backlog) throws Exception { + final ServerSocket initSecure(InetAddress localAddr, int port, int backlog) throws Exception { ServerSocketFactory fac; SSLParameters sslp = null; fac = sslContext.getServerSocketFactory(); sslp = sslContext.getSupportedSSLParameters(); SSLServerSocket se = (SSLServerSocket) fac.createServerSocket(); se.setReuseAddress(false); - se.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), backlog); + se.bind(new InetSocketAddress(localAddr, 0), backlog); if (supportsHTTP11) { sslp.setApplicationProtocols(new String[]{"h2", "http/1.1"}); } else { diff --git a/test/jdk/java/net/httpclient/http2/server/Http2TestServerConnection.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServerConnection.java similarity index 99% rename from test/jdk/java/net/httpclient/http2/server/Http2TestServerConnection.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServerConnection.java index 3c3b9ea985b..1d48425081d 100644 --- a/test/jdk/java/net/httpclient/http2/server/Http2TestServerConnection.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServerConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.httpclient.test.lib.http2; + import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.Closeable; @@ -244,6 +246,10 @@ void handlePing(PingFrame ping) throws IOException { } } + public void addToOutputQ(final Http2Frame frame) throws IOException { + outputQ.put(frame); + } + private static boolean compareIPAddrs(InetAddress addr1, String host) { try { InetAddress addr2 = InetAddress.getByName(host); @@ -769,7 +775,7 @@ void readLoop() { q.orderlyClose(); BodyOutputStream oq = outStreams.get(stream); if (oq != null) - oq.closeInternal(); + oq.markClosed(); } else if (pushStreams.contains(stream)) { // we could interrupt the pushStream's output // but the continuation, even after a reset @@ -814,7 +820,7 @@ static boolean isServerStreamId(int streamid) { } /** Encodes an group of headers, without any ordering guarantees. */ - List encodeHeaders(HttpHeaders headers) { + public List encodeHeaders(HttpHeaders headers) { List buffers = new LinkedList<>(); ByteBuffer buf = getBuffer(); @@ -840,7 +846,7 @@ List encodeHeaders(HttpHeaders headers) { } /** Encodes an ordered list of headers. */ - List encodeHeadersOrdered(List> headers) { + public List encodeHeadersOrdered(List> headers) { List buffers = new LinkedList<>(); ByteBuffer buf = getBuffer(); diff --git a/test/jdk/java/net/httpclient/http2/server/NoBodyHandler.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/NoBodyHandler.java similarity index 94% rename from test/jdk/java/net/httpclient/http2/server/NoBodyHandler.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/NoBodyHandler.java index 7a28ed5d9e8..791d22bbf0d 100644 --- a/test/jdk/java/net/httpclient/http2/server/NoBodyHandler.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/NoBodyHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.httpclient.test.lib.http2; + import java.io.*; import static java.lang.System.out; diff --git a/test/jdk/java/net/httpclient/http2/server/OutgoingPushPromise.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/OutgoingPushPromise.java similarity index 91% rename from test/jdk/java/net/httpclient/http2/server/OutgoingPushPromise.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/OutgoingPushPromise.java index 7b2124b73da..b5dcdea3551 100644 --- a/test/jdk/java/net/httpclient/http2/server/OutgoingPushPromise.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/OutgoingPushPromise.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.httpclient.test.lib.http2; + import java.io.InputStream; import java.net.URI; import java.net.http.HttpHeaders; @@ -28,7 +30,7 @@ // will be converted to a PushPromiseFrame in the writeLoop // a thread is then created to produce the DataFrames from the InputStream -class OutgoingPushPromise extends Http2Frame { +public class OutgoingPushPromise extends Http2Frame { final HttpHeaders headers; final URI uri; final InputStream is; diff --git a/test/jdk/java/net/httpclient/http2/server/PushHandler.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/PushHandler.java similarity index 96% rename from test/jdk/java/net/httpclient/http2/server/PushHandler.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/PushHandler.java index 07864fd0c77..2e014135445 100644 --- a/test/jdk/java/net/httpclient/http2/server/PushHandler.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/PushHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -21,6 +21,8 @@ * questions. */ +package jdk.httpclient.test.lib.http2; + import java.io.*; import java.net.*; import java.net.http.HttpHeaders; diff --git a/test/jdk/java/net/httpclient/http2/server/Queue.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Queue.java similarity index 96% rename from test/jdk/java/net/httpclient/http2/server/Queue.java rename to test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Queue.java index 66b931b4b7c..358d6c509f6 100644 --- a/test/jdk/java/net/httpclient/http2/server/Queue.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Queue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -21,11 +21,15 @@ * questions. */ +package jdk.httpclient.test.lib.http2; + import java.io.IOException; import java.util.LinkedList; import java.util.Objects; import java.util.stream.Stream; +import jdk.httpclient.test.lib.common.ExceptionallyCloseable; + // Each stream has one of these for input. Each Http2Connection has one // for output. Can be used blocking or asynchronously. diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersConcat.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersConcat.java deleted file mode 100644 index 520c16de9a8..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersConcat.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2020, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowPublisherVerification; - -import java.net.http.HttpRequest.BodyPublisher; -import java.net.http.HttpRequest.BodyPublishers; -import java.nio.ByteBuffer; -import java.util.Collections; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Flow.Publisher; - -/* See TckDriver.java for more information */ -public class BodyPublishersConcat - extends FlowPublisherVerification { - - private static final int ELEMENT_SIZE = 16 * 1024; - - public BodyPublishersConcat() { - super(new TestEnvironment(450L)); - } - - private static BodyPublisher ofByteArrays(int n, byte[] bytes) { - return BodyPublishers.ofByteArrays(Collections.nCopies((int) n, bytes)); - } - - @Override - public Publisher createFlowPublisher(long nElements) { - System.out.println("BodyPublishersConcat: %d elements requested" - .formatted(nElements)); - byte[] bytes = S.arrayOfNRandomBytes(ELEMENT_SIZE); - if (nElements == 0) { - System.out.println("BodyPublishersConcat: empty publisher"); - return BodyPublishers.concat(); - } else if (nElements == 1) { - System.out.println("BodyPublishersConcat: singleton publisher"); - return BodyPublishers.concat(ofByteArrays(1, bytes)); - } else if (nElements < 4) { - int left = (int)nElements/2; - int right = (int)nElements - left; - System.out.println("BodyPublishersConcat: dual publisher (%d, %d)".formatted(left, right)); - return BodyPublishers.concat(ofByteArrays(left, bytes), - ofByteArrays(right, bytes)); - } else { - List publishers = new ArrayList<>(); - List sizes = new ArrayList<>(); - long remaining = nElements; - int max = (int) Math.min((long)Integer.MAX_VALUE, nElements/2L); - while (remaining > 0) { - int length = S.randomIntUpTo(max); - if (length == 0) length = 1; - sizes.add(length); - if (remaining > length) { - publishers.add(ofByteArrays(length, bytes)); - remaining = remaining - length; - } else { - publishers.add(ofByteArrays((int)remaining, bytes)); - remaining = 0; - } - } - System.out.println("BodyPublishersConcat: multi publisher " + sizes); - return BodyPublishers.concat(publishers.toArray(BodyPublisher[]::new)); - } - } - - @Override - public Publisher createFailedFlowPublisher() { - return null; - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersFromPublisher.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersFromPublisher.java deleted file mode 100644 index b997fa6a7fc..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersFromPublisher.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowPublisherVerification; - -import java.net.http.HttpRequest.BodyPublishers; -import java.nio.ByteBuffer; -import java.util.concurrent.Flow.Publisher; -import java.util.stream.Stream; - -/* See TckDriver.java for more information */ -public class BodyPublishersFromPublisher - extends FlowPublisherVerification { - - public BodyPublishersFromPublisher() { - super(new TestEnvironment(450L)); - } - - @Override - public Publisher createFlowPublisher(long nElements) { - Stream buffers = - Stream.generate(() -> S.bufferOfNRandomBytes(1024)) - .limit(nElements); - Publisher pub = S.publisherOfStream(buffers); - return BodyPublishers.fromPublisher(pub); - } - - @Override - public Publisher createFailedFlowPublisher() { - return BodyPublishers.fromPublisher(S.newErroredPublisher()); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfByteArray.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfByteArray.java deleted file mode 100644 index 0188b88f26d..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfByteArray.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowPublisherVerification; - -import java.net.http.HttpRequest.BodyPublishers; -import java.nio.ByteBuffer; -import java.util.concurrent.Flow.Publisher; - -/* See TckDriver.java for more information */ -public class BodyPublishersOfByteArray - extends FlowPublisherVerification { - - private static final int ELEMENT_SIZE = 16 * 1024; - - public BodyPublishersOfByteArray() { - super(new TestEnvironment(450L)); - } - - @Override - public Publisher createFlowPublisher(long nElements) { - byte[] b = S.arrayOfNRandomBytes(nElements * ELEMENT_SIZE); - return BodyPublishers.ofByteArray(b); - } - - @Override - public Publisher createFailedFlowPublisher() { - return null; - } - - @Override - public long maxElementsFromPublisher() { - return 21; - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfByteArrays.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfByteArrays.java deleted file mode 100644 index 9ad8a0ccdac..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfByteArrays.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowPublisherVerification; - -import java.net.http.HttpRequest.BodyPublishers; -import java.nio.ByteBuffer; -import java.util.Collections; -import java.util.concurrent.Flow.Publisher; - -/* See TckDriver.java for more information */ -public class BodyPublishersOfByteArrays - extends FlowPublisherVerification { - - private static final int ELEMENT_SIZE = 16 * 1024; - - public BodyPublishersOfByteArrays() { - super(new TestEnvironment(450L)); - } - - @Override - public Publisher createFlowPublisher(long nElements) { - byte[] bytes = S.arrayOfNRandomBytes(ELEMENT_SIZE); - return BodyPublishers.ofByteArrays( - Collections.nCopies((int) nElements, bytes)); - } - - @Override - public Publisher createFailedFlowPublisher() { - return null; - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfFile.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfFile.java deleted file mode 100644 index 97b30f4511d..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfFile.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowPublisherVerification; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.net.http.HttpRequest.BodyPublishers; -import java.nio.ByteBuffer; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.concurrent.Flow.Publisher; -import java.util.concurrent.atomic.AtomicLong; - -/* See TckDriver.java for more information */ -public class BodyPublishersOfFile - extends FlowPublisherVerification { - - private static final int ELEMENT_SIZE = 16 * 1024; - private static final AtomicLong UNIQUE_NUMBERS = new AtomicLong(); - - public BodyPublishersOfFile() { - super(new TestEnvironment(450L)); - } - - @Override - public Publisher createFlowPublisher(long nElements) { - try { - Path f = createFile(nElements * ELEMENT_SIZE); - return BodyPublishers.ofFile(f); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - private static Path createFile(long nBytes) throws IOException { - String name = "f" + UNIQUE_NUMBERS.getAndIncrement(); - Path f = Files.createFile(Path.of(name)); - return Files.write(f, S.arrayOfNRandomBytes(nBytes)); - } - - @Override - public Publisher createFailedFlowPublisher() { - return null; - } - - @Override - public long maxElementsFromPublisher() { - return 21; - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfSubByteArray.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfSubByteArray.java deleted file mode 100644 index e0209fe058c..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfSubByteArray.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowPublisherVerification; - -import java.net.http.HttpRequest.BodyPublishers; -import java.nio.ByteBuffer; -import java.util.concurrent.Flow.Publisher; - -/* See TckDriver.java for more information */ -public class BodyPublishersOfSubByteArray - extends FlowPublisherVerification { - - private static final int ELEMENT_SIZE = 16 * 1024; - - public BodyPublishersOfSubByteArray() { - super(new TestEnvironment(450L)); - } - - @Override - public Publisher createFlowPublisher(long nElements) { - int prefixLen = S.randomIntUpTo(13); - int postfixLen = S.randomIntUpTo(17); - byte[] b = S.arrayOfNRandomBytes(nElements * ELEMENT_SIZE); - byte[] contents = new byte[prefixLen + b.length + postfixLen]; - System.arraycopy(b, 0, contents, prefixLen, b.length); - return BodyPublishers.ofByteArray(contents, prefixLen, b.length); - } - - @Override - public Publisher createFailedFlowPublisher() { - return null; - } - - @Override - public long maxElementsFromPublisher() { - return 21; - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersBuffering.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersBuffering.java deleted file mode 100644 index baa6b306b9a..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersBuffering.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification; - -import java.net.http.HttpResponse.BodySubscribers; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.concurrent.Flow.Subscriber; - -/* See TckDriver.java for more information */ -public class BodySubscribersBuffering - extends FlowSubscriberBlackboxVerification> { - - public BodySubscribersBuffering() { - super(new TestEnvironment(450L)); - } - - @Override - public Subscriber> createFlowSubscriber() { - return BodySubscribers.buffering(BodySubscribers.discarding(), - S.randomIntUpTo(1024) + 1); - } - - @Override - public List createElement(int element) { - return S.listOfBuffersFromBufferOfNBytes(element % 17); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersFromLineSubscriber.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersFromLineSubscriber.java deleted file mode 100644 index 1fbfc5f6717..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersFromLineSubscriber.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification; - -import java.net.http.HttpResponse.BodySubscribers; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.concurrent.Flow.Subscriber; - -/* See TckDriver.java for more information */ -public class BodySubscribersFromLineSubscriber - extends FlowSubscriberBlackboxVerification> { - - public BodySubscribersFromLineSubscriber() { - super(new TestEnvironment(450L)); - } - - @Override - public Subscriber> createFlowSubscriber() { - return BodySubscribers.fromLineSubscriber( - S.nonCompliantSubscriber()); - } - - @Override - public List createElement(int element) { - return S.scatterBuffer( - S.bufferOfNRandomASCIIBytes(element % 17)); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersFromSubscriber.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersFromSubscriber.java deleted file mode 100644 index ca1256cf91c..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersFromSubscriber.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification; - -import java.net.http.HttpResponse.BodySubscribers; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.concurrent.Flow.Subscriber; - -/* See TckDriver.java for more information */ -public class BodySubscribersFromSubscriber - extends FlowSubscriberBlackboxVerification> { - - public BodySubscribersFromSubscriber() { - super(new TestEnvironment(450L)); - } - - @Override - public Subscriber> createFlowSubscriber() { - Subscriber> sub = S.nonCompliantSubscriber(); - return BodySubscribers.fromSubscriber(sub); - } - - @Override - public List createElement(int element) { - return S.scatterBuffer( - S.bufferOfNRandomASCIIBytes(element % 17)); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfByteArrayConsumer.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfByteArrayConsumer.java deleted file mode 100644 index 0dfbdf8eb1a..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfByteArrayConsumer.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification; - -import java.net.http.HttpResponse.BodySubscribers; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.concurrent.Flow.Subscriber; - -/* See TckDriver.java for more information */ -public class BodySubscribersOfByteArrayConsumer - extends FlowSubscriberBlackboxVerification> { - - public BodySubscribersOfByteArrayConsumer() { - super(new TestEnvironment(450L)); - } - - @Override - public Subscriber> createFlowSubscriber() { - return BodySubscribers.ofByteArrayConsumer(bytes -> { }); - } - - @Override - public List createElement(int element) { - return S.listOfBuffersFromBufferOfNBytes(element % 17); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfFile.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfFile.java deleted file mode 100644 index 76a06dfc171..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfFile.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification; - -import java.net.http.HttpResponse.BodySubscribers; -import java.nio.ByteBuffer; -import java.nio.file.Path; -import java.util.List; -import java.util.concurrent.Flow.Subscriber; - -/* See TckDriver.java for more information */ -public class BodySubscribersOfFile - extends FlowSubscriberBlackboxVerification> { - - public BodySubscribersOfFile() { - super(new TestEnvironment(450L)); - } - - @Override - public Subscriber> createFlowSubscriber() { - return BodySubscribers.ofFile(Path.of("f1.bin")); - } - - @Override - public List createElement(int element) { - return S.listOfBuffersFromBufferOfNBytes(element % 17); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfInputStream.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfInputStream.java deleted file mode 100644 index b3330d976b1..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfInputStream.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification; - -import java.net.http.HttpResponse.BodySubscribers; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.concurrent.Flow.Subscriber; - -/* See TckDriver.java for more information */ -public class BodySubscribersOfInputStream - extends FlowSubscriberBlackboxVerification> { - - public BodySubscribersOfInputStream() { - super(new TestEnvironment(450L)); - } - - @Override - public Subscriber> createFlowSubscriber() { - return BodySubscribers.ofInputStream(); - } - - @Override - public List createElement(int element) { - return S.listOfBuffersFromBufferOfNBytes(element % 17); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfLines.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfLines.java deleted file mode 100644 index 4933804631a..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfLines.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification; - -import java.net.http.HttpResponse.BodySubscribers; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.concurrent.Flow.Subscriber; - -/* See TckDriver.java for more information */ -public class BodySubscribersOfLines - extends FlowSubscriberBlackboxVerification> { - - public BodySubscribersOfLines() { - super(new TestEnvironment(450L)); - } - - @Override - public Subscriber> createFlowSubscriber() { - return BodySubscribers.ofLines(StandardCharsets.UTF_8); - } - - @Override - public List createElement(int element) { - return S.scatterBuffer( - S.bufferOfNRandomASCIIBytes(element % 17)); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfPublisher.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfPublisher.java deleted file mode 100644 index 9b274b543e5..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfPublisher.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification; - -import java.net.http.HttpResponse.BodySubscriber; -import java.net.http.HttpResponse.BodySubscribers; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.Flow.Publisher; -import java.util.concurrent.Flow.Subscriber; -import java.util.concurrent.Flow.Subscription; - -/* See TckDriver.java for more information */ -public class BodySubscribersOfPublisher - extends FlowSubscriberBlackboxVerification> { - - public BodySubscribersOfPublisher() { - super(new TestEnvironment(450L)); - } - - /* The reason for overriding this method is that BodySubscribers.ofPublisher - is somewhat tricky. It is not an independent Subscriber, but rather - an adaptor from Subscriber to Publisher. Until the Subscriber that - subscribed to that resulting Publisher requests anything, nothing - happens. */ - @Override - public void triggerFlowRequest( - Subscriber> subscriber) - { - BodySubscriber>> sub = - (BodySubscriber>>) subscriber; - CompletionStage>> body = sub.getBody(); - Publisher> pub = body.toCompletableFuture().join(); - pub.subscribe(new Subscriber<>() { - - @Override - public void onSubscribe(Subscription subscription) { - subscription.request(Integer.MAX_VALUE); - } - - @Override public void onNext(List item) { } - @Override public void onError(Throwable throwable) { } - @Override public void onComplete() { } - }); - } - - @Override - public Subscriber> createFlowSubscriber() { - return BodySubscribers.ofPublisher(); - } - - @Override - public List createElement(int element) { - return S.listOfBuffersFromBufferOfNBytes(element % 17); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfPublisher1.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfPublisher1.java deleted file mode 100644 index ef2b4e98f2b..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfPublisher1.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification; - -import java.net.http.HttpResponse.BodySubscriber; -import java.net.http.HttpResponse.BodySubscribers; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.Flow.Publisher; -import java.util.concurrent.Flow.Subscriber; -import java.util.concurrent.Flow.Subscription; - -/* See TckDriver.java for more information */ -public class BodySubscribersOfPublisher1 - extends FlowSubscriberBlackboxVerification> { - - public BodySubscribersOfPublisher1() { - super(new TestEnvironment(450L)); - } - - /* The reason for overriding this method is that BodySubscribers.ofPublisher - is somewhat tricky. It is not an independent Subscriber, but rather - an adaptor from Subscriber to Publisher. Until the Subscriber that - subscribed to that resulting Publisher requests anything, nothing - happens. */ - @Override - public void triggerFlowRequest( - Subscriber> subscriber) - { - BodySubscriber>> sub = - (BodySubscriber>>) subscriber; - CompletionStage>> body = sub.getBody(); - Publisher> pub = body.toCompletableFuture().join(); - pub.subscribe(new Subscriber<>() { - - Subscription sub; - - @Override - public void onSubscribe(Subscription subscription) { - (sub = subscription).request(1); - } - - @Override public void onNext(List item) { - sub.request(1); - } - - @Override public void onError(Throwable throwable) { } - @Override public void onComplete() { } - }); - } - - @Override - public Subscriber> createFlowSubscriber() { - return BodySubscribers.ofPublisher(); - } - - @Override - public List createElement(int element) { - return S.listOfBuffersFromBufferOfNBytes(element % 17); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfPublisherPublisher.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfPublisherPublisher.java deleted file mode 100644 index 1d8d7aee095..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfPublisherPublisher.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowPublisherVerification; - -import java.net.http.HttpResponse.BodySubscriber; -import java.net.http.HttpResponse.BodySubscribers; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.concurrent.Flow.Publisher; -import java.util.stream.Stream; - -/* See TckDriver.java for more information */ -public class BodySubscribersOfPublisherPublisher - extends FlowPublisherVerification> { - - public BodySubscribersOfPublisherPublisher() { - super(new TestEnvironment(450L)); - } - - @Override - public Publisher> createFlowPublisher(long nElements) { - BodySubscriber>> sub = - BodySubscribers.ofPublisher(); - Stream> buffers = - Stream.generate(() -> S.listOfBuffersFromBufferOfNBytes(1024)) - .limit(nElements); - Publisher> pub = S.publisherOfStream(buffers); - pub.subscribe(sub); - return sub.getBody().toCompletableFuture().join(); - } - - @Override - public Publisher> createFailedFlowPublisher() { - BodySubscriber>> sub = - BodySubscribers.ofPublisher(); - Publisher> pub = S.newErroredPublisher(); - pub.subscribe(sub); - return sub.getBody().toCompletableFuture().join(); - } - - @Override - public long maxElementsFromPublisher() { - return 21; - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfString.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfString.java deleted file mode 100644 index 0d2410ac333..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfString.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification; - -import java.net.http.HttpResponse.BodySubscribers; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.concurrent.Flow.Subscriber; - -/* See TckDriver.java for more information */ -public class BodySubscribersOfString - extends FlowSubscriberBlackboxVerification> { - - public BodySubscribersOfString() { - super(new TestEnvironment(450L)); - } - - @Override - public Subscriber> createFlowSubscriber() { - return BodySubscribers.ofString(StandardCharsets.UTF_8); - } - - @Override - public List createElement(int element) { - return S.scatterBuffer( - S.bufferOfNRandomASCIIBytes(element % 17)); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersReplacing.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersReplacing.java deleted file mode 100644 index cb901f02674..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersReplacing.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification; - -import java.net.http.HttpResponse.BodySubscribers; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.concurrent.Flow.Subscriber; - -/* See TckDriver.java for more information */ -public class BodySubscribersReplacing - extends FlowSubscriberBlackboxVerification> { - - public BodySubscribersReplacing() { - super(new TestEnvironment(450L)); - } - - @Override - public Subscriber> createFlowSubscriber() { - /* it doesn't matter what we are replacing with */ - return BodySubscribers.replacing(Boolean.TRUE); - } - - @Override - public List createElement(int element) { - return S.listOfBuffersFromBufferOfNBytes(element % 17); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/S.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/S.java deleted file mode 100644 index c3f86b753d9..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/S.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (c) 2019, 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.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; -import java.util.Random; -import java.util.concurrent.Flow.Publisher; -import java.util.concurrent.Flow.Subscriber; -import java.util.concurrent.Flow.Subscription; -import java.util.stream.Stream; - -/* - * S for Support. - * - * Auxiliary methods for tests that check conformance with reactive streams - * specification. - * - * Short name is for the sake of convenience calling this class' static methods. - * It could've been called Support or TckSupport, but then we would need to - * place this class in its own package so as to use "import static". - */ -public class S { - - private static final Random RANDOM = new SecureRandom(); - - private S() { } - - public static List listOfBuffersFromBufferOfNBytes(int nBytes) { - return scatterBuffer(bufferOfNRandomBytes(nBytes)); - } - - /* - * Spreads the remaining contents of the given byte buffer across a number - * of buffers put into a list. - */ - public static List scatterBuffer(ByteBuffer src) { - List buffers = new ArrayList<>(); - while (src.hasRemaining()) { - // We do not allow empty buffers ~~~~~~~~~~~~~~~~v - int capacity = RANDOM.nextInt(src.remaining()) + 1; - ByteBuffer b = ByteBuffer.allocate(capacity); - for (int i = 0; i < capacity; i++) { - b.put(src.get()); - } - b.flip(); - buffers.add(b); - } - return List.copyOf(buffers); - } - - public static ByteBuffer bufferOfNRandomBytes(int capacity) { - return ByteBuffer.wrap(arrayOfNRandomBytes(capacity)); - } - - public static byte[] arrayOfNRandomBytes(int nBytes) { - byte[] contents = new byte[nBytes]; - RANDOM.nextBytes(contents); - return contents; - } - - public static InputStream inputStreamOfNReads(long n) { - return new NReadsInputStream(n); - } - - /* - * Convenience method for testing publishers. - */ - public static byte[] arrayOfNRandomBytes(long nBytes) { - return arrayOfNRandomBytes((int) nBytes); - } - - public static ByteBuffer bufferOfNRandomASCIIBytes(int capacity) { - String alphaNumeric = "abcdefghijklmnopqrstuvwxyz1234567890"; - StringBuilder builder = new StringBuilder(capacity); - for (int i = 0; i < capacity; i++) { - int idx = RANDOM.nextInt(alphaNumeric.length()); - builder.append(alphaNumeric.charAt(idx)); - } - return ByteBuffer.wrap(builder.toString().getBytes( - StandardCharsets.US_ASCII)); - } - - /* - * Returns a simple non-compliant Subscriber. - * - * This Subscriber is useful for testing our adaptors and wrappers, to make - * sure they do not delegate RS compliance to the underlying (and foreign to - * java.net.http codebase) Subscribers, but rather comply themselves. - * - * Here's an example: - * - * public void onSubscribe(Subscription s) { - * delegate.onSubscribe(s); - * } - * - * The snippet above cannot be considered a good implementation of a - * Subscriber if `delegate` is an unknown Subscriber. In this case the - * implementation should independently check all the rules from the RS spec - * related to subscribers. - */ - public static Subscriber nonCompliantSubscriber() { - return new Subscriber<>() { - - @Override - public void onSubscribe(Subscription subscription) { - subscription.request(Long.MAX_VALUE); - } - - @Override - public void onNext(T item) { } - - @Override - public void onError(Throwable throwable) { } - - @Override - public void onComplete() { } - }; - } - - public static int randomIntUpTo(int bound) { - return RANDOM.nextInt(bound); - } - - /* - * Signals an error to its subscribers immediately after subscription. - */ - public static Publisher newErroredPublisher() { - return subscriber -> { - subscriber.onSubscribe(new Subscription() { - @Override - public void request(long n) { } - - @Override - public void cancel() { } - }); - subscriber.onError(new IOException()); - }; - } - - /* - * Publishes the elements obtained from the stream and signals completion. - * Can be cancelled, but cannot signal an error. - * - * This trivial ad-hoc implementation of Publisher was created so as to - * publish lists of byte buffers. We can publish ByteBuffer, but we can't - * seem to publish List since there's no readily available - * publisher of those, nor there's a simple adaptor. - */ - public static Publisher publisherOfStream(Stream stream) - { - if (stream == null) { - throw new NullPointerException(); - } - return new Publisher() { - @Override - public void subscribe(Subscriber subscriber) { - if (subscriber == null) { - throw new NullPointerException(); - } - Subscription subscription = new Subscription() { - - boolean inOnNext; // recursion control - volatile boolean cancelled; - long demand; - final Iterator supply = stream.iterator(); - - @Override - public void request(long n) { - demand = demand + n < 0 ? Long.MAX_VALUE : demand + n; - if (inOnNext) { - return; - } - if (cancelled) - return; - if (n <= 0) { - cancelled = true; - subscriber.onError(new IllegalArgumentException( - "non-positive subscription request")); - return; - } - while (supply.hasNext() && demand > 0 && !cancelled) { - demand--; - inOnNext = true; - try { - T item = supply.next(); - subscriber.onNext(item); - } finally { - inOnNext = false; - } - } - if (!supply.hasNext()) { - cancelled = true; - subscriber.onComplete(); - } - } - - @Override - public void cancel() { - cancelled = true; - } - }; - subscriber.onSubscribe(subscription); - } - }; - } - - static final class NReadsInputStream extends InputStream { - - private static final int EOF = -1; - private long readsLeft; - - NReadsInputStream(long n) { - if (n < 0) { - throw new IllegalArgumentException(String.valueOf(n)); - } - this.readsLeft = n; - } - - @Override - public int read() { - if (readsLeft == 0L) { - return EOF; - } - readsLeft--; - return S.randomIntUpTo(256); - } - - @Override - public int read(byte[] b, int off, int len) { - Objects.checkFromIndexSize(off, len, b.length); - // Must return 0 if len == 0, - // even if there are no more reads left - if (len == 0) { - return 0; - } - if (readsLeft == 0L) { - return EOF; - } - readsLeft--; - // At least one byte MUST be read, but we can read - // less than `len` bytes - int r = RANDOM.nextInt(len) + 1; - for (int i = 0; i < r; i++) { - b[i] = (byte) randomIntUpTo(256); - } - return r; - } - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/STest.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/STest.java deleted file mode 100644 index a762b4edf1e..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/STest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.List; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; - -public class STest { - - @DataProvider(name = "bufferSizes") - public static Object[][] bufferSizes() { - return new Object[][]{ - { 1}, - { 2}, - { 3}, - { 4}, - {16}, - {17}, - }; - } - - @DataProvider - public static Object[][] inputStream() { - return new Object[][] { - { 0, 1}, - { 1, 2}, - { 1, 3}, - { 1, 4}, - { 2, 1}, - { 2, 2}, - { 2, 3}, - { 2, 4}, - { 2, 13}, - { 3, 1}, - { 3, 2}, - { 3, 3}, - { 3, 4}, - { 3, 17}, - { 4, 1}, - { 4, 2}, - { 4, 3}, - { 4, 4}, - { 4, 5}, - { 13, 1}, - { 13, 2}, - { 13, 13}, - { 16, 18}, - { 17, 2}, - {255, 1}, - {256, 255}, - {257, 267}, - }; - } - - @Test - public void testScatter0() { - List buffers = S.scatterBuffer( - ByteBuffer.allocate(0)); - assertEquals(buffers.size(), 0); - } - - @Test(dataProvider = "bufferSizes") - public void testScatterN(int n) { - final ByteBuffer src = S.bufferOfNRandomBytes(n); - final int srcLength = src.remaining(); - ByteBuffer copy = ByteBuffer.wrap(Arrays.copyOf(src.array(), - src.array().length)); - List buffers = S.scatterBuffer(src); - int m = 0; - for (ByteBuffer b : buffers) { - m += b.remaining(); - while (b.hasRemaining() & copy.hasRemaining()) { - assertEquals(b.get(), copy.get()); - } - } - assertEquals(m, srcLength); - } - - @Test(dataProvider = "inputStream") - public void testInputStreamOfNReads(int n, int capacity) throws IOException { - InputStream s = S.inputStreamOfNReads(n); - int count = 0; - byte[] b = new byte[capacity]; - while (s.read(b) != -1) { - count++; - } - assertEquals(count, n); - assertTrue(s.read() == -1); - assertTrue(s.read(b) == -1); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/TckDriver.java b/test/jdk/java/net/httpclient/reactivestreams-tck-tests/TckDriver.java deleted file mode 100644 index c7e08eff523..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/TckDriver.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2019, 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 8226602 - * @summary Tests convenience reactive primitives with RS TCK - * - * @library ../reactivestreams-tck - * @build S - * - * @compile -encoding UTF-8 SPublisherOfStream.java - * - * @compile -encoding UTF-8 BodyPublishersFromPublisher.java - * @compile -encoding UTF-8 BodyPublishersNoBody.java - * @compile -encoding UTF-8 BodyPublishersOfByteArray.java - * @compile -encoding UTF-8 BodyPublishersOfByteArrays.java - * @compile -encoding UTF-8 BodyPublishersOfFile.java - * @compile -encoding UTF-8 BodyPublishersOfInputStream.java - * @compile -encoding UTF-8 BodyPublishersOfSubByteArray.java - * @compile -encoding UTF-8 BodyPublishersConcat.java - * - * @compile -encoding UTF-8 BodySubscribersBuffering.java - * @compile -encoding UTF-8 BodySubscribersDiscarding.java - * @compile -encoding UTF-8 BodySubscribersFromLineSubscriber.java - * @compile -encoding UTF-8 BodySubscribersFromSubscriber.java - * @compile -encoding UTF-8 BodySubscribersMapping.java - * @compile -encoding UTF-8 BodySubscribersOfByteArray.java - * @compile -encoding UTF-8 BodySubscribersOfByteArrayConsumer.java - * @compile -encoding UTF-8 BodySubscribersOfFile.java - * @compile -encoding UTF-8 BodySubscribersOfInputStream.java - * @compile -encoding UTF-8 BodySubscribersOfLines.java - * @compile -encoding UTF-8 BodySubscribersOfPublisher.java - * @compile -encoding UTF-8 BodySubscribersOfPublisher1.java - * @compile -encoding UTF-8 BodySubscribersOfPublisherPublisher.java - * @compile -encoding UTF-8 BodySubscribersOfString.java - * @compile -encoding UTF-8 BodySubscribersReplacing.java - * - * @run testng/othervm STest - * @run testng/othervm SPublisherOfStream - * - * @run testng/othervm BodyPublishersFromPublisher - * @run testng/othervm BodyPublishersNoBody - * @run testng/othervm BodyPublishersOfByteArray - * @run testng/othervm BodyPublishersOfByteArrays - * @run testng/othervm BodyPublishersOfFile - * @run testng/othervm BodyPublishersOfInputStream - * @run testng/othervm BodyPublishersOfSubByteArray - * @run testng/othervm BodyPublishersConcat - * - * @run testng/othervm BodySubscribersBuffering - * @run testng/othervm BodySubscribersDiscarding - * @run testng/othervm BodySubscribersFromLineSubscriber - * @run testng/othervm BodySubscribersFromSubscriber - * @run testng/othervm BodySubscribersMapping - * @run testng/othervm BodySubscribersOfByteArray - * @run testng/othervm BodySubscribersOfByteArrayConsumer - * @run testng/othervm BodySubscribersOfFile - * @run testng/othervm BodySubscribersOfInputStream - * @run testng/othervm BodySubscribersOfLines - * @run testng/othervm BodySubscribersOfPublisher - * @run testng/othervm BodySubscribersOfPublisher1 - * @run testng/othervm BodySubscribersOfPublisherPublisher - * @run testng/othervm BodySubscribersOfString - * @run testng/othervm BodySubscribersReplacing - * - * @key randomness - */ -public class TckDriver { - /* - #### General Information - - 1. This JTREG test aggregates multiple TestNG tests. This is because - these tests share a common library (reactivestreams-tck), and we don't - want this library to be compiled separately for each of those tests. - - 2. Tests that use RS TCK are compiled with the UTF-8 encoding. This is - performed for the sake of reactivestreams-tck. We don't want to patch - the TCK because of the extra merging work in the future, should we bring - update(s) from the RS repo. - - #### Tests - - 1. The purpose of each test should be easily digestible. The name of the - test is derived from the very entity the test exercises. For example, - - the BodyPublishersOfFile test exercises the BodyPublisher obtained - by calling BodyPublishers.ofFile(Path) - - the BodySubscribersOfFile test exercises the BodySubscriber obtained - by calling BodySubscribers.ofFile(Path) - - 2. RS TCK requires PublisherVerification tests to produce publishers - capable of emitting a certain number of elements. In order to achieve - this, we use some knowledge of the internal workings of our publishers. - An example would be a chunk size a publisher uses to deliver a portion - of data. Without knowing that it is not possible to guarantee that the - publisher will emit a particular number of elements. - - 3. Typically our publishers cannot be created in a known failed state. - In this case the corresponding `createFailedFlowPublisher` method - returns `null`. - - 4. SubscriberBlackBoxVerification uses the `createElement(int element)` - method. Our implementations usually cap the amount of data created by - this method, because it's not known beforehand how big the `element` - value is. Hence, sometimes there's code like as follows: - - @Override - public List createElement(int element) { - return scatterBuffer( - bufferOfNRandomASCIIBytes(element % 17)); - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ - } - - 5. The amount of testing RS TCK performs on a publisher seems to depend - on the number of elements this publisher reports it can emit. Sometimes - a code like the following can be seen in the tests: - - @Override public long maxElementsFromPublisher() { - return 21; - ~~~~~~~~~~~^ - } - - This magic number is a result of trial and error and seems to unlock - most of the tests. Reporting big values (e.g. Long.MAX_VALUE - 1) is - not an option for most of our publishers because they require to have - all the elements upfront. - - 6. It doesn't seem currently feasible to provide SubscriberWhiteboxVerification - tests as a) it's not clear how much better the coverage is and b) it's - significantly harder to code that. - - #### S (Support) - - Support utilities are being tested (STest) too. - */ -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/FlowAdapters.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/FlowAdapters.java deleted file mode 100644 index 8452dcd5539..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/FlowAdapters.java +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams; - -import java.util.concurrent.Flow; -import static java.util.Objects.requireNonNull; - -/** - * Bridge between Reactive Streams API and the Java 9 {@link java.util.concurrent.Flow} API. - */ -public final class FlowAdapters { - /** Utility class. */ - private FlowAdapters() { - throw new IllegalStateException("No instances!"); - } - - /** - * Converts a Flow Publisher into a Reactive Streams Publisher. - * @param the element type - * @param flowPublisher the source Flow Publisher to convert - * @return the equivalent Reactive Streams Publisher - */ - @SuppressWarnings("unchecked") - public static org.reactivestreams.Publisher toPublisher( - Flow.Publisher flowPublisher) { - requireNonNull(flowPublisher, "flowPublisher"); - final org.reactivestreams.Publisher publisher; - if (flowPublisher instanceof FlowPublisherFromReactive) { - publisher = (org.reactivestreams.Publisher)(((FlowPublisherFromReactive)flowPublisher).reactiveStreams); - } else if (flowPublisher instanceof org.reactivestreams.Publisher) { - publisher = (org.reactivestreams.Publisher)flowPublisher; - } else { - publisher = new ReactivePublisherFromFlow(flowPublisher); - } - return publisher; - } - - /** - * Converts a Reactive Streams Publisher into a Flow Publisher. - * @param the element type - * @param reactiveStreamsPublisher the source Reactive Streams Publisher to convert - * @return the equivalent Flow Publisher - */ - @SuppressWarnings("unchecked") - public static Flow.Publisher toFlowPublisher( - org.reactivestreams.Publisher reactiveStreamsPublisher - ) { - requireNonNull(reactiveStreamsPublisher, "reactiveStreamsPublisher"); - final Flow.Publisher flowPublisher; - if (reactiveStreamsPublisher instanceof ReactivePublisherFromFlow) { - flowPublisher = (Flow.Publisher)(((ReactivePublisherFromFlow)reactiveStreamsPublisher).flow); - } else if (reactiveStreamsPublisher instanceof Flow.Publisher) { - flowPublisher = (Flow.Publisher)reactiveStreamsPublisher; - } else { - flowPublisher = new FlowPublisherFromReactive(reactiveStreamsPublisher); - } - return flowPublisher; - } - - /** - * Converts a Flow Processor into a Reactive Streams Processor. - * @param the input value type - * @param the output value type - * @param flowProcessor the source Flow Processor to convert - * @return the equivalent Reactive Streams Processor - */ - @SuppressWarnings("unchecked") - public static org.reactivestreams.Processor toProcessor( - Flow.Processor flowProcessor - ) { - requireNonNull(flowProcessor, "flowProcessor"); - final org.reactivestreams.Processor processor; - if (flowProcessor instanceof FlowToReactiveProcessor) { - processor = (org.reactivestreams.Processor)(((FlowToReactiveProcessor)flowProcessor).reactiveStreams); - } else if (flowProcessor instanceof org.reactivestreams.Processor) { - processor = (org.reactivestreams.Processor)flowProcessor; - } else { - processor = new ReactiveToFlowProcessor(flowProcessor); - } - return processor; - } - - /** - * Converts a Reactive Streams Processor into a Flow Processor. - * @param the input value type - * @param the output value type - * @param reactiveStreamsProcessor the source Reactive Streams Processor to convert - * @return the equivalent Flow Processor - */ - @SuppressWarnings("unchecked") - public static Flow.Processor toFlowProcessor( - org.reactivestreams.Processor reactiveStreamsProcessor - ) { - requireNonNull(reactiveStreamsProcessor, "reactiveStreamsProcessor"); - final Flow.Processor flowProcessor; - if (reactiveStreamsProcessor instanceof ReactiveToFlowProcessor) { - flowProcessor = (Flow.Processor)(((ReactiveToFlowProcessor)reactiveStreamsProcessor).flow); - } else if (reactiveStreamsProcessor instanceof Flow.Processor) { - flowProcessor = (Flow.Processor)reactiveStreamsProcessor; - } else { - flowProcessor = new FlowToReactiveProcessor(reactiveStreamsProcessor); - } - return flowProcessor; - } - - /** - * Converts a Reactive Streams Subscriber into a Flow Subscriber. - * @param the input and output value type - * @param reactiveStreamsSubscriber the Reactive Streams Subscriber instance to convert - * @return the equivalent Flow Subscriber - */ - @SuppressWarnings("unchecked") - public static Flow.Subscriber toFlowSubscriber(org.reactivestreams.Subscriber reactiveStreamsSubscriber) { - requireNonNull(reactiveStreamsSubscriber, "reactiveStreamsSubscriber"); - final Flow.Subscriber flowSubscriber; - if (reactiveStreamsSubscriber instanceof ReactiveToFlowSubscriber) { - flowSubscriber = (Flow.Subscriber)((ReactiveToFlowSubscriber)reactiveStreamsSubscriber).flow; - } else if (reactiveStreamsSubscriber instanceof Flow.Subscriber) { - flowSubscriber = (Flow.Subscriber)reactiveStreamsSubscriber; - } else { - flowSubscriber = new FlowToReactiveSubscriber(reactiveStreamsSubscriber); - } - return flowSubscriber; - } - - /** - * Converts a Flow Subscriber into a Reactive Streams Subscriber. - * @param the input and output value type - * @param flowSubscriber the Flow Subscriber instance to convert - * @return the equivalent Reactive Streams Subscriber - */ - @SuppressWarnings("unchecked") - public static org.reactivestreams.Subscriber toSubscriber(Flow.Subscriber flowSubscriber) { - requireNonNull(flowSubscriber, "flowSubscriber"); - final org.reactivestreams.Subscriber subscriber; - if (flowSubscriber instanceof FlowToReactiveSubscriber) { - subscriber = (org.reactivestreams.Subscriber)((FlowToReactiveSubscriber)flowSubscriber).reactiveStreams; - } else if (flowSubscriber instanceof org.reactivestreams.Subscriber) { - subscriber = (org.reactivestreams.Subscriber)flowSubscriber; - } else { - subscriber = new ReactiveToFlowSubscriber(flowSubscriber); - } - return subscriber; - } - - /** - * Wraps a Reactive Streams Subscription and converts the calls to a Flow Subscription. - */ - static final class FlowToReactiveSubscription implements Flow.Subscription { - final org.reactivestreams.Subscription reactiveStreams; - - public FlowToReactiveSubscription(org.reactivestreams.Subscription reactive) { - this.reactiveStreams = reactive; - } - - @Override - public void request(long n) { - reactiveStreams.request(n); - } - - @Override - public void cancel() { - reactiveStreams.cancel(); - } - - } - - /** - * Wraps a Flow Subscription and converts the calls to a Reactive Streams Subscription. - */ - static final class ReactiveToFlowSubscription implements org.reactivestreams.Subscription { - final Flow.Subscription flow; - - public ReactiveToFlowSubscription(Flow.Subscription flow) { - this.flow = flow; - } - - @Override - public void request(long n) { - flow.request(n); - } - - @Override - public void cancel() { - flow.cancel(); - } - - - } - - /** - * Wraps a Reactive Streams Subscriber and forwards methods of the Flow Subscriber to it. - * @param the element type - */ - static final class FlowToReactiveSubscriber implements Flow.Subscriber { - final org.reactivestreams.Subscriber reactiveStreams; - - public FlowToReactiveSubscriber(org.reactivestreams.Subscriber reactive) { - this.reactiveStreams = reactive; - } - - @Override - public void onSubscribe(Flow.Subscription subscription) { - reactiveStreams.onSubscribe((subscription == null) ? null : new ReactiveToFlowSubscription(subscription)); - } - - @Override - public void onNext(T item) { - reactiveStreams.onNext(item); - } - - @Override - public void onError(Throwable throwable) { - reactiveStreams.onError(throwable); - } - - @Override - public void onComplete() { - reactiveStreams.onComplete(); - } - - } - - /** - * Wraps a Flow Subscriber and forwards methods of the Reactive Streams Subscriber to it. - * @param the element type - */ - static final class ReactiveToFlowSubscriber implements org.reactivestreams.Subscriber { - final Flow.Subscriber flow; - - public ReactiveToFlowSubscriber(Flow.Subscriber flow) { - this.flow = flow; - } - - @Override - public void onSubscribe(org.reactivestreams.Subscription subscription) { - flow.onSubscribe((subscription == null) ? null : new FlowToReactiveSubscription(subscription)); - } - - @Override - public void onNext(T item) { - flow.onNext(item); - } - - @Override - public void onError(Throwable throwable) { - flow.onError(throwable); - } - - @Override - public void onComplete() { - flow.onComplete(); - } - - } - - /** - * Wraps a Flow Processor and forwards methods of the Reactive Streams Processor to it. - * @param the input type - * @param the output type - */ - static final class ReactiveToFlowProcessor implements org.reactivestreams.Processor { - final Flow.Processor flow; - - public ReactiveToFlowProcessor(Flow.Processor flow) { - this.flow = flow; - } - - @Override - public void onSubscribe(org.reactivestreams.Subscription subscription) { - flow.onSubscribe((subscription == null) ? null : new FlowToReactiveSubscription(subscription)); - } - - @Override - public void onNext(T t) { - flow.onNext(t); - } - - @Override - public void onError(Throwable t) { - flow.onError(t); - } - - @Override - public void onComplete() { - flow.onComplete(); - } - - @Override - public void subscribe(org.reactivestreams.Subscriber s) { - flow.subscribe((s == null) ? null : new FlowToReactiveSubscriber(s)); - } - } - - /** - * Wraps a Reactive Streams Processor and forwards methods of the Flow Processor to it. - * @param the input type - * @param the output type - */ - static final class FlowToReactiveProcessor implements Flow.Processor { - final org.reactivestreams.Processor reactiveStreams; - - public FlowToReactiveProcessor(org.reactivestreams.Processor reactive) { - this.reactiveStreams = reactive; - } - - @Override - public void onSubscribe(Flow.Subscription subscription) { - reactiveStreams.onSubscribe((subscription == null) ? null : new ReactiveToFlowSubscription(subscription)); - } - - @Override - public void onNext(T t) { - reactiveStreams.onNext(t); - } - - @Override - public void onError(Throwable t) { - reactiveStreams.onError(t); - } - - @Override - public void onComplete() { - reactiveStreams.onComplete(); - } - - @Override - public void subscribe(Flow.Subscriber s) { - reactiveStreams.subscribe((s == null) ? null : new ReactiveToFlowSubscriber(s)); - } - } - - /** - * Reactive Streams Publisher that wraps a Flow Publisher. - * @param the element type - */ - static final class ReactivePublisherFromFlow implements org.reactivestreams.Publisher { - final Flow.Publisher flow; - - public ReactivePublisherFromFlow(Flow.Publisher flowPublisher) { - this.flow = flowPublisher; - } - - @Override - public void subscribe(org.reactivestreams.Subscriber reactive) { - flow.subscribe((reactive == null) ? null : new FlowToReactiveSubscriber(reactive)); - } - } - - /** - * Flow Publisher that wraps a Reactive Streams Publisher. - * @param the element type - */ - static final class FlowPublisherFromReactive implements Flow.Publisher { - - final org.reactivestreams.Publisher reactiveStreams; - - public FlowPublisherFromReactive(org.reactivestreams.Publisher reactivePublisher) { - this.reactiveStreams = reactivePublisher; - } - - @Override - public void subscribe(Flow.Subscriber flow) { - reactiveStreams.subscribe((flow == null) ? null : new ReactiveToFlowSubscriber(flow)); - } - } - -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Publisher.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Publisher.java deleted file mode 100644 index ea6eb2908e0..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Publisher.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams; - -/** - * A {@link Publisher} is a provider of a potentially unbounded number of sequenced elements, publishing them according to - * the demand received from its {@link Subscriber}(s). - *

- * A {@link Publisher} can serve multiple {@link Subscriber}s subscribed {@link #subscribe(Subscriber)} dynamically - * at various points in time. - * - * @param the type of element signaled. - */ -public interface Publisher { - - /** - * Request {@link Publisher} to start streaming data. - *

- * This is a "factory method" and can be called multiple times, each time starting a new {@link Subscription}. - *

- * Each {@link Subscription} will work for only a single {@link Subscriber}. - *

- * A {@link Subscriber} should only subscribe once to a single {@link Publisher}. - *

- * If the {@link Publisher} rejects the subscription attempt or otherwise fails it will - * signal the error via {@link Subscriber#onError}. - * - * @param s the {@link Subscriber} that will consume signals from this {@link Publisher} - */ - public void subscribe(Subscriber s); -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Subscriber.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Subscriber.java deleted file mode 100644 index 5ce405aa430..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Subscriber.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams; - -/** - * Will receive call to {@link #onSubscribe(Subscription)} once after passing an instance of {@link Subscriber} to {@link Publisher#subscribe(Subscriber)}. - *

- * No further notifications will be received until {@link Subscription#request(long)} is called. - *

- * After signaling demand: - *

    - *
  • One or more invocations of {@link #onNext(Object)} up to the maximum number defined by {@link Subscription#request(long)}
  • - *
  • Single invocation of {@link #onError(Throwable)} or {@link Subscriber#onComplete()} which signals a terminal state after which no further events will be sent. - *
- *

- * Demand can be signaled via {@link Subscription#request(long)} whenever the {@link Subscriber} instance is capable of handling more. - * - * @param the type of element signaled. - */ -public interface Subscriber { - /** - * Invoked after calling {@link Publisher#subscribe(Subscriber)}. - *

- * No data will start flowing until {@link Subscription#request(long)} is invoked. - *

- * It is the responsibility of this {@link Subscriber} instance to call {@link Subscription#request(long)} whenever more data is wanted. - *

- * The {@link Publisher} will send notifications only in response to {@link Subscription#request(long)}. - * - * @param s - * {@link Subscription} that allows requesting data via {@link Subscription#request(long)} - */ - public void onSubscribe(Subscription s); - - /** - * Data notification sent by the {@link Publisher} in response to requests to {@link Subscription#request(long)}. - * - * @param t the element signaled - */ - public void onNext(T t); - - /** - * Failed terminal state. - *

- * No further events will be sent even if {@link Subscription#request(long)} is invoked again. - * - * @param t the throwable signaled - */ - public void onError(Throwable t); - - /** - * Successful terminal state. - *

- * No further events will be sent even if {@link Subscription#request(long)} is invoked again. - */ - public void onComplete(); -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Subscription.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Subscription.java deleted file mode 100644 index 244ac672e05..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/Subscription.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams; - -/** - * A {@link Subscription} represents a one-to-one lifecycle of a {@link Subscriber} subscribing to a {@link Publisher}. - *

- * It can only be used once by a single {@link Subscriber}. - *

- * It is used to both signal desire for data and cancel demand (and allow resource cleanup). - * - */ -public interface Subscription { - /** - * No events will be sent by a {@link Publisher} until demand is signaled via this method. - *

- * It can be called however often and whenever needed—but if the outstanding cumulative demand ever becomes Long.MAX_VALUE or more, - * it may be treated by the {@link Publisher} as "effectively unbounded". - *

- * Whatever has been requested can be sent by the {@link Publisher} so only signal demand for what can be safely handled. - *

- * A {@link Publisher} can send less than is requested if the stream ends but - * then must emit either {@link Subscriber#onError(Throwable)} or {@link Subscriber#onComplete()}. - * - * @param n the strictly positive number of elements to requests to the upstream {@link Publisher} - */ - public void request(long n); - - /** - * Request the {@link Publisher} to stop sending data and clean up resources. - *

- * Data may still be sent to meet previously signalled demand after calling cancel. - */ - public void cancel(); -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/AsyncIterablePublisher.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/AsyncIterablePublisher.java deleted file mode 100644 index ed09f07bd84..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/AsyncIterablePublisher.java +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.example.unicast; - -import org.reactivestreams.Publisher; -import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; - -import java.util.Iterator; -import java.util.Collections; -import java.util.concurrent.Executor; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.ConcurrentLinkedQueue; - -/** - * AsyncIterablePublisher is an implementation of Reactive Streams `Publisher` - * which executes asynchronously, using a provided `Executor` and produces elements - * from a given `Iterable` in a "unicast" configuration to its `Subscribers`. - * - * NOTE: The code below uses a lot of try-catches to show the reader where exceptions can be expected, and where they are forbidden. - */ -public class AsyncIterablePublisher implements Publisher { - private final static int DEFAULT_BATCHSIZE = 1024; - - private final Iterable elements; // This is our data source / generator - private final Executor executor; // This is our thread pool, which will make sure that our Publisher runs asynchronously to its Subscribers - private final int batchSize; // In general, if one uses an `Executor`, one should be nice nad not hog a thread for too long, this is the cap for that, in elements - - public AsyncIterablePublisher(final Iterable elements, final Executor executor) { - this(elements, DEFAULT_BATCHSIZE, executor); - } - - public AsyncIterablePublisher(final Iterable elements, final int batchSize, final Executor executor) { - if (elements == null) throw null; - if (executor == null) throw null; - if (batchSize < 1) throw new IllegalArgumentException("batchSize must be greater than zero!"); - this.elements = elements; - this.executor = executor; - this.batchSize = batchSize; - } - - @Override - public void subscribe(final Subscriber s) { - // As per rule 1.11, we have decided to support multiple subscribers in a unicast configuration - // for this `Publisher` implementation. - // As per 2.13, this method must return normally (i.e. not throw) - new SubscriptionImpl(s).init(); - } - - // These represent the protocol of the `AsyncIterablePublishers` SubscriptionImpls - static interface Signal {}; - enum Cancel implements Signal { Instance; }; - enum Subscribe implements Signal { Instance; }; - enum Send implements Signal { Instance; }; - static final class Request implements Signal { - final long n; - Request(final long n) { - this.n = n; - } - }; - - // This is our implementation of the Reactive Streams `Subscription`, - // which represents the association between a `Publisher` and a `Subscriber`. - final class SubscriptionImpl implements Subscription, Runnable { - final Subscriber subscriber; // We need a reference to the `Subscriber` so we can talk to it - private boolean cancelled = false; // This flag will track whether this `Subscription` is to be considered cancelled or not - private long demand = 0; // Here we track the current demand, i.e. what has been requested but not yet delivered - private Iterator iterator; // This is our cursor into the data stream, which we will send to the `Subscriber` - - SubscriptionImpl(final Subscriber subscriber) { - // As per rule 1.09, we need to throw a `java.lang.NullPointerException` if the `Subscriber` is `null` - if (subscriber == null) throw null; - this.subscriber = subscriber; - } - - // This `ConcurrentLinkedQueue` will track signals that are sent to this `Subscription`, like `request` and `cancel` - private final ConcurrentLinkedQueue inboundSignals = new ConcurrentLinkedQueue(); - - // We are using this `AtomicBoolean` to make sure that this `Subscription` doesn't run concurrently with itself, - // which would violate rule 1.3 among others (no concurrent notifications). - private final AtomicBoolean on = new AtomicBoolean(false); - - // This method will register inbound demand from our `Subscriber` and validate it against rule 3.9 and rule 3.17 - private void doRequest(final long n) { - if (n < 1) - terminateDueTo(new IllegalArgumentException(subscriber + " violated the Reactive Streams rule 3.9 by requesting a non-positive number of elements.")); - else if (demand + n < 1) { - // As governed by rule 3.17, when demand overflows `Long.MAX_VALUE` we treat the signalled demand as "effectively unbounded" - demand = Long.MAX_VALUE; // Here we protect from the overflow and treat it as "effectively unbounded" - doSend(); // Then we proceed with sending data downstream - } else { - demand += n; // Here we record the downstream demand - doSend(); // Then we can proceed with sending data downstream - } - } - - // This handles cancellation requests, and is idempotent, thread-safe and not synchronously performing heavy computations as specified in rule 3.5 - private void doCancel() { - cancelled = true; - } - - // Instead of executing `subscriber.onSubscribe` synchronously from within `Publisher.subscribe` - // we execute it asynchronously, this is to avoid executing the user code (`Iterable.iterator`) on the calling thread. - // It also makes it easier to follow rule 1.9 - private void doSubscribe() { - try { - iterator = elements.iterator(); - if (iterator == null) - iterator = Collections.emptyList().iterator(); // So we can assume that `iterator` is never null - } catch(final Throwable t) { - subscriber.onSubscribe(new Subscription() { // We need to make sure we signal onSubscribe before onError, obeying rule 1.9 - @Override public void cancel() {} - @Override public void request(long n) {} - }); - terminateDueTo(t); // Here we send onError, obeying rule 1.09 - } - - if (!cancelled) { - // Deal with setting up the subscription with the subscriber - try { - subscriber.onSubscribe(this); - } catch(final Throwable t) { // Due diligence to obey 2.13 - terminateDueTo(new IllegalStateException(subscriber + " violated the Reactive Streams rule 2.13 by throwing an exception from onSubscribe.", t)); - } - - // Deal with already complete iterators promptly - boolean hasElements = false; - try { - hasElements = iterator.hasNext(); - } catch(final Throwable t) { - terminateDueTo(t); // If hasNext throws, there's something wrong and we need to signal onError as per 1.2, 1.4, - } - - // If we don't have anything to deliver, we're already done, so lets do the right thing and - // not wait for demand to deliver `onComplete` as per rule 1.2 and 1.3 - if (!hasElements) { - try { - doCancel(); // Rule 1.6 says we need to consider the `Subscription` cancelled when `onComplete` is signalled - subscriber.onComplete(); - } catch(final Throwable t) { // As per rule 2.13, `onComplete` is not allowed to throw exceptions, so we do what we can, and log this. - (new IllegalStateException(subscriber + " violated the Reactive Streams rule 2.13 by throwing an exception from onComplete.", t)).printStackTrace(System.err); - } - } - } - } - - // This is our behavior for producing elements downstream - private void doSend() { - try { - // In order to play nice with the `Executor` we will only send at-most `batchSize` before - // rescheduing ourselves and relinquishing the current thread. - int leftInBatch = batchSize; - do { - T next; - boolean hasNext; - try { - next = iterator.next(); // We have already checked `hasNext` when subscribing, so we can fall back to testing -after- `next` is called. - hasNext = iterator.hasNext(); // Need to keep track of End-of-Stream - } catch (final Throwable t) { - terminateDueTo(t); // If `next` or `hasNext` throws (they can, since it is user-provided), we need to treat the stream as errored as per rule 1.4 - return; - } - subscriber.onNext(next); // Then we signal the next element downstream to the `Subscriber` - if (!hasNext) { // If we are at End-of-Stream - doCancel(); // We need to consider this `Subscription` as cancelled as per rule 1.6 - subscriber.onComplete(); // Then we signal `onComplete` as per rule 1.2 and 1.5 - } - } while (!cancelled // This makes sure that rule 1.8 is upheld, i.e. we need to stop signalling "eventually" - && --leftInBatch > 0 // This makes sure that we only send `batchSize` number of elements in one go (so we can yield to other Runnables) - && --demand > 0); // This makes sure that rule 1.1 is upheld (sending more than was demanded) - - if (!cancelled && demand > 0) // If the `Subscription` is still alive and well, and we have demand to satisfy, we signal ourselves to send more data - signal(Send.Instance); - } catch(final Throwable t) { - // We can only get here if `onNext` or `onComplete` threw, and they are not allowed to according to 2.13, so we can only cancel and log here. - doCancel(); // Make sure that we are cancelled, since we cannot do anything else since the `Subscriber` is faulty. - (new IllegalStateException(subscriber + " violated the Reactive Streams rule 2.13 by throwing an exception from onNext or onComplete.", t)).printStackTrace(System.err); - } - } - - // This is a helper method to ensure that we always `cancel` when we signal `onError` as per rule 1.6 - private void terminateDueTo(final Throwable t) { - cancelled = true; // When we signal onError, the subscription must be considered as cancelled, as per rule 1.6 - try { - subscriber.onError(t); // Then we signal the error downstream, to the `Subscriber` - } catch(final Throwable t2) { // If `onError` throws an exception, this is a spec violation according to rule 1.9, and all we can do is to log it. - (new IllegalStateException(subscriber + " violated the Reactive Streams rule 2.13 by throwing an exception from onError.", t2)).printStackTrace(System.err); - } - } - - // What `signal` does is that it sends signals to the `Subscription` asynchronously - private void signal(final Signal signal) { - if (inboundSignals.offer(signal)) // No need to null-check here as ConcurrentLinkedQueue does this for us - tryScheduleToExecute(); // Then we try to schedule it for execution, if it isn't already - } - - // This is the main "event loop" if you so will - @Override public final void run() { - if(on.get()) { // establishes a happens-before relationship with the end of the previous run - try { - final Signal s = inboundSignals.poll(); // We take a signal off the queue - if (!cancelled) { // to make sure that we follow rule 1.8, 3.6 and 3.7 - - // Below we simply unpack the `Signal`s and invoke the corresponding methods - if (s instanceof Request) - doRequest(((Request)s).n); - else if (s == Send.Instance) - doSend(); - else if (s == Cancel.Instance) - doCancel(); - else if (s == Subscribe.Instance) - doSubscribe(); - } - } finally { - on.set(false); // establishes a happens-before relationship with the beginning of the next run - if(!inboundSignals.isEmpty()) // If we still have signals to process - tryScheduleToExecute(); // Then we try to schedule ourselves to execute again - } - } - } - - // This method makes sure that this `Subscription` is only running on one Thread at a time, - // this is important to make sure that we follow rule 1.3 - private final void tryScheduleToExecute() { - if(on.compareAndSet(false, true)) { - try { - executor.execute(this); - } catch(Throwable t) { // If we can't run on the `Executor`, we need to fail gracefully - if (!cancelled) { - doCancel(); // First of all, this failure is not recoverable, so we need to follow rule 1.4 and 1.6 - try { - terminateDueTo(new IllegalStateException("Publisher terminated due to unavailable Executor.", t)); - } finally { - inboundSignals.clear(); // We're not going to need these anymore - // This subscription is cancelled by now, but letting it become schedulable again means - // that we can drain the inboundSignals queue if anything arrives after clearing - on.set(false); - } - } - } - } - } - - // Our implementation of `Subscription.request` sends a signal to the Subscription that more elements are in demand - @Override public void request(final long n) { - signal(new Request(n)); - } - // Our implementation of `Subscription.cancel` sends a signal to the Subscription that the `Subscriber` is not interested in any more elements - @Override public void cancel() { - signal(Cancel.Instance); - } - // The reason for the `init` method is that we want to ensure the `SubscriptionImpl` - // is completely constructed before it is exposed to the thread pool, therefor this - // method is only intended to be invoked once, and immediately after the constructor has - // finished. - void init() { - signal(Subscribe.Instance); - } - }; -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/AsyncSubscriber.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/AsyncSubscriber.java deleted file mode 100644 index a610a93cca4..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/AsyncSubscriber.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.example.unicast; - -import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; - -import java.util.concurrent.Executor; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.ConcurrentLinkedQueue; - -/** - * AsyncSubscriber is an implementation of Reactive Streams `Subscriber`, - * it runs asynchronously (on an Executor), requests one element - * at a time, and invokes a user-defined method to process each element. - * - * NOTE: The code below uses a lot of try-catches to show the reader where exceptions can be expected, and where they are forbidden. - */ -public abstract class AsyncSubscriber implements Subscriber, Runnable { - - // Signal represents the asynchronous protocol between the Publisher and Subscriber - private static interface Signal {} - - private enum OnComplete implements Signal { Instance; } - - private static class OnError implements Signal { - public final Throwable error; - public OnError(final Throwable error) { this.error = error; } - } - - private static class OnNext implements Signal { - public final T next; - public OnNext(final T next) { this.next = next; } - } - - private static class OnSubscribe implements Signal { - public final Subscription subscription; - public OnSubscribe(final Subscription subscription) { this.subscription = subscription; } - } - - private Subscription subscription; // Obeying rule 3.1, we make this private! - private boolean done; // It's useful to keep track of whether this Subscriber is done or not - private final Executor executor; // This is the Executor we'll use to be asynchronous, obeying rule 2.2 - - // Only one constructor, and it's only accessible for the subclasses - protected AsyncSubscriber(Executor executor) { - if (executor == null) throw null; - this.executor = executor; - } - - // Showcases a convenience method to idempotently marking the Subscriber as "done", so we don't want to process more elements - // herefor we also need to cancel our `Subscription`. - private final void done() { - //On this line we could add a guard against `!done`, but since rule 3.7 says that `Subscription.cancel()` is idempotent, we don't need to. - done = true; // If `whenNext` throws an exception, let's consider ourselves done (not accepting more elements) - if (subscription != null) { // If we are bailing out before we got a `Subscription` there's little need for cancelling it. - try { - subscription.cancel(); // Cancel the subscription - } catch(final Throwable t) { - //Subscription.cancel is not allowed to throw an exception, according to rule 3.15 - (new IllegalStateException(subscription + " violated the Reactive Streams rule 3.15 by throwing an exception from cancel.", t)).printStackTrace(System.err); - } - } - } - - // This method is invoked when the OnNext signals arrive - // Returns whether more elements are desired or not, and if no more elements are desired, - // for convenience. - protected abstract boolean whenNext(final T element); - - // This method is invoked when the OnComplete signal arrives - // override this method to implement your own custom onComplete logic. - protected void whenComplete() { } - - // This method is invoked if the OnError signal arrives - // override this method to implement your own custom onError logic. - protected void whenError(Throwable error) { } - - private final void handleOnSubscribe(final Subscription s) { - if (s == null) { - // Getting a null `Subscription` here is not valid so lets just ignore it. - } else if (subscription != null) { // If someone has made a mistake and added this Subscriber multiple times, let's handle it gracefully - try { - s.cancel(); // Cancel the additional subscription to follow rule 2.5 - } catch(final Throwable t) { - //Subscription.cancel is not allowed to throw an exception, according to rule 3.15 - (new IllegalStateException(s + " violated the Reactive Streams rule 3.15 by throwing an exception from cancel.", t)).printStackTrace(System.err); - } - } else { - // We have to assign it locally before we use it, if we want to be a synchronous `Subscriber` - // Because according to rule 3.10, the Subscription is allowed to call `onNext` synchronously from within `request` - subscription = s; - try { - // If we want elements, according to rule 2.1 we need to call `request` - // And, according to rule 3.2 we are allowed to call this synchronously from within the `onSubscribe` method - s.request(1); // Our Subscriber is unbuffered and modest, it requests one element at a time - } catch(final Throwable t) { - // Subscription.request is not allowed to throw according to rule 3.16 - (new IllegalStateException(s + " violated the Reactive Streams rule 3.16 by throwing an exception from request.", t)).printStackTrace(System.err); - } - } - } - - private final void handleOnNext(final T element) { - if (!done) { // If we aren't already done - if(subscription == null) { // Technically this check is not needed, since we are expecting Publishers to conform to the spec - // Check for spec violation of 2.1 and 1.09 - (new IllegalStateException("Someone violated the Reactive Streams rule 1.09 and 2.1 by signalling OnNext before `Subscription.request`. (no Subscription)")).printStackTrace(System.err); - } else { - try { - if (whenNext(element)) { - try { - subscription.request(1); // Our Subscriber is unbuffered and modest, it requests one element at a time - } catch(final Throwable t) { - // Subscription.request is not allowed to throw according to rule 3.16 - (new IllegalStateException(subscription + " violated the Reactive Streams rule 3.16 by throwing an exception from request.", t)).printStackTrace(System.err); - } - } else { - done(); // This is legal according to rule 2.6 - } - } catch(final Throwable t) { - done(); - try { - onError(t); - } catch(final Throwable t2) { - //Subscriber.onError is not allowed to throw an exception, according to rule 2.13 - (new IllegalStateException(this + " violated the Reactive Streams rule 2.13 by throwing an exception from onError.", t2)).printStackTrace(System.err); - } - } - } - } - } - - // Here it is important that we do not violate 2.2 and 2.3 by calling methods on the `Subscription` or `Publisher` - private void handleOnComplete() { - if (subscription == null) { // Technically this check is not needed, since we are expecting Publishers to conform to the spec - // Publisher is not allowed to signal onComplete before onSubscribe according to rule 1.09 - (new IllegalStateException("Publisher violated the Reactive Streams rule 1.09 signalling onComplete prior to onSubscribe.")).printStackTrace(System.err); - } else { - done = true; // Obey rule 2.4 - whenComplete(); - } - } - - // Here it is important that we do not violate 2.2 and 2.3 by calling methods on the `Subscription` or `Publisher` - private void handleOnError(final Throwable error) { - if (subscription == null) { // Technically this check is not needed, since we are expecting Publishers to conform to the spec - // Publisher is not allowed to signal onError before onSubscribe according to rule 1.09 - (new IllegalStateException("Publisher violated the Reactive Streams rule 1.09 signalling onError prior to onSubscribe.")).printStackTrace(System.err); - } else { - done = true; // Obey rule 2.4 - whenError(error); - } - } - - // We implement the OnX methods on `Subscriber` to send Signals that we will process asycnhronously, but only one at a time - - @Override public final void onSubscribe(final Subscription s) { - // As per rule 2.13, we need to throw a `java.lang.NullPointerException` if the `Subscription` is `null` - if (s == null) throw null; - - signal(new OnSubscribe(s)); - } - - @Override public final void onNext(final T element) { - // As per rule 2.13, we need to throw a `java.lang.NullPointerException` if the `element` is `null` - if (element == null) throw null; - - signal(new OnNext(element)); - } - - @Override public final void onError(final Throwable t) { - // As per rule 2.13, we need to throw a `java.lang.NullPointerException` if the `Throwable` is `null` - if (t == null) throw null; - - signal(new OnError(t)); - } - - @Override public final void onComplete() { - signal(OnComplete.Instance); - } - - // This `ConcurrentLinkedQueue` will track signals that are sent to this `Subscriber`, like `OnComplete` and `OnNext` , - // and obeying rule 2.11 - private final ConcurrentLinkedQueue inboundSignals = new ConcurrentLinkedQueue(); - - // We are using this `AtomicBoolean` to make sure that this `Subscriber` doesn't run concurrently with itself, - // obeying rule 2.7 and 2.11 - private final AtomicBoolean on = new AtomicBoolean(false); - - @SuppressWarnings("unchecked") - @Override public final void run() { - if(on.get()) { // establishes a happens-before relationship with the end of the previous run - try { - final Signal s = inboundSignals.poll(); // We take a signal off the queue - if (!done) { // If we're done, we shouldn't process any more signals, obeying rule 2.8 - // Below we simply unpack the `Signal`s and invoke the corresponding methods - if (s instanceof OnNext) - handleOnNext(((OnNext)s).next); - else if (s instanceof OnSubscribe) - handleOnSubscribe(((OnSubscribe)s).subscription); - else if (s instanceof OnError) // We are always able to handle OnError, obeying rule 2.10 - handleOnError(((OnError)s).error); - else if (s == OnComplete.Instance) // We are always able to handle OnComplete, obeying rule 2.9 - handleOnComplete(); - } - } finally { - on.set(false); // establishes a happens-before relationship with the beginning of the next run - if(!inboundSignals.isEmpty()) // If we still have signals to process - tryScheduleToExecute(); // Then we try to schedule ourselves to execute again - } - } - } - - // What `signal` does is that it sends signals to the `Subscription` asynchronously - private void signal(final Signal signal) { - if (inboundSignals.offer(signal)) // No need to null-check here as ConcurrentLinkedQueue does this for us - tryScheduleToExecute(); // Then we try to schedule it for execution, if it isn't already - } - - // This method makes sure that this `Subscriber` is only executing on one Thread at a time - private final void tryScheduleToExecute() { - if(on.compareAndSet(false, true)) { - try { - executor.execute(this); - } catch(Throwable t) { // If we can't run on the `Executor`, we need to fail gracefully and not violate rule 2.13 - if (!done) { - try { - done(); // First of all, this failure is not recoverable, so we need to cancel our subscription - } finally { - inboundSignals.clear(); // We're not going to need these anymore - // This subscription is cancelled by now, but letting the Subscriber become schedulable again means - // that we can drain the inboundSignals queue if anything arrives after clearing - on.set(false); - } - } - } - } - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/InfiniteIncrementNumberPublisher.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/InfiniteIncrementNumberPublisher.java deleted file mode 100644 index c1db3e66186..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/InfiniteIncrementNumberPublisher.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.example.unicast; - -import java.util.Iterator; -import java.util.concurrent.Executor; - -import org.reactivestreams.Subscription; -import org.reactivestreams.Subscriber; -import org.reactivestreams.Publisher; - -public class InfiniteIncrementNumberPublisher extends AsyncIterablePublisher { - public InfiniteIncrementNumberPublisher(final Executor executor) { - super(new Iterable() { - @Override public Iterator iterator() { - return new Iterator() { - private int at = 0; - @Override public boolean hasNext() { return true; } - @Override public Integer next() { return at++; } // Wraps around on overflow - @Override public void remove() { throw new UnsupportedOperationException(); } - }; - } - }, executor); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/NumberIterablePublisher.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/NumberIterablePublisher.java deleted file mode 100644 index 3ac116b6d14..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/NumberIterablePublisher.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.example.unicast; - -import java.util.Collections; -import java.util.Iterator; -import java.util.concurrent.Executor; -import org.reactivestreams.Subscription; -import org.reactivestreams.Subscriber; -import org.reactivestreams.Publisher; - -public class NumberIterablePublisher extends AsyncIterablePublisher { - public NumberIterablePublisher(final int from, final int to, final Executor executor) { - super(new Iterable() { - { if(from > to) throw new IllegalArgumentException("from must be equal or greater than to!"); } - @Override public Iterator iterator() { - return new Iterator() { - private int at = from; - @Override public boolean hasNext() { return at < to; } - @Override public Integer next() { - if (!hasNext()) return Collections.emptyList().iterator().next(); - else return at++; - } - @Override public void remove() { throw new UnsupportedOperationException(); } - }; - } - }, executor); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/RangePublisher.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/RangePublisher.java deleted file mode 100644 index 18c13b2aa86..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/RangePublisher.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.example.unicast; - -import org.reactivestreams.*; - -import java.util.concurrent.atomic.AtomicLong; - -/** - * A synchronous implementation of the {@link Publisher} that can - * be subscribed to multiple times and each individual subscription - * will receive range of monotonically increasing integer values on demand. - */ -public final class RangePublisher implements Publisher { - - /** The starting value of the range. */ - final int start; - - /** The number of items to emit. */ - final int count; - - /** - * Constructs a RangePublisher instance with the given start and count values - * that yields a sequence of [start, start + count). - * @param start the starting value of the range - * @param count the number of items to emit - */ - public RangePublisher(int start, int count) { - this.start = start; - this.count = count; - } - - @Override - public void subscribe(Subscriber subscriber) { - // As per rule 1.11, we have decided to support multiple subscribers - // in a unicast configuration for this `Publisher` implementation. - - // As per rule 1.09, we need to throw a `java.lang.NullPointerException` - // if the `Subscriber` is `null` - if (subscriber == null) throw null; - - // As per 2.13, this method must return normally (i.e. not throw). - try { - subscriber.onSubscribe(new RangeSubscription(subscriber, start, start + count)); - } catch (Throwable ex) { - new IllegalStateException(subscriber + " violated the Reactive Streams rule 2.13 " + - "by throwing an exception from onSubscribe.", ex) - // When onSubscribe fails this way, we don't know what state the - // subscriber is thus calling onError may cause more crashes. - .printStackTrace(); - } - } - - /** - * A Subscription implementation that holds the current downstream - * requested amount and responds to the downstream's request() and - * cancel() calls. - */ - static final class RangeSubscription - // We are using this `AtomicLong` to make sure that this `Subscription` - // doesn't run concurrently with itself, which would violate rule 1.3 - // among others (no concurrent notifications). - // The atomic transition from 0L to N > 0L will ensure this. - extends AtomicLong implements Subscription { - - private static final long serialVersionUID = -9000845542177067735L; - - /** The Subscriber we are emitting integer values to. */ - final Subscriber downstream; - - /** The end index (exclusive). */ - final int end; - - /** - * The current index and within the [start, start + count) range that - * will be emitted as downstream.onNext(). - */ - int index; - - /** - * Indicates the emission should stop. - */ - volatile boolean cancelled; - - /** - * Holds onto the IllegalArgumentException (containing the offending stacktrace) - * indicating there was a non-positive request() call from the downstream. - */ - volatile Throwable invalidRequest; - - /** - * Constructs a stateful RangeSubscription that emits signals to the given - * downstream from an integer range of [start, end). - * @param downstream the Subscriber receiving the integer values and the completion signal. - * @param start the first integer value emitted, start of the range - * @param end the end of the range, exclusive - */ - RangeSubscription(Subscriber downstream, int start, int end) { - this.downstream = downstream; - this.index = start; - this.end = end; - } - - // This method will register inbound demand from our `Subscriber` and - // validate it against rule 3.9 and rule 3.17 - @Override - public void request(long n) { - // Non-positive requests should be honored with IllegalArgumentException - if (n <= 0L) { - invalidRequest = new IllegalArgumentException("§3.9: non-positive requests are not allowed!"); - n = 1; - } - // Downstream requests are cumulative and may come from any thread - for (;;) { - long requested = get(); - long update = requested + n; - // As governed by rule 3.17, when demand overflows `Long.MAX_VALUE` - // we treat the signalled demand as "effectively unbounded" - if (update < 0L) { - update = Long.MAX_VALUE; - } - // atomically update the current requested amount - if (compareAndSet(requested, update)) { - // if there was no prior request amount, we start the emission loop - if (requested == 0L) { - emit(update); - } - break; - } - } - } - - // This handles cancellation requests, and is idempotent, thread-safe and not - // synchronously performing heavy computations as specified in rule 3.5 - @Override - public void cancel() { - // Indicate to the emission loop it should stop. - cancelled = true; - } - - void emit(long currentRequested) { - // Load fields to avoid re-reading them from memory due to volatile accesses in the loop. - Subscriber downstream = this.downstream; - int index = this.index; - int end = this.end; - int emitted = 0; - - try { - for (; ; ) { - // Check if there was an invalid request and then report its exception - // as mandated by rule 3.9. The stacktrace in it should - // help locate the faulty logic in the Subscriber. - Throwable invalidRequest = this.invalidRequest; - if (invalidRequest != null) { - // When we signal onError, the subscription must be considered as cancelled, as per rule 1.6 - cancelled = true; - - downstream.onError(invalidRequest); - return; - } - - // Loop while the index hasn't reached the end and we haven't - // emitted all that's been requested - while (index != end && emitted != currentRequested) { - // to make sure that we follow rule 1.8, 3.6 and 3.7 - // We stop if cancellation was requested. - if (cancelled) { - return; - } - - downstream.onNext(index); - - // Increment the index for the next possible emission. - index++; - // Increment the emitted count to prevent overflowing the downstream. - emitted++; - } - - // If the index reached the end, we complete the downstream. - if (index == end) { - // to make sure that we follow rule 1.8, 3.6 and 3.7 - // Unless cancellation was requested by the last onNext. - if (!cancelled) { - // We need to consider this `Subscription` as cancelled as per rule 1.6 - // Note, however, that this state is not observable from the outside - // world and since we leave the loop with requested > 0L, any - // further request() will never trigger the loop. - cancelled = true; - - downstream.onComplete(); - } - return; - } - - // Did the requested amount change while we were looping? - long freshRequested = get(); - if (freshRequested == currentRequested) { - // Save where the loop has left off: the next value to be emitted - this.index = index; - // Atomically subtract the previously requested (also emitted) amount - currentRequested = addAndGet(-currentRequested); - // If there was no new request in between get() and addAndGet(), we simply quit - // The next 0 to N transition in request() will trigger the next emission loop. - if (currentRequested == 0L) { - break; - } - // Looks like there were more async requests, reset the emitted count and continue. - emitted = 0; - } else { - // Yes, avoid the atomic subtraction and resume. - // emitted != currentRequest in this case and index - // still points to the next value to be emitted - currentRequested = freshRequested; - } - } - } catch (Throwable ex) { - // We can only get here if `onNext`, `onError` or `onComplete` threw, and they - // are not allowed to according to 2.13, so we can only cancel and log here. - // If `onError` throws an exception, this is a spec violation according to rule 1.9, - // and all we can do is to log it. - - // Make sure that we are cancelled, since we cannot do anything else - // since the `Subscriber` is faulty. - cancelled = true; - - // We can't report the failure to onError as the Subscriber is unreliable. - (new IllegalStateException(downstream + " violated the Reactive Streams rule 2.13 by " + - "throwing an exception from onNext, onError or onComplete.", ex)) - .printStackTrace(); - } - } - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/SyncSubscriber.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/SyncSubscriber.java deleted file mode 100644 index 98817a200d5..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/example/unicast/SyncSubscriber.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.example.unicast; - -import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; - -/** - * SyncSubscriber is an implementation of Reactive Streams `Subscriber`, - * it runs synchronously (on the Publisher's thread) and requests one element - * at a time and invokes a user-defined method to process each element. - * - * NOTE: The code below uses a lot of try-catches to show the reader where exceptions can be expected, and where they are forbidden. - */ -public abstract class SyncSubscriber implements Subscriber { - private Subscription subscription; // Obeying rule 3.1, we make this private! - private boolean done = false; - - @Override public void onSubscribe(final Subscription s) { - // As per rule 2.13, we need to throw a `java.lang.NullPointerException` if the `Subscription` is `null` - if (s == null) throw null; - - if (subscription != null) { // If someone has made a mistake and added this Subscriber multiple times, let's handle it gracefully - try { - s.cancel(); // Cancel the additional subscription - } catch(final Throwable t) { - //Subscription.cancel is not allowed to throw an exception, according to rule 3.15 - (new IllegalStateException(s + " violated the Reactive Streams rule 3.15 by throwing an exception from cancel.", t)).printStackTrace(System.err); - } - } else { - // We have to assign it locally before we use it, if we want to be a synchronous `Subscriber` - // Because according to rule 3.10, the Subscription is allowed to call `onNext` synchronously from within `request` - subscription = s; - try { - // If we want elements, according to rule 2.1 we need to call `request` - // And, according to rule 3.2 we are allowed to call this synchronously from within the `onSubscribe` method - s.request(1); // Our Subscriber is unbuffered and modest, it requests one element at a time - } catch(final Throwable t) { - // Subscription.request is not allowed to throw according to rule 3.16 - (new IllegalStateException(s + " violated the Reactive Streams rule 3.16 by throwing an exception from request.", t)).printStackTrace(System.err); - } - } - } - - @Override public void onNext(final T element) { - if (subscription == null) { // Technically this check is not needed, since we are expecting Publishers to conform to the spec - (new IllegalStateException("Publisher violated the Reactive Streams rule 1.09 signalling onNext prior to onSubscribe.")).printStackTrace(System.err); - } else { - // As per rule 2.13, we need to throw a `java.lang.NullPointerException` if the `element` is `null` - if (element == null) throw null; - - if (!done) { // If we aren't already done - try { - if (whenNext(element)) { - try { - subscription.request(1); // Our Subscriber is unbuffered and modest, it requests one element at a time - } catch (final Throwable t) { - // Subscription.request is not allowed to throw according to rule 3.16 - (new IllegalStateException(subscription + " violated the Reactive Streams rule 3.16 by throwing an exception from request.", t)).printStackTrace(System.err); - } - } else { - done(); - } - } catch (final Throwable t) { - done(); - try { - onError(t); - } catch (final Throwable t2) { - //Subscriber.onError is not allowed to throw an exception, according to rule 2.13 - (new IllegalStateException(this + " violated the Reactive Streams rule 2.13 by throwing an exception from onError.", t2)).printStackTrace(System.err); - } - } - } - } - } - - // Showcases a convenience method to idempotently marking the Subscriber as "done", so we don't want to process more elements - // herefor we also need to cancel our `Subscription`. - private void done() { - //On this line we could add a guard against `!done`, but since rule 3.7 says that `Subscription.cancel()` is idempotent, we don't need to. - done = true; // If we `whenNext` throws an exception, let's consider ourselves done (not accepting more elements) - try { - subscription.cancel(); // Cancel the subscription - } catch(final Throwable t) { - //Subscription.cancel is not allowed to throw an exception, according to rule 3.15 - (new IllegalStateException(subscription + " violated the Reactive Streams rule 3.15 by throwing an exception from cancel.", t)).printStackTrace(System.err); - } - } - - // This method is left as an exercise to the reader/extension point - // Returns whether more elements are desired or not, and if no more elements are desired - protected abstract boolean whenNext(final T element); - - @Override public void onError(final Throwable t) { - if (subscription == null) { // Technically this check is not needed, since we are expecting Publishers to conform to the spec - (new IllegalStateException("Publisher violated the Reactive Streams rule 1.09 signalling onError prior to onSubscribe.")).printStackTrace(System.err); - } else { - // As per rule 2.13, we need to throw a `java.lang.NullPointerException` if the `Throwable` is `null` - if (t == null) throw null; - // Here we are not allowed to call any methods on the `Subscription` or the `Publisher`, as per rule 2.3 - // And anyway, the `Subscription` is considered to be cancelled if this method gets called, as per rule 2.4 - } - } - - @Override public void onComplete() { - if (subscription == null) { // Technically this check is not needed, since we are expecting Publishers to conform to the spec - (new IllegalStateException("Publisher violated the Reactive Streams rule 1.09 signalling onComplete prior to onSubscribe.")).printStackTrace(System.err); - } else { - // Here we are not allowed to call any methods on the `Subscription` or the `Publisher`, as per rule 2.3 - // And anyway, the `Subscription` is considered to be cancelled if this method gets called, as per rule 2.4 - } - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/IdentityProcessorVerification.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/IdentityProcessorVerification.java deleted file mode 100644 index cce7f2240f0..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/IdentityProcessorVerification.java +++ /dev/null @@ -1,896 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck; - -import org.reactivestreams.Processor; -import org.reactivestreams.Publisher; -import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; -import org.reactivestreams.tck.TestEnvironment.ManualPublisher; -import org.reactivestreams.tck.TestEnvironment.ManualSubscriber; -import org.reactivestreams.tck.TestEnvironment.ManualSubscriberWithSubscriptionSupport; -import org.reactivestreams.tck.TestEnvironment.Promise; -import org.reactivestreams.tck.flow.support.Function; -import org.reactivestreams.tck.flow.support.SubscriberWhiteboxVerificationRules; -import org.reactivestreams.tck.flow.support.PublisherVerificationRules; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import java.util.HashSet; -import java.util.Set; - -public abstract class IdentityProcessorVerification extends WithHelperPublisher - implements SubscriberWhiteboxVerificationRules, PublisherVerificationRules { - - private final TestEnvironment env; - - ////////////////////// DELEGATED TO SPECS ////////////////////// - - // for delegating tests - private final SubscriberWhiteboxVerification subscriberVerification; - - // for delegating tests - private final PublisherVerification publisherVerification; - - ////////////////// END OF DELEGATED TO SPECS ////////////////// - - // number of elements the processor under test must be able ot buffer, - // without dropping elements. Defaults to `TestEnvironment.TEST_BUFFER_SIZE`. - private final int processorBufferSize; - - /** - * Test class must specify the expected time it takes for the publisher to - * shut itself down when the the last downstream {@code Subscription} is cancelled. - * - * The processor will be required to be able to buffer {@code TestEnvironment.TEST_BUFFER_SIZE} elements. - */ - @SuppressWarnings("unused") - public IdentityProcessorVerification(final TestEnvironment env) { - this(env, PublisherVerification.envPublisherReferenceGCTimeoutMillis(), TestEnvironment.TEST_BUFFER_SIZE); - } - - /** - * Test class must specify the expected time it takes for the publisher to - * shut itself down when the the last downstream {@code Subscription} is cancelled. - * - * The processor will be required to be able to buffer {@code TestEnvironment.TEST_BUFFER_SIZE} elements. - * - * @param publisherReferenceGCTimeoutMillis used to determine after how much time a reference to a Subscriber should be already dropped by the Publisher. - */ - @SuppressWarnings("unused") - public IdentityProcessorVerification(final TestEnvironment env, long publisherReferenceGCTimeoutMillis) { - this(env, publisherReferenceGCTimeoutMillis, TestEnvironment.TEST_BUFFER_SIZE); - } - - /** - * Test class must specify the expected time it takes for the publisher to - * shut itself down when the the last downstream {@code Subscription} is cancelled. - * - * @param publisherReferenceGCTimeoutMillis used to determine after how much time a reference to a Subscriber should be already dropped by the Publisher. - * @param processorBufferSize number of elements the processor is required to be able to buffer. - */ - public IdentityProcessorVerification(final TestEnvironment env, long publisherReferenceGCTimeoutMillis, int processorBufferSize) { - this.env = env; - this.processorBufferSize = processorBufferSize; - - this.subscriberVerification = new SubscriberWhiteboxVerification(env) { - @Override - public Subscriber createSubscriber(WhiteboxSubscriberProbe probe) { - return IdentityProcessorVerification.this.createSubscriber(probe); - } - - @Override public T createElement(int element) { - return IdentityProcessorVerification.this.createElement(element); - } - - @Override - public Publisher createHelperPublisher(long elements) { - return IdentityProcessorVerification.this.createHelperPublisher(elements); - } - }; - - publisherVerification = new PublisherVerification(env, publisherReferenceGCTimeoutMillis) { - @Override - public Publisher createPublisher(long elements) { - return IdentityProcessorVerification.this.createPublisher(elements); - } - - @Override - public Publisher createFailedPublisher() { - return IdentityProcessorVerification.this.createFailedPublisher(); - } - - @Override - public long maxElementsFromPublisher() { - return IdentityProcessorVerification.this.maxElementsFromPublisher(); - } - - @Override - public long boundedDepthOfOnNextAndRequestRecursion() { - return IdentityProcessorVerification.this.boundedDepthOfOnNextAndRequestRecursion(); - } - - @Override - public boolean skipStochasticTests() { - return IdentityProcessorVerification.this.skipStochasticTests(); - } - }; - } - - /** - * This is the main method you must implement in your test incarnation. - * It must create a {@link Processor}, which simply forwards all stream elements from its upstream - * to its downstream. It must be able to internally buffer the given number of elements. - * - * @param bufferSize number of elements the processor is required to be able to buffer. - */ - public abstract Processor createIdentityProcessor(int bufferSize); - - /** - * By implementing this method, additional TCK tests concerning a "failed" publishers will be run. - * - * The expected behaviour of the {@link Publisher} returned by this method is hand out a subscription, - * followed by signalling {@code onError} on it, as specified by Rule 1.9. - * - * If you want to ignore these additional tests, return {@code null} from this method. - */ - public abstract Publisher createFailedPublisher(); - - /** - * Override and return lower value if your Publisher is only able to produce a known number of elements. - * For example, if it is designed to return at-most-one element, return {@code 1} from this method. - * - * Defaults to {@code Long.MAX_VALUE - 1}, meaning that the Publisher can be produce a huge but NOT an unbounded number of elements. - * - * To mark your Publisher will *never* signal an {@code onComplete} override this method and return {@code Long.MAX_VALUE}, - * which will result in *skipping all tests which require an onComplete to be triggered* (!). - */ - public long maxElementsFromPublisher() { - return Long.MAX_VALUE - 1; - } - - /** - * In order to verify rule 3.3 of the reactive streams spec, this number will be used to check if a - * {@code Subscription} actually solves the "unbounded recursion" problem by not allowing the number of - * recursive calls to exceed the number returned by this method. - * - * @see reactive streams spec, rule 3.3 - * @see PublisherVerification#required_spec303_mustNotAllowUnboundedRecursion() - */ - public long boundedDepthOfOnNextAndRequestRecursion() { - return 1; - } - - /** - * Override and return {@code true} in order to skip executing tests marked as {@code Stochastic}. - * Stochastic in this case means that the Rule is impossible or infeasible to deterministically verify— - * usually this means that this test case can yield false positives ("be green") even if for some case, - * the given implementation may violate the tested behaviour. - */ - public boolean skipStochasticTests() { - return false; - } - - /** - * Describes the tested implementation in terms of how many subscribers they can support. - * Some tests require the {@code Publisher} under test to support multiple Subscribers, - * yet the spec does not require all publishers to be able to do so, thus – if an implementation - * supports only a limited number of subscribers (e.g. only 1 subscriber, also known as "no fanout") - * you MUST return that number from this method by overriding it. - */ - public long maxSupportedSubscribers() { - return Long.MAX_VALUE; - } - - /** - * Override this method and return {@code true} if the {@link Processor} returned by the - * {@link #createIdentityProcessor(int)} coordinates its {@link Subscriber}s - * request amounts and only delivers onNext signals if all Subscribers have - * indicated (via their Subscription#request(long)) they are ready to receive elements. - */ - public boolean doesCoordinatedEmission() { - return false; - } - - ////////////////////// TEST ENV CLEANUP ///////////////////////////////////// - - @BeforeMethod - public void setUp() throws Exception { - publisherVerification.setUp(); - subscriberVerification.setUp(); - } - - ////////////////////// PUBLISHER RULES VERIFICATION /////////////////////////// - - // A Processor - // must obey all Publisher rules on its publishing side - public Publisher createPublisher(long elements) { - final Processor processor = createIdentityProcessor(processorBufferSize); - final Publisher pub = createHelperPublisher(elements); - pub.subscribe(processor); - return processor; // we run the PublisherVerification against this - } - - @Override @Test - public void required_validate_maxElementsFromPublisher() throws Exception { - publisherVerification.required_validate_maxElementsFromPublisher(); - } - - @Override @Test - public void required_validate_boundedDepthOfOnNextAndRequestRecursion() throws Exception { - publisherVerification.required_validate_boundedDepthOfOnNextAndRequestRecursion(); - } - - /////////////////////// DELEGATED TESTS, A PROCESSOR "IS A" PUBLISHER ////////////////////// - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#4.1 - - @Test - public void required_createPublisher1MustProduceAStreamOfExactly1Element() throws Throwable { - publisherVerification.required_createPublisher1MustProduceAStreamOfExactly1Element(); - } - - @Test - public void required_createPublisher3MustProduceAStreamOfExactly3Elements() throws Throwable { - publisherVerification.required_createPublisher3MustProduceAStreamOfExactly3Elements(); - } - - @Override @Test - public void required_spec101_subscriptionRequestMustResultInTheCorrectNumberOfProducedElements() throws Throwable { - publisherVerification.required_spec101_subscriptionRequestMustResultInTheCorrectNumberOfProducedElements(); - } - - @Override @Test - public void required_spec102_maySignalLessThanRequestedAndTerminateSubscription() throws Throwable { - publisherVerification.required_spec102_maySignalLessThanRequestedAndTerminateSubscription(); - } - - @Override @Test - public void stochastic_spec103_mustSignalOnMethodsSequentially() throws Throwable { - publisherVerification.stochastic_spec103_mustSignalOnMethodsSequentially(); - } - - @Override @Test - public void optional_spec104_mustSignalOnErrorWhenFails() throws Throwable { - publisherVerification.optional_spec104_mustSignalOnErrorWhenFails(); - } - - @Override @Test - public void required_spec105_mustSignalOnCompleteWhenFiniteStreamTerminates() throws Throwable { - publisherVerification.required_spec105_mustSignalOnCompleteWhenFiniteStreamTerminates(); - } - - @Override @Test - public void optional_spec105_emptyStreamMustTerminateBySignallingOnComplete() throws Throwable { - publisherVerification.optional_spec105_emptyStreamMustTerminateBySignallingOnComplete(); - } - - @Override @Test - public void untested_spec106_mustConsiderSubscriptionCancelledAfterOnErrorOrOnCompleteHasBeenCalled() throws Throwable { - publisherVerification.untested_spec106_mustConsiderSubscriptionCancelledAfterOnErrorOrOnCompleteHasBeenCalled(); - } - - @Override @Test - public void required_spec107_mustNotEmitFurtherSignalsOnceOnCompleteHasBeenSignalled() throws Throwable { - publisherVerification.required_spec107_mustNotEmitFurtherSignalsOnceOnCompleteHasBeenSignalled(); - } - - @Override @Test - public void untested_spec107_mustNotEmitFurtherSignalsOnceOnErrorHasBeenSignalled() throws Throwable { - publisherVerification.untested_spec107_mustNotEmitFurtherSignalsOnceOnErrorHasBeenSignalled(); - } - - @Override @Test - public void untested_spec108_possiblyCanceledSubscriptionShouldNotReceiveOnErrorOrOnCompleteSignals() throws Throwable { - publisherVerification.untested_spec108_possiblyCanceledSubscriptionShouldNotReceiveOnErrorOrOnCompleteSignals(); - } - - @Override @Test - public void untested_spec109_subscribeShouldNotThrowNonFatalThrowable() throws Throwable { - publisherVerification.untested_spec109_subscribeShouldNotThrowNonFatalThrowable(); - } - - @Override @Test - public void required_spec109_subscribeThrowNPEOnNullSubscriber() throws Throwable { - publisherVerification.required_spec109_subscribeThrowNPEOnNullSubscriber(); - } - - @Override @Test - public void required_spec109_mayRejectCallsToSubscribeIfPublisherIsUnableOrUnwillingToServeThemRejectionMustTriggerOnErrorAfterOnSubscribe() throws Throwable { - publisherVerification.required_spec109_mayRejectCallsToSubscribeIfPublisherIsUnableOrUnwillingToServeThemRejectionMustTriggerOnErrorAfterOnSubscribe(); - } - - @Override @Test - public void required_spec109_mustIssueOnSubscribeForNonNullSubscriber() throws Throwable { - publisherVerification.required_spec109_mustIssueOnSubscribeForNonNullSubscriber(); - } - - @Override @Test - public void untested_spec110_rejectASubscriptionRequestIfTheSameSubscriberSubscribesTwice() throws Throwable { - publisherVerification.untested_spec110_rejectASubscriptionRequestIfTheSameSubscriberSubscribesTwice(); - } - - @Override @Test - public void optional_spec111_maySupportMultiSubscribe() throws Throwable { - publisherVerification.optional_spec111_maySupportMultiSubscribe(); - } - - @Override @Test - public void optional_spec111_registeredSubscribersMustReceiveOnNextOrOnCompleteSignals() throws Throwable { - publisherVerification.optional_spec111_registeredSubscribersMustReceiveOnNextOrOnCompleteSignals(); - } - - @Override @Test - public void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingOneByOne() throws Throwable { - publisherVerification.optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingOneByOne(); - } - - @Override @Test - public void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfront() throws Throwable { - publisherVerification.optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfront(); - } - - @Override @Test - public void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfrontAndCompleteAsExpected() throws Throwable { - publisherVerification.optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfrontAndCompleteAsExpected(); - } - - @Override @Test - public void required_spec302_mustAllowSynchronousRequestCallsFromOnNextAndOnSubscribe() throws Throwable { - publisherVerification.required_spec302_mustAllowSynchronousRequestCallsFromOnNextAndOnSubscribe(); - } - - @Override @Test - public void required_spec303_mustNotAllowUnboundedRecursion() throws Throwable { - publisherVerification.required_spec303_mustNotAllowUnboundedRecursion(); - } - - @Override @Test - public void untested_spec304_requestShouldNotPerformHeavyComputations() throws Exception { - publisherVerification.untested_spec304_requestShouldNotPerformHeavyComputations(); - } - - @Override @Test - public void untested_spec305_cancelMustNotSynchronouslyPerformHeavyComputation() throws Exception { - publisherVerification.untested_spec305_cancelMustNotSynchronouslyPerformHeavyComputation(); - } - - @Override @Test - public void required_spec306_afterSubscriptionIsCancelledRequestMustBeNops() throws Throwable { - publisherVerification.required_spec306_afterSubscriptionIsCancelledRequestMustBeNops(); - } - - @Override @Test - public void required_spec307_afterSubscriptionIsCancelledAdditionalCancelationsMustBeNops() throws Throwable { - publisherVerification.required_spec307_afterSubscriptionIsCancelledAdditionalCancelationsMustBeNops(); - } - - @Override @Test - public void required_spec309_requestZeroMustSignalIllegalArgumentException() throws Throwable { - publisherVerification.required_spec309_requestZeroMustSignalIllegalArgumentException(); - } - - @Override @Test - public void required_spec309_requestNegativeNumberMustSignalIllegalArgumentException() throws Throwable { - publisherVerification.required_spec309_requestNegativeNumberMustSignalIllegalArgumentException(); - } - - @Override @Test - public void optional_spec309_requestNegativeNumberMaySignalIllegalArgumentExceptionWithSpecificMessage() throws Throwable { - publisherVerification.optional_spec309_requestNegativeNumberMaySignalIllegalArgumentExceptionWithSpecificMessage(); - } - - @Override @Test - public void required_spec312_cancelMustMakeThePublisherToEventuallyStopSignaling() throws Throwable { - publisherVerification.required_spec312_cancelMustMakeThePublisherToEventuallyStopSignaling(); - } - - @Override @Test - public void required_spec313_cancelMustMakeThePublisherEventuallyDropAllReferencesToTheSubscriber() throws Throwable { - publisherVerification.required_spec313_cancelMustMakeThePublisherEventuallyDropAllReferencesToTheSubscriber(); - } - - @Override @Test - public void required_spec317_mustSupportAPendingElementCountUpToLongMaxValue() throws Throwable { - publisherVerification.required_spec317_mustSupportAPendingElementCountUpToLongMaxValue(); - } - - @Override @Test - public void required_spec317_mustSupportACumulativePendingElementCountUpToLongMaxValue() throws Throwable { - publisherVerification.required_spec317_mustSupportACumulativePendingElementCountUpToLongMaxValue(); - } - - @Override @Test - public void required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue() throws Throwable { - publisherVerification.required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue(); - } - - - /** - * Asks for a {@code Processor} that supports at least 2 {@code Subscriber}s at once and checks if two {@code Subscriber}s - * receive the same items and a terminal {@code Exception}. - *

- * If the {@code Processor} requests and/or emits items only when all of its {@code Subscriber}s have requested, - * override {@link #doesCoordinatedEmission()} and return {@code true} to indicate this property. - *

- * Verifies rule: 1.4 with multiple - * {@code Subscriber}s. - *

- * The test is not executed if {@link IdentityProcessorVerification#maxSupportedSubscribers()} is less than 2. - *

- * If this test fails, the following could be checked within the {@code Processor} implementation: - *

    - *
  • The {@code TestEnvironment} has large enough timeout specified in case the {@code Processor} has some time-delay behavior.
  • - *
  • The {@code Processor} is able to fulfill requests of its {@code Subscriber}s independently of each other's requests or - * else override {@link #doesCoordinatedEmission()} and return {@code true} to indicate the test {@code Subscriber}s - * both have to request first.
  • - *
- */ - @Test - public void required_spec104_mustCallOnErrorOnAllItsSubscribersIfItEncountersANonRecoverableError() throws Throwable { - optionalMultipleSubscribersTest(2, new Function() { - @Override - public TestSetup apply(Long aLong) throws Throwable { - return new TestSetup(env, processorBufferSize) {{ - final ManualSubscriberWithErrorCollection sub1 = new ManualSubscriberWithErrorCollection(env); - env.subscribe(processor, sub1); - - final ManualSubscriberWithErrorCollection sub2 = new ManualSubscriberWithErrorCollection(env); - env.subscribe(processor, sub2); - - final Exception ex = new RuntimeException("Test exception"); - - if (doesCoordinatedEmission()) { - sub1.request(1); - sub2.request(1); - - expectRequest(); - - final T x = sendNextTFromUpstream(); - - expectNextElement(sub1, x); - expectNextElement(sub2, x); - - sub1.request(1); - sub2.request(1); - } else { - sub1.request(1); - - expectRequest(env.defaultTimeoutMillis(), - "If the Processor coordinates requests/emissions when having multiple Subscribers" - + " at once, please override doesCoordinatedEmission() to return true in this " - + "IdentityProcessorVerification to allow this test to pass."); - - final T x = sendNextTFromUpstream(); - expectNextElement(sub1, x, - "If the Processor coordinates requests/emissions when having multiple Subscribers" - + " at once, please override doesCoordinatedEmission() to return true in this " - + "IdentityProcessorVerification to allow this test to pass."); - - sub1.request(1); - - // sub1 has received one element, and has one demand pending - // sub2 has not yet requested anything - } - sendError(ex); - - sub1.expectError(ex); - sub2.expectError(ex); - - env.verifyNoAsyncErrorsNoDelay(); - }}; - } - }); - } - - ////////////////////// SUBSCRIBER RULES VERIFICATION /////////////////////////// - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#4.1 - - // A Processor - // must obey all Subscriber rules on its consuming side - public Subscriber createSubscriber(final SubscriberWhiteboxVerification.WhiteboxSubscriberProbe probe) { - final Processor processor = createIdentityProcessor(processorBufferSize); - processor.subscribe( - new Subscriber() { - private final Promise subs = new Promise(env); - - @Override - public void onSubscribe(final Subscription subscription) { - if (env.debugEnabled()) { - env.debug(String.format("whiteboxSubscriber::onSubscribe(%s)", subscription)); - } - if (subs.isCompleted()) subscription.cancel(); // the Probe must also pass subscriber verification - - probe.registerOnSubscribe(new SubscriberWhiteboxVerification.SubscriberPuppet() { - - @Override - public void triggerRequest(long elements) { - subscription.request(elements); - } - - @Override - public void signalCancel() { - subscription.cancel(); - } - }); - } - - @Override - public void onNext(T element) { - if (env.debugEnabled()) { - env.debug(String.format("whiteboxSubscriber::onNext(%s)", element)); - } - probe.registerOnNext(element); - } - - @Override - public void onComplete() { - if (env.debugEnabled()) { - env.debug("whiteboxSubscriber::onComplete()"); - } - probe.registerOnComplete(); - } - - @Override - public void onError(Throwable cause) { - if (env.debugEnabled()) { - env.debug(String.format("whiteboxSubscriber::onError(%s)", cause)); - } - probe.registerOnError(cause); - } - }); - - return processor; // we run the SubscriberVerification against this - } - - ////////////////////// OTHER RULE VERIFICATION /////////////////////////// - - // A Processor - // must immediately pass on `onError` events received from its upstream to its downstream - @Test - public void mustImmediatelyPassOnOnErrorEventsReceivedFromItsUpstreamToItsDownstream() throws Exception { - new TestSetup(env, processorBufferSize) {{ - final ManualSubscriberWithErrorCollection sub = new ManualSubscriberWithErrorCollection(env); - env.subscribe(processor, sub); - - final Exception ex = new RuntimeException("Test exception"); - sendError(ex); - sub.expectError(ex); // "immediately", i.e. without a preceding request - - env.verifyNoAsyncErrorsNoDelay(); - }}; - } - - /////////////////////// DELEGATED TESTS, A PROCESSOR "IS A" SUBSCRIBER ////////////////////// - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#4.1 - - @Test - public void required_exerciseWhiteboxHappyPath() throws Throwable { - subscriberVerification.required_exerciseWhiteboxHappyPath(); - } - - @Override @Test - public void required_spec201_mustSignalDemandViaSubscriptionRequest() throws Throwable { - subscriberVerification.required_spec201_mustSignalDemandViaSubscriptionRequest(); - } - - @Override @Test - public void untested_spec202_shouldAsynchronouslyDispatch() throws Exception { - subscriberVerification.untested_spec202_shouldAsynchronouslyDispatch(); - } - - @Override @Test - public void required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnComplete() throws Throwable { - subscriberVerification.required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnComplete(); - } - - @Override @Test - public void required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnError() throws Throwable { - subscriberVerification.required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnError(); - } - - @Override @Test - public void untested_spec204_mustConsiderTheSubscriptionAsCancelledInAfterRecievingOnCompleteOrOnError() throws Exception { - subscriberVerification.untested_spec204_mustConsiderTheSubscriptionAsCancelledInAfterRecievingOnCompleteOrOnError(); - } - - @Override @Test - public void required_spec205_mustCallSubscriptionCancelIfItAlreadyHasAnSubscriptionAndReceivesAnotherOnSubscribeSignal() throws Throwable { - subscriberVerification.required_spec205_mustCallSubscriptionCancelIfItAlreadyHasAnSubscriptionAndReceivesAnotherOnSubscribeSignal(); - } - - @Override @Test - public void untested_spec206_mustCallSubscriptionCancelIfItIsNoLongerValid() throws Exception { - subscriberVerification.untested_spec206_mustCallSubscriptionCancelIfItIsNoLongerValid(); - } - - @Override @Test - public void untested_spec207_mustEnsureAllCallsOnItsSubscriptionTakePlaceFromTheSameThreadOrTakeCareOfSynchronization() throws Exception { - subscriberVerification.untested_spec207_mustEnsureAllCallsOnItsSubscriptionTakePlaceFromTheSameThreadOrTakeCareOfSynchronization(); - } - - @Override @Test - public void required_spec208_mustBePreparedToReceiveOnNextSignalsAfterHavingCalledSubscriptionCancel() throws Throwable { - subscriberVerification.required_spec208_mustBePreparedToReceiveOnNextSignalsAfterHavingCalledSubscriptionCancel(); - } - - @Override @Test - public void required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithPrecedingRequestCall() throws Throwable { - subscriberVerification.required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithPrecedingRequestCall(); - } - - @Override @Test - public void required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithoutPrecedingRequestCall() throws Throwable { - subscriberVerification.required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithoutPrecedingRequestCall(); - } - - @Override @Test - public void required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithPrecedingRequestCall() throws Throwable { - subscriberVerification.required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithPrecedingRequestCall(); - } - - @Override @Test - public void required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithoutPrecedingRequestCall() throws Throwable { - subscriberVerification.required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithoutPrecedingRequestCall(); - } - - @Override @Test - public void untested_spec211_mustMakeSureThatAllCallsOnItsMethodsHappenBeforeTheProcessingOfTheRespectiveEvents() throws Exception { - subscriberVerification.untested_spec211_mustMakeSureThatAllCallsOnItsMethodsHappenBeforeTheProcessingOfTheRespectiveEvents(); - } - - @Override @Test - public void untested_spec212_mustNotCallOnSubscribeMoreThanOnceBasedOnObjectEquality_specViolation() throws Throwable { - subscriberVerification.untested_spec212_mustNotCallOnSubscribeMoreThanOnceBasedOnObjectEquality_specViolation(); - } - - @Override @Test - public void untested_spec213_failingOnSignalInvocation() throws Exception { - subscriberVerification.untested_spec213_failingOnSignalInvocation(); - } - - @Override @Test - public void required_spec213_onSubscribe_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable { - subscriberVerification.required_spec213_onSubscribe_mustThrowNullPointerExceptionWhenParametersAreNull(); - } - @Override @Test - public void required_spec213_onNext_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable { - subscriberVerification.required_spec213_onNext_mustThrowNullPointerExceptionWhenParametersAreNull(); - } - @Override @Test - public void required_spec213_onError_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable { - subscriberVerification.required_spec213_onError_mustThrowNullPointerExceptionWhenParametersAreNull(); - } - - @Override @Test - public void untested_spec301_mustNotBeCalledOutsideSubscriberContext() throws Exception { - subscriberVerification.untested_spec301_mustNotBeCalledOutsideSubscriberContext(); - } - - @Override @Test - public void required_spec308_requestMustRegisterGivenNumberElementsToBeProduced() throws Throwable { - subscriberVerification.required_spec308_requestMustRegisterGivenNumberElementsToBeProduced(); - } - - @Override @Test - public void untested_spec310_requestMaySynchronouslyCallOnNextOnSubscriber() throws Exception { - subscriberVerification.untested_spec310_requestMaySynchronouslyCallOnNextOnSubscriber(); - } - - @Override @Test - public void untested_spec311_requestMaySynchronouslyCallOnCompleteOrOnError() throws Exception { - subscriberVerification.untested_spec311_requestMaySynchronouslyCallOnCompleteOrOnError(); - } - - @Override @Test - public void untested_spec314_cancelMayCauseThePublisherToShutdownIfNoOtherSubscriptionExists() throws Exception { - subscriberVerification.untested_spec314_cancelMayCauseThePublisherToShutdownIfNoOtherSubscriptionExists(); - } - - @Override @Test - public void untested_spec315_cancelMustNotThrowExceptionAndMustSignalOnError() throws Exception { - subscriberVerification.untested_spec315_cancelMustNotThrowExceptionAndMustSignalOnError(); - } - - @Override @Test - public void untested_spec316_requestMustNotThrowExceptionAndMustOnErrorTheSubscriber() throws Exception { - subscriberVerification.untested_spec316_requestMustNotThrowExceptionAndMustOnErrorTheSubscriber(); - } - - /////////////////////// ADDITIONAL "COROLLARY" TESTS ////////////////////// - - /** - * Asks for a {@code Processor} that supports at least 2 {@code Subscriber}s at once and checks requests - * from {@code Subscriber}s will eventually lead to requests towards the upstream of the {@code Processor}. - *

- * If the {@code Processor} requests and/or emits items only when all of its {@code Subscriber}s have requested, - * override {@link #doesCoordinatedEmission()} and return {@code true} to indicate this property. - *

- * Verifies rule: 2.1 with multiple - * {@code Subscriber}s. - *

- * The test is not executed if {@link IdentityProcessorVerification#maxSupportedSubscribers()} is less than 2. - *

- * If this test fails, the following could be checked within the {@code Processor} implementation: - *

    - *
  • The {@code TestEnvironment} has large enough timeout specified in case the {@code Processor} has some time-delay behavior.
  • - *
  • The {@code Processor} is able to fulfill requests of its {@code Subscriber}s independently of each other's requests or - * else override {@link #doesCoordinatedEmission()} and return {@code true} to indicate the test {@code Subscriber}s - * both have to request first.
  • - *
- */ - @Test - public void required_mustRequestFromUpstreamForElementsThatHaveBeenRequestedLongAgo() throws Throwable { - optionalMultipleSubscribersTest(2, new Function() { - @Override - public TestSetup apply(Long subscribers) throws Throwable { - return new TestSetup(env, processorBufferSize) {{ - ManualSubscriber sub1 = newSubscriber(); - sub1.request(20); - - long totalRequests = expectRequest(); - final T x = sendNextTFromUpstream(); - expectNextElement(sub1, x); - - if (totalRequests == 1) { - totalRequests += expectRequest(); - } - final T y = sendNextTFromUpstream(); - expectNextElement(sub1, y); - - if (totalRequests == 2) { - totalRequests += expectRequest(); - } - - final ManualSubscriber sub2 = newSubscriber(); - - // sub1 now has 18 pending - // sub2 has 0 pending - - if (doesCoordinatedEmission()) { - sub2.expectNone(); // since sub2 hasn't requested anything yet - - sub2.request(1); - - final T z = sendNextTFromUpstream(); - expectNextElement(sub1, z); - expectNextElement(sub2, z); - } else { - final T z = sendNextTFromUpstream(); - expectNextElement(sub1, z, - "If the Processor coordinates requests/emissions when having multiple Subscribers" - + " at once, please override doesCoordinatedEmission() to return true in this " - + "IdentityProcessorVerification to allow this test to pass."); - sub2.expectNone(); // since sub2 hasn't requested anything yet - - sub2.request(1); - expectNextElement(sub2, z); - } - if (totalRequests == 3) { - expectRequest(); - } - - // to avoid error messages during test harness shutdown - sendCompletion(); - sub1.expectCompletion(env.defaultTimeoutMillis()); - sub2.expectCompletion(env.defaultTimeoutMillis()); - - env.verifyNoAsyncErrorsNoDelay(); - }}; - } - }); - } - - /////////////////////// TEST INFRASTRUCTURE ////////////////////// - - public void notVerified() { - publisherVerification.notVerified(); - } - - public void notVerified(String message) { - publisherVerification.notVerified(message); - } - - /** - * Test for feature that REQUIRES multiple subscribers to be supported by Publisher. - */ - public void optionalMultipleSubscribersTest(long requiredSubscribersSupport, Function body) throws Throwable { - if (requiredSubscribersSupport > maxSupportedSubscribers()) - notVerified(String.format("The Publisher under test only supports %d subscribers, while this test requires at least %d to run.", - maxSupportedSubscribers(), requiredSubscribersSupport)); - else body.apply(requiredSubscribersSupport); - } - - public abstract class TestSetup extends ManualPublisher { - final private ManualSubscriber tees; // gives us access to an infinite stream of T values - private Set seenTees = new HashSet(); - - final Processor processor; - - public TestSetup(TestEnvironment env, int testBufferSize) throws InterruptedException { - super(env); - tees = env.newManualSubscriber(createHelperPublisher(Long.MAX_VALUE)); - processor = createIdentityProcessor(testBufferSize); - subscribe(processor); - } - - public ManualSubscriber newSubscriber() throws InterruptedException { - return env.newManualSubscriber(processor); - } - - public T nextT() throws InterruptedException { - final T t = tees.requestNextElement(); - if (seenTees.contains(t)) { - env.flop(String.format("Helper publisher illegally produced the same element %s twice", t)); - } - seenTees.add(t); - return t; - } - - public void expectNextElement(ManualSubscriber sub, T expected) throws InterruptedException { - final T elem = sub.nextElement(String.format("timeout while awaiting %s", expected)); - if (!elem.equals(expected)) { - env.flop(String.format("Received `onNext(%s)` on downstream but expected `onNext(%s)`", elem, expected)); - } - } - - public void expectNextElement(ManualSubscriber sub, T expected, String errorMessageAddendum) throws InterruptedException { - final T elem = sub.nextElement(String.format("timeout while awaiting %s. %s", expected, errorMessageAddendum)); - if (!elem.equals(expected)) { - env.flop(String.format("Received `onNext(%s)` on downstream but expected `onNext(%s)`", elem, expected)); - } - } - - public T sendNextTFromUpstream() throws InterruptedException { - final T x = nextT(); - sendNext(x); - return x; - } - } - - public class ManualSubscriberWithErrorCollection extends ManualSubscriberWithSubscriptionSupport { - Promise error; - - public ManualSubscriberWithErrorCollection(TestEnvironment env) { - super(env); - error = new Promise(env); - } - - @Override - public void onError(Throwable cause) { - error.complete(cause); - } - - public void expectError(Throwable cause) throws InterruptedException { - expectError(cause, env.defaultTimeoutMillis()); - } - - @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - public void expectError(Throwable cause, long timeoutMillis) throws InterruptedException { - error.expectCompletion(timeoutMillis, "Did not receive expected error on downstream"); - if (!cause.equals(error.value())) { - env.flop(String.format("Expected error %s but got %s", cause, error.value())); - } - } - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/PublisherVerification.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/PublisherVerification.java deleted file mode 100644 index fdfd24582ef..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/PublisherVerification.java +++ /dev/null @@ -1,1245 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck; - -import org.reactivestreams.Publisher; -import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; -import org.reactivestreams.tck.TestEnvironment.BlackholeSubscriberWithSubscriptionSupport; -import org.reactivestreams.tck.TestEnvironment.Latch; -import org.reactivestreams.tck.TestEnvironment.ManualSubscriber; -import org.reactivestreams.tck.TestEnvironment.ManualSubscriberWithSubscriptionSupport; -import org.reactivestreams.tck.flow.support.Function; -import org.reactivestreams.tck.flow.support.Optional; -import org.reactivestreams.tck.flow.support.PublisherVerificationRules; -import org.testng.SkipException; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import java.lang.Override; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; - -/** - * Provides tests for verifying {@code Publisher} specification rules. - * - * @see org.reactivestreams.Publisher - */ -public abstract class PublisherVerification implements PublisherVerificationRules { - - private static final String PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS_ENV = "PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS"; - private static final long DEFAULT_PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS = 300L; - - private final TestEnvironment env; - - /** - * The amount of time after which a cancelled Subscriber reference should be dropped. - * See Rule 3.13 for details. - */ - private final long publisherReferenceGCTimeoutMillis; - - /** - * Constructs a new verification class using the given env and configuration. - * - * @param publisherReferenceGCTimeoutMillis used to determine after how much time a reference to a Subscriber should be already dropped by the Publisher. - */ - public PublisherVerification(TestEnvironment env, long publisherReferenceGCTimeoutMillis) { - this.env = env; - this.publisherReferenceGCTimeoutMillis = publisherReferenceGCTimeoutMillis; - } - - /** - * Constructs a new verification class using the given env and configuration. - * - * The value for {@code publisherReferenceGCTimeoutMillis} will be obtained by using {@link PublisherVerification#envPublisherReferenceGCTimeoutMillis()}. - */ - public PublisherVerification(TestEnvironment env) { - this.env = env; - this.publisherReferenceGCTimeoutMillis = envPublisherReferenceGCTimeoutMillis(); - } - - /** - * Tries to parse the env variable {@code PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS} as long and returns the value if present, - * OR its default value ({@link PublisherVerification#DEFAULT_PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS}). - * - * This value is used to determine after how much time a reference to a Subscriber should be already dropped by the Publisher. - * - * @throws java.lang.IllegalArgumentException when unable to parse the env variable - */ - public static long envPublisherReferenceGCTimeoutMillis() { - final String envMillis = System.getenv(PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS_ENV); - if (envMillis == null) return DEFAULT_PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS; - else try { - return Long.parseLong(envMillis); - } catch (NumberFormatException ex) { - throw new IllegalArgumentException(String.format("Unable to parse %s env value [%s] as long!", PUBLISHER_REFERENCE_GC_TIMEOUT_MILLIS_ENV, envMillis), ex); - } - } - - /** - * This is the main method you must implement in your test incarnation. - * It must create a Publisher for a stream with exactly the given number of elements. - * If `elements` is `Long.MAX_VALUE` the produced stream must be infinite. - */ - public abstract Publisher createPublisher(long elements); - - /** - * By implementing this method, additional TCK tests concerning a "failed" publishers will be run. - * - * The expected behaviour of the {@link Publisher} returned by this method is hand out a subscription, - * followed by signalling {@code onError} on it, as specified by Rule 1.9. - * - * If you ignore these additional tests, return {@code null} from this method. - */ - public abstract Publisher createFailedPublisher(); - - - /** - * Override and return lower value if your Publisher is only able to produce a known number of elements. - * For example, if it is designed to return at-most-one element, return {@code 1} from this method. - * - * Defaults to {@code Long.MAX_VALUE - 1}, meaning that the Publisher can be produce a huge but NOT an unbounded number of elements. - * - * To mark your Publisher will *never* signal an {@code onComplete} override this method and return {@code Long.MAX_VALUE}, - * which will result in *skipping all tests which require an onComplete to be triggered* (!). - */ - public long maxElementsFromPublisher() { - return Long.MAX_VALUE - 1; - } - - /** - * Override and return {@code true} in order to skip executing tests marked as {@code Stochastic}. - * Stochastic in this case means that the Rule is impossible or infeasible to deterministically verify— - * usually this means that this test case can yield false positives ("be green") even if for some case, - * the given implementation may violate the tested behaviour. - */ - public boolean skipStochasticTests() { - return false; - } - - /** - * In order to verify rule 3.3 of the reactive streams spec, this number will be used to check if a - * {@code Subscription} actually solves the "unbounded recursion" problem by not allowing the number of - * recursive calls to exceed the number returned by this method. - * - * @see reactive streams spec, rule 3.3 - * @see PublisherVerification#required_spec303_mustNotAllowUnboundedRecursion() - */ - public long boundedDepthOfOnNextAndRequestRecursion() { - return 1; - } - - ////////////////////// TEST ENV CLEANUP ///////////////////////////////////// - - @BeforeMethod - public void setUp() throws Exception { - env.clearAsyncErrors(); - } - - ////////////////////// TEST SETUP VERIFICATION ////////////////////////////// - - @Override @Test - public void required_createPublisher1MustProduceAStreamOfExactly1Element() throws Throwable { - activePublisherTest(1, true, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws InterruptedException { - ManualSubscriber sub = env.newManualSubscriber(pub); - assertTrue(requestNextElementOrEndOfStream(pub, sub).isDefined(), String.format("Publisher %s produced no elements", pub)); - sub.requestEndOfStream(); - } - - Optional requestNextElementOrEndOfStream(Publisher pub, ManualSubscriber sub) throws InterruptedException { - return sub.requestNextElementOrEndOfStream(String.format("Timeout while waiting for next element from Publisher %s", pub)); - } - - }); - } - - @Override @Test - public void required_createPublisher3MustProduceAStreamOfExactly3Elements() throws Throwable { - activePublisherTest(3, true, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws InterruptedException { - ManualSubscriber sub = env.newManualSubscriber(pub); - assertTrue(requestNextElementOrEndOfStream(pub, sub).isDefined(), String.format("Publisher %s produced no elements", pub)); - assertTrue(requestNextElementOrEndOfStream(pub, sub).isDefined(), String.format("Publisher %s produced only 1 element", pub)); - assertTrue(requestNextElementOrEndOfStream(pub, sub).isDefined(), String.format("Publisher %s produced only 2 elements", pub)); - sub.requestEndOfStream(); - } - - Optional requestNextElementOrEndOfStream(Publisher pub, ManualSubscriber sub) throws InterruptedException { - return sub.requestNextElementOrEndOfStream(String.format("Timeout while waiting for next element from Publisher %s", pub)); - } - - }); - } - - @Override @Test - public void required_validate_maxElementsFromPublisher() throws Exception { - assertTrue(maxElementsFromPublisher() >= 0, "maxElementsFromPublisher MUST return a number >= 0"); - } - - @Override @Test - public void required_validate_boundedDepthOfOnNextAndRequestRecursion() throws Exception { - assertTrue(boundedDepthOfOnNextAndRequestRecursion() >= 1, "boundedDepthOfOnNextAndRequestRecursion must return a number >= 1"); - } - - - ////////////////////// SPEC RULE VERIFICATION /////////////////////////////// - - @Override @Test - public void required_spec101_subscriptionRequestMustResultInTheCorrectNumberOfProducedElements() throws Throwable { - activePublisherTest(5, false, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws InterruptedException { - - ManualSubscriber sub = env.newManualSubscriber(pub); - try { - sub.expectNone(String.format("Publisher %s produced value before the first `request`: ", pub)); - sub.request(1); - sub.nextElement(String.format("Publisher %s produced no element after first `request`", pub)); - sub.expectNone(String.format("Publisher %s produced unrequested: ", pub)); - - sub.request(1); - sub.request(2); - sub.nextElements(3, env.defaultTimeoutMillis(), String.format("Publisher %s produced less than 3 elements after two respective `request` calls", pub)); - - sub.expectNone(String.format("Publisher %sproduced unrequested ", pub)); - } finally { - sub.cancel(); - } - } - }); - } - - @Override @Test - public void required_spec102_maySignalLessThanRequestedAndTerminateSubscription() throws Throwable { - final int elements = 3; - final int requested = 10; - - activePublisherTest(elements, true, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - final ManualSubscriber sub = env.newManualSubscriber(pub); - sub.request(requested); - sub.nextElements(elements); - sub.expectCompletion(); - } - }); - } - - @Override @Test - public void stochastic_spec103_mustSignalOnMethodsSequentially() throws Throwable { - final int iterations = 100; - final int elements = 10; - - stochasticTest(iterations, new Function() { - @Override - public Void apply(final Integer runNumber) throws Throwable { - activePublisherTest(elements, true, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - final Latch completionLatch = new Latch(env); - - final AtomicInteger gotElements = new AtomicInteger(0); - pub.subscribe(new Subscriber() { - private Subscription subs; - - private ConcurrentAccessBarrier concurrentAccessBarrier = new ConcurrentAccessBarrier(); - - /** - * Concept wise very similar to a {@link org.reactivestreams.tck.TestEnvironment.Latch}, serves to protect - * a critical section from concurrent access, with the added benefit of Thread tracking and same-thread-access awareness. - * - * Since a Synchronous Publisher may choose to synchronously (using the same {@link Thread}) call - * {@code onNext} directly from either {@code subscribe} or {@code request} a plain Latch is not enough - * to verify concurrent access safety - one needs to track if the caller is not still using the calling thread - * to enter subsequent critical sections ("nesting" them effectively). - */ - final class ConcurrentAccessBarrier { - private AtomicReference currentlySignallingThread = new AtomicReference(null); - private volatile String previousSignal = null; - - public void enterSignal(String signalName) { - if((!currentlySignallingThread.compareAndSet(null, Thread.currentThread())) && !isSynchronousSignal()) { - env.flop(String.format( - "Illegal concurrent access detected (entering critical section)! " + - "%s emited %s signal, before %s finished its %s signal.", - Thread.currentThread(), signalName, currentlySignallingThread.get(), previousSignal)); - } - this.previousSignal = signalName; - } - - public void leaveSignal(String signalName) { - currentlySignallingThread.set(null); - this.previousSignal = signalName; - } - - private boolean isSynchronousSignal() { - return (previousSignal != null) && Thread.currentThread().equals(currentlySignallingThread.get()); - } - - } - - @Override - public void onSubscribe(Subscription s) { - final String signal = "onSubscribe()"; - concurrentAccessBarrier.enterSignal(signal); - - subs = s; - subs.request(1); - - concurrentAccessBarrier.leaveSignal(signal); - } - - @Override - public void onNext(T ignore) { - final String signal = String.format("onNext(%s)", ignore); - concurrentAccessBarrier.enterSignal(signal); - - if (gotElements.incrementAndGet() <= elements) // requesting one more than we know are in the stream (some Publishers need this) - subs.request(1); - - concurrentAccessBarrier.leaveSignal(signal); - } - - @Override - public void onError(Throwable t) { - final String signal = String.format("onError(%s)", t.getMessage()); - concurrentAccessBarrier.enterSignal(signal); - - // ignore value - - concurrentAccessBarrier.leaveSignal(signal); - } - - @Override - public void onComplete() { - final String signal = "onComplete()"; - concurrentAccessBarrier.enterSignal(signal); - - // entering for completeness - - concurrentAccessBarrier.leaveSignal(signal); - completionLatch.close(); - } - }); - - completionLatch.expectClose( - elements * env.defaultTimeoutMillis(), - String.format("Failed in iteration %d of %d. Expected completion signal after signalling %d elements (signalled %d), yet did not receive it", - runNumber, iterations, elements, gotElements.get())); - } - }); - return null; - } - }); - } - - @Override @Test - public void optional_spec104_mustSignalOnErrorWhenFails() throws Throwable { - try { - whenHasErrorPublisherTest(new PublisherTestRun() { - @Override - public void run(final Publisher pub) throws InterruptedException { - final Latch onErrorlatch = new Latch(env); - final Latch onSubscribeLatch = new Latch(env); - pub.subscribe(new TestEnvironment.TestSubscriber(env) { - @Override - public void onSubscribe(Subscription subs) { - onSubscribeLatch.assertOpen("Only one onSubscribe call expected"); - onSubscribeLatch.close(); - } - @Override - public void onError(Throwable cause) { - onSubscribeLatch.assertClosed("onSubscribe should be called prior to onError always"); - onErrorlatch.assertOpen(String.format("Error-state Publisher %s called `onError` twice on new Subscriber", pub)); - onErrorlatch.close(); - } - }); - - onSubscribeLatch.expectClose("Should have received onSubscribe"); - onErrorlatch.expectClose(String.format("Error-state Publisher %s did not call `onError` on new Subscriber", pub)); - - env.verifyNoAsyncErrors(); - } - }); - } catch (SkipException se) { - throw se; - } catch (Throwable ex) { - // we also want to catch AssertionErrors and anything the publisher may have thrown inside subscribe - // which was wrong of him - he should have signalled on error using onError - throw new RuntimeException(String.format("Publisher threw exception (%s) instead of signalling error via onError!", ex.getMessage()), ex); - } - } - - @Override @Test - public void required_spec105_mustSignalOnCompleteWhenFiniteStreamTerminates() throws Throwable { - activePublisherTest(3, true, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - ManualSubscriber sub = env.newManualSubscriber(pub); - sub.requestNextElement(); - sub.requestNextElement(); - sub.requestNextElement(); - sub.requestEndOfStream(); - sub.expectNone(); - } - }); - } - - @Override @Test - public void optional_spec105_emptyStreamMustTerminateBySignallingOnComplete() throws Throwable { - optionalActivePublisherTest(0, true, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - ManualSubscriber sub = env.newManualSubscriber(pub); - sub.request(1); - sub.expectCompletion(); - sub.expectNone(); - } - }); - } - - @Override @Test - public void untested_spec106_mustConsiderSubscriptionCancelledAfterOnErrorOrOnCompleteHasBeenCalled() throws Throwable { - notVerified(); // not really testable without more control over the Publisher - } - - @Override @Test - public void required_spec107_mustNotEmitFurtherSignalsOnceOnCompleteHasBeenSignalled() throws Throwable { - activePublisherTest(1, true, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - ManualSubscriber sub = env.newManualSubscriber(pub); - sub.request(10); - sub.nextElement(); - sub.expectCompletion(); - - sub.request(10); - sub.expectNone(); - } - }); - } - - @Override @Test - public void untested_spec107_mustNotEmitFurtherSignalsOnceOnErrorHasBeenSignalled() throws Throwable { - notVerified(); // can we meaningfully test this, without more control over the publisher? - } - - @Override @Test - public void untested_spec108_possiblyCanceledSubscriptionShouldNotReceiveOnErrorOrOnCompleteSignals() throws Throwable { - notVerified(); // can we meaningfully test this? - } - - @Override @Test - public void untested_spec109_subscribeShouldNotThrowNonFatalThrowable() throws Throwable { - notVerified(); // can we meaningfully test this? - } - - @Override @Test - public void required_spec109_subscribeThrowNPEOnNullSubscriber() throws Throwable { - activePublisherTest(0, false, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - try { - pub.subscribe(null); - env.flop("Publisher did not throw a NullPointerException when given a null Subscribe in subscribe"); - } catch (NullPointerException ignored) { - // valid behaviour - } - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - @Override @Test - public void required_spec109_mustIssueOnSubscribeForNonNullSubscriber() throws Throwable { - activePublisherTest(0, false, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - final Latch onSubscribeLatch = new Latch(env); - final AtomicReference cancel = new AtomicReference(); - try { - pub.subscribe(new Subscriber() { - @Override - public void onError(Throwable cause) { - onSubscribeLatch.assertClosed("onSubscribe should be called prior to onError always"); - } - - @Override - public void onSubscribe(Subscription subs) { - cancel.set(subs); - onSubscribeLatch.assertOpen("Only one onSubscribe call expected"); - onSubscribeLatch.close(); - } - - @Override - public void onNext(T elem) { - onSubscribeLatch.assertClosed("onSubscribe should be called prior to onNext always"); - } - - @Override - public void onComplete() { - onSubscribeLatch.assertClosed("onSubscribe should be called prior to onComplete always"); - } - }); - onSubscribeLatch.expectClose("Should have received onSubscribe"); - env.verifyNoAsyncErrorsNoDelay(); - } finally { - Subscription s = cancel.getAndSet(null); - if (s != null) { - s.cancel(); - } - } - } - }); - } - - @Override @Test - public void required_spec109_mayRejectCallsToSubscribeIfPublisherIsUnableOrUnwillingToServeThemRejectionMustTriggerOnErrorAfterOnSubscribe() throws Throwable { - whenHasErrorPublisherTest(new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - final Latch onErrorLatch = new Latch(env); - final Latch onSubscribeLatch = new Latch(env); - ManualSubscriberWithSubscriptionSupport sub = new ManualSubscriberWithSubscriptionSupport(env) { - @Override - public void onError(Throwable cause) { - onSubscribeLatch.assertClosed("onSubscribe should be called prior to onError always"); - onErrorLatch.assertOpen("Only one onError call expected"); - onErrorLatch.close(); - } - - @Override - public void onSubscribe(Subscription subs) { - onSubscribeLatch.assertOpen("Only one onSubscribe call expected"); - onSubscribeLatch.close(); - } - }; - pub.subscribe(sub); - onSubscribeLatch.expectClose("Should have received onSubscribe"); - onErrorLatch.expectClose("Should have received onError"); - - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - @Override @Test - public void untested_spec110_rejectASubscriptionRequestIfTheSameSubscriberSubscribesTwice() throws Throwable { - notVerified(); // can we meaningfully test this? - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#1.11 - @Override @Test - public void optional_spec111_maySupportMultiSubscribe() throws Throwable { - optionalActivePublisherTest(1, false, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - ManualSubscriber sub1 = env.newManualSubscriber(pub); - ManualSubscriber sub2 = env.newManualSubscriber(pub); - - try { - env.verifyNoAsyncErrors(); - } finally { - try { - sub1.cancel(); - } finally { - sub2.cancel(); - } - } - } - }); - } - - @Override @Test - public void optional_spec111_registeredSubscribersMustReceiveOnNextOrOnCompleteSignals() throws Throwable { - optionalActivePublisherTest(1, false, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - ManualSubscriber sub1 = env.newManualSubscriber(pub); - ManualSubscriber sub2 = env.newManualSubscriber(pub); - // Since we're testing the case when the Publisher DOES support the optional multi-subscribers scenario, - // and decides if it handles them uni-cast or multi-cast, we don't know which subscriber will receive an - // onNext (and optional onComplete) signal(s) and which just onComplete signal. - // Plus, even if subscription assumed to be unicast, it's implementation choice, which one will be signalled - // with onNext. - sub1.requestNextElementOrEndOfStream(); - sub2.requestNextElementOrEndOfStream(); - try { - env.verifyNoAsyncErrors(); - } finally { - try { - sub1.cancel(); - } finally { - sub2.cancel(); - } - } - } - }); - } - - @Override @Test - public void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingOneByOne() throws Throwable { - optionalActivePublisherTest(5, true, new PublisherTestRun() { // This test is skipped if the publisher is unbounded (never sends onComplete) - @Override - public void run(Publisher pub) throws InterruptedException { - ManualSubscriber sub1 = env.newManualSubscriber(pub); - ManualSubscriber sub2 = env.newManualSubscriber(pub); - ManualSubscriber sub3 = env.newManualSubscriber(pub); - - sub1.request(1); - T x1 = sub1.nextElement(String.format("Publisher %s did not produce the requested 1 element on 1st subscriber", pub)); - sub2.request(2); - List y1 = sub2.nextElements(2, String.format("Publisher %s did not produce the requested 2 elements on 2nd subscriber", pub)); - sub1.request(1); - T x2 = sub1.nextElement(String.format("Publisher %s did not produce the requested 1 element on 1st subscriber", pub)); - sub3.request(3); - List z1 = sub3.nextElements(3, String.format("Publisher %s did not produce the requested 3 elements on 3rd subscriber", pub)); - sub3.request(1); - T z2 = sub3.nextElement(String.format("Publisher %s did not produce the requested 1 element on 3rd subscriber", pub)); - sub3.request(1); - T z3 = sub3.nextElement(String.format("Publisher %s did not produce the requested 1 element on 3rd subscriber", pub)); - sub3.requestEndOfStream(String.format("Publisher %s did not complete the stream as expected on 3rd subscriber", pub)); - sub2.request(3); - List y2 = sub2.nextElements(3, String.format("Publisher %s did not produce the requested 3 elements on 2nd subscriber", pub)); - sub2.requestEndOfStream(String.format("Publisher %s did not complete the stream as expected on 2nd subscriber", pub)); - sub1.request(2); - List x3 = sub1.nextElements(2, String.format("Publisher %s did not produce the requested 2 elements on 1st subscriber", pub)); - sub1.request(1); - T x4 = sub1.nextElement(String.format("Publisher %s did not produce the requested 1 element on 1st subscriber", pub)); - sub1.requestEndOfStream(String.format("Publisher %s did not complete the stream as expected on 1st subscriber", pub)); - - @SuppressWarnings("unchecked") - List r = new ArrayList(Arrays.asList(x1, x2)); - r.addAll(x3); - r.addAll(Collections.singleton(x4)); - - List check1 = new ArrayList(y1); - check1.addAll(y2); - - //noinspection unchecked - List check2 = new ArrayList(z1); - check2.add(z2); - check2.add(z3); - - assertEquals(r, check1, String.format("Publisher %s did not produce the same element sequence for subscribers 1 and 2", pub)); - assertEquals(r, check2, String.format("Publisher %s did not produce the same element sequence for subscribers 1 and 3", pub)); - } - }); - } - - @Override @Test - public void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfront() throws Throwable { - optionalActivePublisherTest(3, false, new PublisherTestRun() { // This test is skipped if the publisher cannot produce enough elements - @Override - public void run(Publisher pub) throws Throwable { - ManualSubscriber sub1 = env.newManualSubscriber(pub); - ManualSubscriber sub2 = env.newManualSubscriber(pub); - ManualSubscriber sub3 = env.newManualSubscriber(pub); - - List received1 = new ArrayList(); - List received2 = new ArrayList(); - List received3 = new ArrayList(); - - // if the publisher must touch it's source to notice it's been drained, the OnComplete won't come until we ask for more than it actually contains... - // edgy edge case? - sub1.request(4); - sub2.request(4); - sub3.request(4); - - received1.addAll(sub1.nextElements(3)); - received2.addAll(sub2.nextElements(3)); - received3.addAll(sub3.nextElements(3)); - - // NOTE: can't check completion, the Publisher may not be able to signal it - // a similar test *with* completion checking is implemented - - assertEquals(received1, received2, String.format("Expected elements to be signaled in the same sequence to 1st and 2nd subscribers")); - assertEquals(received2, received3, String.format("Expected elements to be signaled in the same sequence to 2nd and 3rd subscribers")); - } - }); - } - - @Override @Test - public void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfrontAndCompleteAsExpected() throws Throwable { - optionalActivePublisherTest(3, true, new PublisherTestRun() { // This test is skipped if the publisher is unbounded (never sends onComplete) - @Override - public void run(Publisher pub) throws Throwable { - ManualSubscriber sub1 = env.newManualSubscriber(pub); - ManualSubscriber sub2 = env.newManualSubscriber(pub); - ManualSubscriber sub3 = env.newManualSubscriber(pub); - - List received1 = new ArrayList(); - List received2 = new ArrayList(); - List received3 = new ArrayList(); - - // if the publisher must touch it's source to notice it's been drained, the OnComplete won't come until we ask for more than it actually contains... - // edgy edge case? - sub1.request(4); - sub2.request(4); - sub3.request(4); - - received1.addAll(sub1.nextElements(3)); - received2.addAll(sub2.nextElements(3)); - received3.addAll(sub3.nextElements(3)); - - sub1.expectCompletion(); - sub2.expectCompletion(); - sub3.expectCompletion(); - - assertEquals(received1, received2, String.format("Expected elements to be signaled in the same sequence to 1st and 2nd subscribers")); - assertEquals(received2, received3, String.format("Expected elements to be signaled in the same sequence to 2nd and 3rd subscribers")); - } - }); - } - - ///////////////////// SUBSCRIPTION TESTS ////////////////////////////////// - - @Override @Test - public void required_spec302_mustAllowSynchronousRequestCallsFromOnNextAndOnSubscribe() throws Throwable { - activePublisherTest(6, false, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - ManualSubscriber sub = new ManualSubscriber(env) { - @Override - public void onSubscribe(Subscription subs) { - this.subscription.completeImmediatly(subs); - - subs.request(1); - subs.request(1); - subs.request(1); - } - - @Override - public void onNext(T element) { - Subscription subs = this.subscription.value(); - subs.request(1); - } - }; - - env.subscribe(pub, sub); - - env.verifyNoAsyncErrors(); - } - }); - } - - @Override @Test - public void required_spec303_mustNotAllowUnboundedRecursion() throws Throwable { - final long oneMoreThanBoundedLimit = boundedDepthOfOnNextAndRequestRecursion() + 1; - - activePublisherTest(oneMoreThanBoundedLimit, false, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - final ThreadLocal stackDepthCounter = new ThreadLocal() { - @Override - protected Long initialValue() { - return 0L; - } - }; - - final Latch runCompleted = new Latch(env); - - final ManualSubscriber sub = new ManualSubscriberWithSubscriptionSupport(env) { - // counts the number of signals received, used to break out from possibly infinite request/onNext loops - long signalsReceived = 0L; - - @Override - public void onNext(T element) { - // NOT calling super.onNext as this test only cares about stack depths, not the actual values of elements - // which also simplifies this test as we do not have to drain the test buffer, which would otherwise be in danger of overflowing - - signalsReceived += 1; - stackDepthCounter.set(stackDepthCounter.get() + 1); - if (env.debugEnabled()) { - env.debug(String.format("%s(recursion depth: %d)::onNext(%s)", this, stackDepthCounter.get(), element)); - } - - final long callsUntilNow = stackDepthCounter.get(); - if (callsUntilNow > boundedDepthOfOnNextAndRequestRecursion()) { - env.flop(String.format("Got %d onNext calls within thread: %s, yet expected recursive bound was %d", - callsUntilNow, Thread.currentThread(), boundedDepthOfOnNextAndRequestRecursion())); - - // stop the recursive call chain - runCompleted.close(); - return; - } else if (signalsReceived >= oneMoreThanBoundedLimit) { - // since max number of signals reached, and recursion depth not exceeded, we judge this as a success and - // stop the recursive call chain - runCompleted.close(); - return; - } - - // request more right away, the Publisher must break the recursion - subscription.value().request(1); - - stackDepthCounter.set(stackDepthCounter.get() - 1); - } - - @Override - public void onComplete() { - super.onComplete(); - runCompleted.close(); - } - - @Override - public void onError(Throwable cause) { - super.onError(cause); - runCompleted.close(); - } - }; - - try { - env.subscribe(pub, sub); - - sub.request(1); // kick-off the `request -> onNext -> request -> onNext -> ...` - - final String msg = String.format("Unable to validate call stack depth safety, " + - "awaited at-most %s signals (`maxOnNextSignalsInRecursionTest()`) or completion", - oneMoreThanBoundedLimit); - runCompleted.expectClose(env.defaultTimeoutMillis(), msg); - env.verifyNoAsyncErrorsNoDelay(); - } finally { - // since the request/onNext recursive calls may keep the publisher running "forever", - // we MUST cancel it manually before exiting this test case - sub.cancel(); - } - } - }); - } - - @Override @Test - public void untested_spec304_requestShouldNotPerformHeavyComputations() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - @Override @Test - public void untested_spec305_cancelMustNotSynchronouslyPerformHeavyComputation() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - @Override @Test - public void required_spec306_afterSubscriptionIsCancelledRequestMustBeNops() throws Throwable { - activePublisherTest(3, false, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - - // override ManualSubscriberWithSubscriptionSupport#cancel because by default a ManualSubscriber will drop the - // subscription once it's cancelled (as expected). - // In this test however it must keep the cancelled Subscription and keep issuing `request(long)` to it. - ManualSubscriber sub = new ManualSubscriberWithSubscriptionSupport(env) { - @Override - public void cancel() { - if (subscription.isCompleted()) { - subscription.value().cancel(); - } else { - env.flop("Cannot cancel a subscription before having received it"); - } - } - }; - - env.subscribe(pub, sub); - - sub.cancel(); - sub.request(1); - sub.request(1); - sub.request(1); - - sub.expectNone(); - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - @Override @Test - public void required_spec307_afterSubscriptionIsCancelledAdditionalCancelationsMustBeNops() throws Throwable { - activePublisherTest(1, false, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - final ManualSubscriber sub = env.newManualSubscriber(pub); - - // leak the Subscription - final Subscription subs = sub.subscription.value(); - - subs.cancel(); - subs.cancel(); - subs.cancel(); - - sub.expectNone(); - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - @Override @Test - public void required_spec309_requestZeroMustSignalIllegalArgumentException() throws Throwable { - activePublisherTest(10, false, new PublisherTestRun() { - @Override public void run(Publisher pub) throws Throwable { - final ManualSubscriber sub = env.newManualSubscriber(pub); - sub.request(0); - sub.expectError(IllegalArgumentException.class); - } - }); - } - - @Override @Test - public void required_spec309_requestNegativeNumberMustSignalIllegalArgumentException() throws Throwable { - activePublisherTest(10, false, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - final ManualSubscriber sub = env.newManualSubscriber(pub); - final Random r = new Random(); - sub.request(-r.nextInt(Integer.MAX_VALUE) - 1); - // we do require implementations to mention the rule number at the very least, or mentioning that the non-negative request is the problem - sub.expectError(IllegalArgumentException.class); - } - }); - } - - @Override @Test - public void optional_spec309_requestNegativeNumberMaySignalIllegalArgumentExceptionWithSpecificMessage() throws Throwable { - optionalActivePublisherTest(10, false, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - final ManualSubscriber sub = env.newManualSubscriber(pub); - final Random r = new Random(); - sub.request(-r.nextInt(Integer.MAX_VALUE) - 1); - // we do require implementations to mention the rule number at the very least, or mentioning that the non-negative request is the problem - sub.expectErrorWithMessage(IllegalArgumentException.class, Arrays.asList("3.9", "non-positive subscription request", "negative subscription request")); - } - }); - } - - @Override @Test - public void required_spec312_cancelMustMakeThePublisherToEventuallyStopSignaling() throws Throwable { - // the publisher is able to signal more elements than the subscriber will be requesting in total - final int publisherElements = 20; - - final int demand1 = 10; - final int demand2 = 5; - final int totalDemand = demand1 + demand2; - - activePublisherTest(publisherElements, false, new PublisherTestRun() { - @Override @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - public void run(Publisher pub) throws Throwable { - final ManualSubscriber sub = env.newManualSubscriber(pub); - - sub.request(demand1); - sub.request(demand2); - - /* - NOTE: The order of the nextElement/cancel calls below is very important (!) - - If this ordering was reversed, given an asynchronous publisher, - the following scenario would be *legal* and would break this test: - - > AsyncPublisher receives request(10) - it does not emit data right away, it's asynchronous - > AsyncPublisher receives request(5) - demand is now 15 - ! AsyncPublisher didn't emit any onNext yet (!) - > AsyncPublisher receives cancel() - handles it right away, by "stopping itself" for example - ! cancel was handled hefore the AsyncPublisher ever got the chance to emit data - ! the subscriber ends up never receiving even one element - the test is stuck (and fails, even on valid Publisher) - - Which is why we must first expect an element, and then cancel, once the producing is "running". - */ - sub.nextElement(); - sub.cancel(); - - int onNextsSignalled = 1; - - boolean stillBeingSignalled; - do { - // put asyncError if onNext signal received - sub.expectNone(); - Throwable error = env.dropAsyncError(); - - if (error == null) { - stillBeingSignalled = false; - } else { - onNextsSignalled += 1; - stillBeingSignalled = true; - } - - // if the Publisher tries to emit more elements than was requested (and/or ignores cancellation) this will throw - assertTrue(onNextsSignalled <= totalDemand, - String.format("Publisher signalled [%d] elements, which is more than the signalled demand: %d", - onNextsSignalled, totalDemand)); - - } while (stillBeingSignalled); - } - }); - - env.verifyNoAsyncErrorsNoDelay(); - } - - @Override @Test - public void required_spec313_cancelMustMakeThePublisherEventuallyDropAllReferencesToTheSubscriber() throws Throwable { - final ReferenceQueue> queue = new ReferenceQueue>(); - - final Function, WeakReference>> run = new Function, WeakReference>>() { - @Override - public WeakReference> apply(Publisher pub) throws Exception { - final ManualSubscriber sub = env.newManualSubscriber(pub); - final WeakReference> ref = new WeakReference>(sub, queue); - - sub.request(1); - sub.nextElement(); - sub.cancel(); - - return ref; - } - }; - - activePublisherTest(3, false, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - final WeakReference> ref = run.apply(pub); - - // cancel may be run asynchronously so we add a sleep before running the GC - // to "resolve" the race - Thread.sleep(publisherReferenceGCTimeoutMillis); - System.gc(); - - if (!ref.equals(queue.remove(100))) { - env.flop(String.format("Publisher %s did not drop reference to test subscriber after subscription cancellation", pub)); - } - - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - @Override @Test - public void required_spec317_mustSupportAPendingElementCountUpToLongMaxValue() throws Throwable { - final int totalElements = 3; - - activePublisherTest(totalElements, true, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - ManualSubscriber sub = env.newManualSubscriber(pub); - sub.request(Long.MAX_VALUE); - - sub.nextElements(totalElements); - sub.expectCompletion(); - - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - @Override @Test - public void required_spec317_mustSupportACumulativePendingElementCountUpToLongMaxValue() throws Throwable { - final int totalElements = 3; - - activePublisherTest(totalElements, true, new PublisherTestRun() { - @Override - public void run(Publisher pub) throws Throwable { - final ManualSubscriber sub = env.newManualSubscriber(pub); - sub.request(Long.MAX_VALUE / 2); // pending = Long.MAX_VALUE / 2 - sub.request(Long.MAX_VALUE / 2); // pending = Long.MAX_VALUE - 1 - sub.request(1); // pending = Long.MAX_VALUE - - sub.nextElements(totalElements); - sub.expectCompletion(); - - try { - env.verifyNoAsyncErrorsNoDelay(); - } finally { - sub.cancel(); - } - - } - }); - } - - @Override @Test - public void required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue() throws Throwable { - activePublisherTest(Integer.MAX_VALUE, false, new PublisherTestRun() { - @Override public void run(Publisher pub) throws Throwable { - final ManualSubscriberWithSubscriptionSupport sub = new BlackholeSubscriberWithSubscriptionSupport(env) { - // arbitrarily set limit on nuber of request calls signalled, we expect overflow after already 2 calls, - // so 10 is relatively high and safe even if arbitrarily chosen - int callsCounter = 10; - - @Override - public void onNext(T element) { - if (env.debugEnabled()) { - env.debug(String.format("%s::onNext(%s)", this, element)); - } - if (subscription.isCompleted()) { - if (callsCounter > 0) { - subscription.value().request(Long.MAX_VALUE - 1); - callsCounter--; - } else { - subscription.value().cancel(); - } - } else { - env.flop(String.format("Subscriber::onNext(%s) called before Subscriber::onSubscribe", element)); - } - } - }; - env.subscribe(pub, sub, env.defaultTimeoutMillis()); - - // eventually triggers `onNext`, which will then trigger up to `callsCounter` times `request(Long.MAX_VALUE - 1)` - // we're pretty sure to overflow from those - sub.request(1); - - // no onError should be signalled - try { - env.verifyNoAsyncErrors(); - } finally { - sub.cancel(); - } - } - }); - } - - ///////////////////// ADDITIONAL "COROLLARY" TESTS //////////////////////// - - ///////////////////// TEST INFRASTRUCTURE ///////////////////////////////// - - public interface PublisherTestRun { - public void run(Publisher pub) throws Throwable; - } - - /** - * Test for feature that SHOULD/MUST be implemented, using a live publisher. - * - * @param elements the number of elements the Publisher under test must be able to emit to run this test - * @param completionSignalRequired true if an {@code onComplete} signal is required by this test to run. - * If the tested Publisher is unable to signal completion, tests requireing onComplete signals will be skipped. - * To signal if your Publisher is able to signal completion see {@link PublisherVerification#maxElementsFromPublisher()}. - */ - public void activePublisherTest(long elements, boolean completionSignalRequired, PublisherTestRun body) throws Throwable { - if (elements > maxElementsFromPublisher()) { - throw new SkipException(String.format("Unable to run this test, as required elements nr: %d is higher than supported by given producer: %d", elements, maxElementsFromPublisher())); - } else if (completionSignalRequired && maxElementsFromPublisher() == Long.MAX_VALUE) { - throw new SkipException("Unable to run this test, as it requires an onComplete signal, " + - "which this Publisher is unable to provide (as signalled by returning Long.MAX_VALUE from `maxElementsFromPublisher()`)"); - } else { - Publisher pub = createPublisher(elements); - body.run(pub); - env.verifyNoAsyncErrorsNoDelay(); - } - } - - /** - * Test for feature that MAY be implemented. This test will be marked as SKIPPED if it fails. - * - * @param elements the number of elements the Publisher under test must be able to emit to run this test - * @param completionSignalRequired true if an {@code onComplete} signal is required by this test to run. - * If the tested Publisher is unable to signal completion, tests requireing onComplete signals will be skipped. - * To signal if your Publisher is able to signal completion see {@link PublisherVerification#maxElementsFromPublisher()}. - */ - public void optionalActivePublisherTest(long elements, boolean completionSignalRequired, PublisherTestRun body) throws Throwable { - if (elements > maxElementsFromPublisher()) { - throw new SkipException(String.format("Unable to run this test, as required elements nr: %d is higher than supported by given producer: %d", elements, maxElementsFromPublisher())); - } else if (completionSignalRequired && maxElementsFromPublisher() == Long.MAX_VALUE) { - throw new SkipException("Unable to run this test, as it requires an onComplete signal, " + - "which this Publisher is unable to provide (as signalled by returning Long.MAX_VALUE from `maxElementsFromPublisher()`)"); - } else { - - final Publisher pub = createPublisher(elements); - final String skipMessage = "Skipped because tested publisher does NOT implement this OPTIONAL requirement."; - - try { - potentiallyPendingTest(pub, body); - } catch (Exception ex) { - notVerified(skipMessage); - } catch (AssertionError ex) { - notVerified(skipMessage + " Reason for skipping was: " + ex.getMessage()); - } - } - } - - public static final String SKIPPING_NO_ERROR_PUBLISHER_AVAILABLE = - "Skipping because no error state Publisher provided, and the test requires it. " + - "Please implement PublisherVerification#createFailedPublisher to run this test."; - - public static final String SKIPPING_OPTIONAL_TEST_FAILED = - "Skipping, because provided Publisher does not pass this *additional* verification."; - /** - * Additional test for Publisher in error state - */ - public void whenHasErrorPublisherTest(PublisherTestRun body) throws Throwable { - potentiallyPendingTest(createFailedPublisher(), body, SKIPPING_NO_ERROR_PUBLISHER_AVAILABLE); - } - - public void potentiallyPendingTest(Publisher pub, PublisherTestRun body) throws Throwable { - potentiallyPendingTest(pub, body, SKIPPING_OPTIONAL_TEST_FAILED); - } - - public void potentiallyPendingTest(Publisher pub, PublisherTestRun body, String message) throws Throwable { - if (pub != null) { - body.run(pub); - } else { - throw new SkipException(message); - } - } - - /** - * Executes a given test body {@code n} times. - * All the test runs must pass in order for the stochastic test to pass. - */ - public void stochasticTest(int n, Function body) throws Throwable { - if (skipStochasticTests()) { - notVerified("Skipping @Stochastic test because `skipStochasticTests()` returned `true`!"); - } - - for (int i = 0; i < n; i++) { - body.apply(i); - } - } - - public void notVerified() { - throw new SkipException("Not verified by this TCK."); - } - - /** - * Return this value from {@link PublisherVerification#maxElementsFromPublisher()} to mark that the given {@link org.reactivestreams.Publisher}, - * is not able to signal completion. For example it is strictly a time-bound or unbounded source of data. - * - * Returning this value from {@link PublisherVerification#maxElementsFromPublisher()} will result in skipping all TCK tests which require onComplete signals! - */ - public long publisherUnableToSignalOnComplete() { - return Long.MAX_VALUE; - } - - public void notVerified(String message) { - throw new SkipException(message); - } - -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/SubscriberBlackboxVerification.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/SubscriberBlackboxVerification.java deleted file mode 100644 index 62c899a7847..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/SubscriberBlackboxVerification.java +++ /dev/null @@ -1,516 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck; - -import org.reactivestreams.Publisher; -import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; -import org.reactivestreams.tck.TestEnvironment.ManualPublisher; -import org.reactivestreams.tck.TestEnvironment.ManualSubscriber; -import org.reactivestreams.tck.flow.support.Optional; -import org.reactivestreams.tck.flow.support.SubscriberBlackboxVerificationRules; -import org.reactivestreams.tck.flow.support.TestException; -import org.testng.SkipException; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import static org.reactivestreams.tck.SubscriberWhiteboxVerification.BlackboxSubscriberProxy; -import static org.testng.Assert.assertTrue; - -/** - * Provides tests for verifying {@link org.reactivestreams.Subscriber} and {@link org.reactivestreams.Subscription} - * specification rules, without any modifications to the tested implementation (also known as "Black Box" testing). - * - * This verification is NOT able to check many of the rules of the spec, and if you want more - * verification of your implementation you'll have to implement {@code org.reactivestreams.tck.SubscriberWhiteboxVerification} - * instead. - * - * @see org.reactivestreams.Subscriber - * @see org.reactivestreams.Subscription - */ -public abstract class SubscriberBlackboxVerification extends WithHelperPublisher - implements SubscriberBlackboxVerificationRules { - - protected final TestEnvironment env; - - protected SubscriberBlackboxVerification(TestEnvironment env) { - this.env = env; - } - - // USER API - - /** - * This is the main method you must implement in your test incarnation. - * It must create a new {@link org.reactivestreams.Subscriber} instance to be subjected to the testing logic. - */ - public abstract Subscriber createSubscriber(); - - /** - * Override this method if the Subscriber implementation you are verifying - * needs an external signal before it signals demand to its Publisher. - * - * By default this method does nothing. - */ - public void triggerRequest(final Subscriber subscriber) { - // this method is intentionally left blank - } - - // ENV SETUP - - /** - * Executor service used by the default provided asynchronous Publisher. - * @see #createHelperPublisher(long) - */ - private ExecutorService publisherExecutor; - @BeforeClass public void startPublisherExecutorService() { publisherExecutor = Executors.newFixedThreadPool(4); } - @AfterClass public void shutdownPublisherExecutorService() { if (publisherExecutor != null) publisherExecutor.shutdown(); } - @Override public ExecutorService publisherExecutorService() { return publisherExecutor; } - - ////////////////////// TEST ENV CLEANUP ///////////////////////////////////// - - @BeforeMethod - public void setUp() throws Exception { - env.clearAsyncErrors(); - } - - ////////////////////// SPEC RULE VERIFICATION /////////////////////////////// - - @Override @Test - public void required_spec201_blackbox_mustSignalDemandViaSubscriptionRequest() throws Throwable { - blackboxSubscriberTest(new BlackboxTestStageTestRun() { - @Override - public void run(BlackboxTestStage stage) throws InterruptedException { - triggerRequest(stage.subProxy().sub()); - final long requested = stage.expectRequest();// assuming subscriber wants to consume elements... - final long signalsToEmit = Math.min(requested, 512); // protecting against Subscriber which sends ridiculous large demand - - // should cope with up to requested number of elements - for (int i = 0; i < signalsToEmit && sampleIsCancelled(stage, i, 10); i++) - stage.signalNext(); - - // we complete after `signalsToEmit` (which can be less than `requested`), - // which is legal under https://github.com/reactive-streams/reactive-streams-jvm#1.2 - stage.sendCompletion(); - } - - /** - * In order to allow some "skid" and not check state on each iteration, - * only check {@code stage.isCancelled} every {@code checkInterval}'th iteration. - */ - private boolean sampleIsCancelled(BlackboxTestStage stage, int i, int checkInterval) throws InterruptedException { - if (i % checkInterval == 0) return stage.isCancelled(); - else return false; - } - }); - } - - @Override @Test - public void untested_spec202_blackbox_shouldAsynchronouslyDispatch() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - @Override @Test - public void required_spec203_blackbox_mustNotCallMethodsOnSubscriptionOrPublisherInOnComplete() throws Throwable { - blackboxSubscriberWithoutSetupTest(new BlackboxTestStageTestRun() { - @Override - public void run(BlackboxTestStage stage) throws Throwable { - final Subscription subs = new Subscription() { - @Override - public void request(long n) { - final Optional onCompleteStackTraceElement = env.findCallerMethodInStackTrace("onComplete"); - if (onCompleteStackTraceElement.isDefined()) { - final StackTraceElement stackElem = onCompleteStackTraceElement.get(); - env.flop(String.format("Subscription::request MUST NOT be called from Subscriber::onComplete (Rule 2.3)! (Caller: %s::%s line %d)", - stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber())); - } - } - - @Override - public void cancel() { - final Optional onCompleteStackElement = env.findCallerMethodInStackTrace("onComplete"); - if (onCompleteStackElement.isDefined()) { - final StackTraceElement stackElem = onCompleteStackElement.get(); - env.flop(String.format("Subscription::cancel MUST NOT be called from Subscriber::onComplete (Rule 2.3)! (Caller: %s::%s line %d)", - stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber())); - } - } - }; - - final Subscriber sub = createSubscriber(); - sub.onSubscribe(subs); - sub.onComplete(); - - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - @Override @Test - public void required_spec203_blackbox_mustNotCallMethodsOnSubscriptionOrPublisherInOnError() throws Throwable { - blackboxSubscriberWithoutSetupTest(new BlackboxTestStageTestRun() { - @Override - public void run(BlackboxTestStage stage) throws Throwable { - final Subscription subs = new Subscription() { - @Override - public void request(long n) { - Throwable thr = new Throwable(); - for (StackTraceElement stackElem : thr.getStackTrace()) { - if (stackElem.getMethodName().equals("onError")) { - env.flop(String.format("Subscription::request MUST NOT be called from Subscriber::onError (Rule 2.3)! (Caller: %s::%s line %d)", - stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber())); - } - } - } - - @Override - public void cancel() { - Throwable thr = new Throwable(); - for (StackTraceElement stackElem : thr.getStackTrace()) { - if (stackElem.getMethodName().equals("onError")) { - env.flop(String.format("Subscription::cancel MUST NOT be called from Subscriber::onError (Rule 2.3)! (Caller: %s::%s line %d)", - stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber())); - } - } - } - }; - - final Subscriber sub = createSubscriber(); - sub.onSubscribe(subs); - sub.onError(new TestException()); - - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - @Override @Test - public void untested_spec204_blackbox_mustConsiderTheSubscriptionAsCancelledInAfterRecievingOnCompleteOrOnError() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - @Override @Test - public void required_spec205_blackbox_mustCallSubscriptionCancelIfItAlreadyHasAnSubscriptionAndReceivesAnotherOnSubscribeSignal() throws Exception { - new BlackboxTestStage(env) {{ - // try to subscribe another time, if the subscriber calls `probe.registerOnSubscribe` the test will fail - final TestEnvironment.Latch secondSubscriptionCancelled = new TestEnvironment.Latch(env); - sub().onSubscribe( - new Subscription() { - @Override - public void request(long elements) { - env.flop(String.format("Subscriber %s illegally called `subscription.request(%s)`!", sub(), elements)); - } - - @Override - public void cancel() { - secondSubscriptionCancelled.close(); - } - - @Override - public String toString() { - return "SecondSubscription(should get cancelled)"; - } - }); - - secondSubscriptionCancelled.expectClose("Expected SecondSubscription given to subscriber to be cancelled, but `Subscription.cancel()` was not called."); - env.verifyNoAsyncErrorsNoDelay(); - sendCompletion(); // we're done, complete the subscriber under test - }}; - } - - @Override @Test - public void untested_spec206_blackbox_mustCallSubscriptionCancelIfItIsNoLongerValid() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - @Override @Test - public void untested_spec207_blackbox_mustEnsureAllCallsOnItsSubscriptionTakePlaceFromTheSameThreadOrTakeCareOfSynchronization() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - // the same thread part of the clause can be verified but that is not very useful, or is it? - } - - @Override @Test - public void untested_spec208_blackbox_mustBePreparedToReceiveOnNextSignalsAfterHavingCalledSubscriptionCancel() throws Throwable { - notVerified(); // cannot be meaningfully tested as black box, or can it? - } - - @Override @Test - public void required_spec209_blackbox_mustBePreparedToReceiveAnOnCompleteSignalWithPrecedingRequestCall() throws Throwable { - blackboxSubscriberTest(new BlackboxTestStageTestRun() { - @Override @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - public void run(BlackboxTestStage stage) throws Throwable { - triggerRequest(stage.subProxy().sub()); - final long notUsed = stage.expectRequest(); // received request signal - stage.sub().onComplete(); - stage.subProxy().expectCompletion(); - } - }); - } - - @Override @Test - public void required_spec209_blackbox_mustBePreparedToReceiveAnOnCompleteSignalWithoutPrecedingRequestCall() throws Throwable { - blackboxSubscriberTest(new BlackboxTestStageTestRun() { - @Override @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - public void run(BlackboxTestStage stage) throws Throwable { - final Subscriber sub = stage.sub(); - sub.onComplete(); - stage.subProxy().expectCompletion(); - } - }); - } - - @Override @Test - public void required_spec210_blackbox_mustBePreparedToReceiveAnOnErrorSignalWithPrecedingRequestCall() throws Throwable { - blackboxSubscriberTest(new BlackboxTestStageTestRun() { - @Override @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - public void run(BlackboxTestStage stage) throws Throwable { - triggerRequest(stage.subProxy().sub()); - final long notUsed = stage.expectRequest(); // received request signal - stage.sub().onError(new TestException()); // in response to that, we fail - stage.subProxy().expectError(Throwable.class); - } - }); - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.10 - @Override @Test - public void required_spec210_blackbox_mustBePreparedToReceiveAnOnErrorSignalWithoutPrecedingRequestCall() throws Throwable { - blackboxSubscriberTest(new BlackboxTestStageTestRun() { - @Override @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - public void run(BlackboxTestStage stage) throws Throwable { - - stage.sub().onError(new TestException()); - stage.subProxy().expectError(Throwable.class); - } - }); - } - - @Override @Test - public void untested_spec211_blackbox_mustMakeSureThatAllCallsOnItsMethodsHappenBeforeTheProcessingOfTheRespectiveEvents() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - @Override @Test - public void untested_spec212_blackbox_mustNotCallOnSubscribeMoreThanOnceBasedOnObjectEquality() throws Throwable { - notVerified(); // cannot be meaningfully tested as black box, or can it? - } - - @Override @Test - public void untested_spec213_blackbox_failingOnSignalInvocation() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - @Override @Test - public void required_spec213_blackbox_onSubscribe_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable { - blackboxSubscriberWithoutSetupTest(new BlackboxTestStageTestRun() { - @Override - public void run(BlackboxTestStage stage) throws Throwable { - - { - final Subscriber sub = createSubscriber(); - boolean gotNPE = false; - try { - sub.onSubscribe(null); - } catch(final NullPointerException expected) { - gotNPE = true; - } - assertTrue(gotNPE, "onSubscribe(null) did not throw NullPointerException"); - } - - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - @Override @Test - public void required_spec213_blackbox_onNext_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable { - blackboxSubscriberWithoutSetupTest(new BlackboxTestStageTestRun() { - @Override - public void run(BlackboxTestStage stage) throws Throwable { - final Subscription subscription = new Subscription() { - @Override public void request(final long elements) {} - @Override public void cancel() {} - }; - - { - final Subscriber sub = createSubscriber(); - boolean gotNPE = false; - sub.onSubscribe(subscription); - try { - sub.onNext(null); - } catch(final NullPointerException expected) { - gotNPE = true; - } - assertTrue(gotNPE, "onNext(null) did not throw NullPointerException"); - } - - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - @Override @Test - public void required_spec213_blackbox_onError_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable { - blackboxSubscriberWithoutSetupTest(new BlackboxTestStageTestRun() { - @Override - public void run(BlackboxTestStage stage) throws Throwable { - final Subscription subscription = new Subscription() { - @Override public void request(final long elements) {} - @Override public void cancel() {} - }; - - { - final Subscriber sub = createSubscriber(); - boolean gotNPE = false; - sub.onSubscribe(subscription); - try { - sub.onError(null); - } catch(final NullPointerException expected) { - gotNPE = true; - } - assertTrue(gotNPE, "onError(null) did not throw NullPointerException"); - } - - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - ////////////////////// SUBSCRIPTION SPEC RULE VERIFICATION ////////////////// - - @Override @Test - public void untested_spec301_blackbox_mustNotBeCalledOutsideSubscriberContext() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - @Override @Test - public void untested_spec308_blackbox_requestMustRegisterGivenNumberElementsToBeProduced() throws Throwable { - notVerified(); // cannot be meaningfully tested as black box, or can it? - } - - @Override @Test - public void untested_spec310_blackbox_requestMaySynchronouslyCallOnNextOnSubscriber() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - @Override @Test - public void untested_spec311_blackbox_requestMaySynchronouslyCallOnCompleteOrOnError() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - @Override @Test - public void untested_spec314_blackbox_cancelMayCauseThePublisherToShutdownIfNoOtherSubscriptionExists() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - @Override @Test - public void untested_spec315_blackbox_cancelMustNotThrowExceptionAndMustSignalOnError() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - @Override @Test - public void untested_spec316_blackbox_requestMustNotThrowExceptionAndMustOnErrorTheSubscriber() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - /////////////////////// ADDITIONAL "COROLLARY" TESTS //////////////////////// - - /////////////////////// TEST INFRASTRUCTURE ///////////////////////////////// - - abstract class BlackboxTestStageTestRun { - public abstract void run(BlackboxTestStage stage) throws Throwable; - } - - public void blackboxSubscriberTest(BlackboxTestStageTestRun body) throws Throwable { - BlackboxTestStage stage = new BlackboxTestStage(env, true); - body.run(stage); - } - - public void blackboxSubscriberWithoutSetupTest(BlackboxTestStageTestRun body) throws Throwable { - BlackboxTestStage stage = new BlackboxTestStage(env, false); - body.run(stage); - } - - public class BlackboxTestStage extends ManualPublisher { - public Publisher pub; - public ManualSubscriber tees; // gives us access to an infinite stream of T values - - public T lastT = null; - private Optional> subProxy = Optional.empty(); - - public BlackboxTestStage(TestEnvironment env) throws InterruptedException { - this(env, true); - } - - public BlackboxTestStage(TestEnvironment env, boolean runDefaultInit) throws InterruptedException { - super(env); - if (runDefaultInit) { - pub = this.createHelperPublisher(Long.MAX_VALUE); - tees = env.newManualSubscriber(pub); - Subscriber sub = createSubscriber(); - subProxy = Optional.of(createBlackboxSubscriberProxy(env, sub)); - subscribe(subProxy.get()); - } - } - - public Subscriber sub() { - return subscriber.value(); - } - - /** - * Proxy for the {@link #sub()} {@code Subscriber}, providing certain assertions on methods being called on the Subscriber. - */ - public BlackboxSubscriberProxy subProxy() { - return subProxy.get(); - } - - public Publisher createHelperPublisher(long elements) { - return SubscriberBlackboxVerification.this.createHelperPublisher(elements); - } - - public BlackboxSubscriberProxy createBlackboxSubscriberProxy(TestEnvironment env, Subscriber sub) { - return new BlackboxSubscriberProxy(env, sub); - } - - public T signalNext() throws InterruptedException { - T element = nextT(); - sendNext(element); - return element; - } - - public T nextT() throws InterruptedException { - lastT = tees.requestNextElement(); - return lastT; - } - - } - - public void notVerified() { - throw new SkipException("Not verified using this TCK."); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/SubscriberWhiteboxVerification.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/SubscriberWhiteboxVerification.java deleted file mode 100644 index 5f07ae2ccba..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/SubscriberWhiteboxVerification.java +++ /dev/null @@ -1,850 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck; - -import org.reactivestreams.Publisher; -import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; -import org.reactivestreams.tck.TestEnvironment.*; -import org.reactivestreams.tck.flow.support.Optional; -import org.reactivestreams.tck.flow.support.SubscriberWhiteboxVerificationRules; -import org.reactivestreams.tck.flow.support.TestException; -import org.testng.SkipException; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import static org.testng.Assert.assertTrue; - -/** - * Provides whitebox style tests for verifying {@link org.reactivestreams.Subscriber} - * and {@link org.reactivestreams.Subscription} specification rules. - * - * @see org.reactivestreams.Subscriber - * @see org.reactivestreams.Subscription - */ -public abstract class SubscriberWhiteboxVerification extends WithHelperPublisher - implements SubscriberWhiteboxVerificationRules { - - private final TestEnvironment env; - - protected SubscriberWhiteboxVerification(TestEnvironment env) { - this.env = env; - } - - // USER API - - /** - * This is the main method you must implement in your test incarnation. - * It must create a new {@link org.reactivestreams.Subscriber} instance to be subjected to the testing logic. - * - * In order to be meaningfully testable your Subscriber must inform the given - * `WhiteboxSubscriberProbe` of the respective events having been received. - */ - public abstract Subscriber createSubscriber(WhiteboxSubscriberProbe probe); - - // ENV SETUP - - /** - * Executor service used by the default provided asynchronous Publisher. - * @see #createHelperPublisher(long) - */ - private ExecutorService publisherExecutor; - @BeforeClass public void startPublisherExecutorService() { publisherExecutor = Executors.newFixedThreadPool(4); } - @AfterClass public void shutdownPublisherExecutorService() { if (publisherExecutor != null) publisherExecutor.shutdown(); } - @Override public ExecutorService publisherExecutorService() { return publisherExecutor; } - - ////////////////////// TEST ENV CLEANUP ///////////////////////////////////// - - @BeforeMethod - public void setUp() throws Exception { - env.clearAsyncErrors(); - } - - ////////////////////// TEST SETUP VERIFICATION ////////////////////////////// - - @Test - public void required_exerciseWhiteboxHappyPath() throws Throwable { - subscriberTest(new TestStageTestRun() { - @Override - public void run(WhiteboxTestStage stage) throws InterruptedException { - stage.puppet().triggerRequest(1); - stage.puppet().triggerRequest(1); - - long receivedRequests = stage.expectRequest(); - - stage.signalNext(); - stage.probe.expectNext(stage.lastT); - - stage.puppet().triggerRequest(1); - if (receivedRequests == 1) { - stage.expectRequest(); - } - - stage.signalNext(); - stage.probe.expectNext(stage.lastT); - - stage.puppet().signalCancel(); - stage.expectCancelling(); - - stage.verifyNoAsyncErrors(); - } - }); - } - - ////////////////////// SPEC RULE VERIFICATION /////////////////////////////// - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.1 - @Override @Test - public void required_spec201_mustSignalDemandViaSubscriptionRequest() throws Throwable { - subscriberTest(new TestStageTestRun() { - @Override - public void run(WhiteboxTestStage stage) throws InterruptedException { - stage.puppet().triggerRequest(1); - stage.expectRequest(); - - stage.signalNext(); - } - }); - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.2 - @Override @Test - public void untested_spec202_shouldAsynchronouslyDispatch() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.3 - @Override @Test - public void required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnComplete() throws Throwable { - subscriberTestWithoutSetup(new TestStageTestRun() { - @Override - public void run(WhiteboxTestStage stage) throws Throwable { - final Subscription subs = new Subscription() { - @Override - public void request(long n) { - final Optional onCompleteStackTraceElement = env.findCallerMethodInStackTrace("onComplete"); - if (onCompleteStackTraceElement.isDefined()) { - final StackTraceElement stackElem = onCompleteStackTraceElement.get(); - env.flop(String.format("Subscription::request MUST NOT be called from Subscriber::onComplete (Rule 2.3)! (Caller: %s::%s line %d)", - stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber())); - } - } - - @Override - public void cancel() { - final Optional onCompleteStackElement = env.findCallerMethodInStackTrace("onComplete"); - if (onCompleteStackElement.isDefined()) { - final StackTraceElement stackElem = onCompleteStackElement.get(); - env.flop(String.format("Subscription::cancel MUST NOT be called from Subscriber::onComplete (Rule 2.3)! (Caller: %s::%s line %d)", - stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber())); - } - } - }; - - stage.probe = stage.createWhiteboxSubscriberProbe(env); - final Subscriber sub = createSubscriber(stage.probe); - - sub.onSubscribe(subs); - sub.onComplete(); - - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.3 - @Override @Test - public void required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnError() throws Throwable { - subscriberTestWithoutSetup(new TestStageTestRun() { - @Override - public void run(WhiteboxTestStage stage) throws Throwable { - final Subscription subs = new Subscription() { - @Override - public void request(long n) { - Throwable thr = new Throwable(); - for (StackTraceElement stackElem : thr.getStackTrace()) { - if (stackElem.getMethodName().equals("onError")) { - env.flop(String.format("Subscription::request MUST NOT be called from Subscriber::onError (Rule 2.3)! (Caller: %s::%s line %d)", - stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber())); - } - } - } - - @Override - public void cancel() { - Throwable thr = new Throwable(); - for (StackTraceElement stackElem : thr.getStackTrace()) { - if (stackElem.getMethodName().equals("onError")) { - env.flop(String.format("Subscription::cancel MUST NOT be called from Subscriber::onError (Rule 2.3)! (Caller: %s::%s line %d)", - stackElem.getClassName(), stackElem.getMethodName(), stackElem.getLineNumber())); - } - } - } - }; - - stage.probe = stage.createWhiteboxSubscriberProbe(env); - final Subscriber sub = createSubscriber(stage.probe); - - sub.onSubscribe(subs); - sub.onError(new TestException()); - - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.4 - @Override @Test - public void untested_spec204_mustConsiderTheSubscriptionAsCancelledInAfterRecievingOnCompleteOrOnError() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.5 - @Override @Test - public void required_spec205_mustCallSubscriptionCancelIfItAlreadyHasAnSubscriptionAndReceivesAnotherOnSubscribeSignal() throws Throwable { - subscriberTest(new TestStageTestRun() { - @Override - public void run(WhiteboxTestStage stage) throws Throwable { - // try to subscribe another time, if the subscriber calls `probe.registerOnSubscribe` the test will fail - final Latch secondSubscriptionCancelled = new Latch(env); - final Subscriber sub = stage.sub(); - final Subscription subscription = new Subscription() { - @Override - public void request(long elements) { - // ignore... - } - - @Override - public void cancel() { - secondSubscriptionCancelled.close(); - } - - @Override - public String toString() { - return "SecondSubscription(should get cancelled)"; - } - }; - sub.onSubscribe(subscription); - - secondSubscriptionCancelled.expectClose("Expected 2nd Subscription given to subscriber to be cancelled, but `Subscription.cancel()` was not called"); - env.verifyNoAsyncErrors(); - } - }); - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.6 - @Override @Test - public void untested_spec206_mustCallSubscriptionCancelIfItIsNoLongerValid() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.7 - @Override @Test - public void untested_spec207_mustEnsureAllCallsOnItsSubscriptionTakePlaceFromTheSameThreadOrTakeCareOfSynchronization() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - // the same thread part of the clause can be verified but that is not very useful, or is it? - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.8 - @Override @Test - public void required_spec208_mustBePreparedToReceiveOnNextSignalsAfterHavingCalledSubscriptionCancel() throws Throwable { - subscriberTest(new TestStageTestRun() { - @Override - public void run(WhiteboxTestStage stage) throws InterruptedException { - stage.puppet().triggerRequest(1); - stage.expectRequest(); - stage.puppet().signalCancel(); - stage.expectCancelling(); - stage.signalNext(); - - stage.puppet().triggerRequest(1); - stage.puppet().triggerRequest(1); - - stage.verifyNoAsyncErrors(); - } - }); - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.9 - @Override @Test - public void required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithPrecedingRequestCall() throws Throwable { - subscriberTest(new TestStageTestRun() { - @Override - public void run(WhiteboxTestStage stage) throws InterruptedException { - stage.puppet().triggerRequest(1); - stage.sendCompletion(); - stage.probe.expectCompletion(); - - stage.verifyNoAsyncErrors(); - } - }); - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.9 - @Override @Test - public void required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithoutPrecedingRequestCall() throws Throwable { - subscriberTest(new TestStageTestRun() { - @Override - public void run(WhiteboxTestStage stage) throws InterruptedException { - stage.sendCompletion(); - stage.probe.expectCompletion(); - - stage.verifyNoAsyncErrors(); - } - }); - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.10 - @Override @Test - public void required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithPrecedingRequestCall() throws Throwable { - subscriberTest(new TestStageTestRun() { - @Override - public void run(WhiteboxTestStage stage) throws InterruptedException { - stage.puppet().triggerRequest(1); - stage.puppet().triggerRequest(1); - - Exception ex = new TestException(); - stage.sendError(ex); - stage.probe.expectError(ex); - - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.10 - @Override @Test - public void required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithoutPrecedingRequestCall() throws Throwable { - subscriberTest(new TestStageTestRun() { - @Override - public void run(WhiteboxTestStage stage) throws InterruptedException { - Exception ex = new TestException(); - stage.sendError(ex); - stage.probe.expectError(ex); - - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.11 - @Override @Test - public void untested_spec211_mustMakeSureThatAllCallsOnItsMethodsHappenBeforeTheProcessingOfTheRespectiveEvents() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.12 - @Override @Test - public void untested_spec212_mustNotCallOnSubscribeMoreThanOnceBasedOnObjectEquality_specViolation() throws Throwable { - notVerified(); // cannot be meaningfully tested, or can it? - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.13 - @Override @Test - public void untested_spec213_failingOnSignalInvocation() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.13 - @Override @Test - public void required_spec213_onSubscribe_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable { - subscriberTest(new TestStageTestRun() { - @Override - public void run(WhiteboxTestStage stage) throws Throwable { - - final Subscriber sub = stage.sub(); - boolean gotNPE = false; - try { - sub.onSubscribe(null); - } catch (final NullPointerException expected) { - gotNPE = true; - } - - assertTrue(gotNPE, "onSubscribe(null) did not throw NullPointerException"); - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.13 - @Override @Test - public void required_spec213_onNext_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable { - subscriberTest(new TestStageTestRun() { - @Override - public void run(WhiteboxTestStage stage) throws Throwable { - - final Subscriber sub = stage.sub(); - boolean gotNPE = false; - try { - sub.onNext(null); - } catch (final NullPointerException expected) { - gotNPE = true; - } - - assertTrue(gotNPE, "onNext(null) did not throw NullPointerException"); - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#2.13 - @Override @Test - public void required_spec213_onError_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable { - subscriberTest(new TestStageTestRun() { - @Override - public void run(WhiteboxTestStage stage) throws Throwable { - - final Subscriber sub = stage.sub(); - boolean gotNPE = false; - try { - sub.onError(null); - } catch (final NullPointerException expected) { - gotNPE = true; - } finally { - assertTrue(gotNPE, "onError(null) did not throw NullPointerException"); - } - - env.verifyNoAsyncErrorsNoDelay(); - } - }); - } - - - ////////////////////// SUBSCRIPTION SPEC RULE VERIFICATION ////////////////// - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#3.1 - @Override @Test - public void untested_spec301_mustNotBeCalledOutsideSubscriberContext() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#3.8 - @Override @Test - public void required_spec308_requestMustRegisterGivenNumberElementsToBeProduced() throws Throwable { - subscriberTest(new TestStageTestRun() { - @Override - public void run(WhiteboxTestStage stage) throws InterruptedException { - stage.puppet().triggerRequest(2); - long requestedElements = stage.expectRequest(); - stage.probe.expectNext(stage.signalNext()); - // Some subscribers may only request one element at a time. - if (requestedElements < 2) { - stage.expectRequest(); - } - stage.probe.expectNext(stage.signalNext()); - - stage.probe.expectNone(); - stage.puppet().triggerRequest(3); - - stage.verifyNoAsyncErrors(); - } - }); - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#3.10 - @Override @Test - public void untested_spec310_requestMaySynchronouslyCallOnNextOnSubscriber() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#3.11 - @Override @Test - public void untested_spec311_requestMaySynchronouslyCallOnCompleteOrOnError() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#3.14 - @Override @Test - public void untested_spec314_cancelMayCauseThePublisherToShutdownIfNoOtherSubscriptionExists() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#3.15 - @Override @Test - public void untested_spec315_cancelMustNotThrowExceptionAndMustSignalOnError() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - // Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#3.16 - @Override @Test - public void untested_spec316_requestMustNotThrowExceptionAndMustOnErrorTheSubscriber() throws Exception { - notVerified(); // cannot be meaningfully tested, or can it? - } - - /////////////////////// ADDITIONAL "COROLLARY" TESTS //////////////////////// - - /////////////////////// TEST INFRASTRUCTURE ///////////////////////////////// - - abstract class TestStageTestRun { - public abstract void run(WhiteboxTestStage stage) throws Throwable; - } - - /** - * Prepares subscriber and publisher pair (by subscribing the first to the latter), - * and then hands over the tests {@link WhiteboxTestStage} over to the test. - * - * The test stage is, like in a puppet show, used to orchestrate what each participant should do. - * Since this is a whitebox test, this allows the stage to completely control when and how to signal / expect signals. - */ - public void subscriberTest(TestStageTestRun body) throws Throwable { - WhiteboxTestStage stage = new WhiteboxTestStage(env, true); - body.run(stage); - } - - /** - * Provides a {@link WhiteboxTestStage} without performing any additional setup, - * like the {@link #subscriberTest(SubscriberWhiteboxVerification.TestStageTestRun)} would. - * - * Use this method to write tests in which you need full control over when and how the initial {@code subscribe} is signalled. - */ - public void subscriberTestWithoutSetup(TestStageTestRun body) throws Throwable { - WhiteboxTestStage stage = new WhiteboxTestStage(env, false); - body.run(stage); - } - - /** - * Test for feature that MAY be implemented. This test will be marked as SKIPPED if it fails. - */ - public void optionalSubscriberTestWithoutSetup(TestStageTestRun body) throws Throwable { - try { - subscriberTestWithoutSetup(body); - } catch (Exception ex) { - notVerified("Skipped because tested publisher does NOT implement this OPTIONAL requirement."); - } - } - - public class WhiteboxTestStage extends ManualPublisher { - public Publisher pub; - public ManualSubscriber tees; // gives us access to a stream T values - public WhiteboxSubscriberProbe probe; - - public T lastT = null; - - public WhiteboxTestStage(TestEnvironment env) throws InterruptedException { - this(env, true); - } - - public WhiteboxTestStage(TestEnvironment env, boolean runDefaultInit) throws InterruptedException { - super(env); - if (runDefaultInit) { - pub = this.createHelperPublisher(Long.MAX_VALUE); - tees = env.newManualSubscriber(pub); - probe = new WhiteboxSubscriberProbe(env, subscriber); - subscribe(createSubscriber(probe)); - probe.puppet.expectCompletion(env.defaultTimeoutMillis(), String.format("Subscriber %s did not `registerOnSubscribe`", sub())); - env.verifyNoAsyncErrorsNoDelay(); - } - } - - public Subscriber sub() { - return subscriber.value(); - } - - public SubscriberPuppet puppet() { - return probe.puppet(); - } - - public WhiteboxSubscriberProbe probe() { - return probe; - } - - public Publisher createHelperPublisher(long elements) { - return SubscriberWhiteboxVerification.this.createHelperPublisher(elements); - } - - public WhiteboxSubscriberProbe createWhiteboxSubscriberProbe(TestEnvironment env) { - return new WhiteboxSubscriberProbe(env, subscriber); - } - - public T signalNext() throws InterruptedException { - return signalNext(nextT()); - } - - private T signalNext(T element) throws InterruptedException { - sendNext(element); - return element; - } - - public T nextT() throws InterruptedException { - lastT = tees.requestNextElement(); - return lastT; - } - - public void verifyNoAsyncErrors() { - env.verifyNoAsyncErrors(); - } - } - - /** - * This class is intented to be used as {@code Subscriber} decorator and should be used in {@code pub.subscriber(...)} calls, - * in order to allow intercepting calls on the underlying {@code Subscriber}. - * This delegation allows the proxy to implement {@link BlackboxProbe} assertions. - */ - public static class BlackboxSubscriberProxy extends BlackboxProbe implements Subscriber { - - public BlackboxSubscriberProxy(TestEnvironment env, Subscriber subscriber) { - super(env, Promise.>completed(env, subscriber)); - } - - @Override - public void onSubscribe(Subscription s) { - sub().onSubscribe(s); - } - - @Override - public void onNext(T t) { - registerOnNext(t); - sub().onNext(t); - } - - @Override - public void onError(Throwable cause) { - registerOnError(cause); - sub().onError(cause); - } - - @Override - public void onComplete() { - registerOnComplete(); - sub().onComplete(); - } - } - - public static class BlackboxProbe implements SubscriberProbe { - protected final TestEnvironment env; - protected final Promise> subscriber; - - protected final Receptacle elements; - protected final Promise error; - - public BlackboxProbe(TestEnvironment env, Promise> subscriber) { - this.env = env; - this.subscriber = subscriber; - elements = new Receptacle(env); - error = new Promise(env); - } - - @Override - public void registerOnNext(T element) { - elements.add(element); - } - - @Override - public void registerOnComplete() { - try { - elements.complete(); - } catch (IllegalStateException ex) { - // "Queue full", onComplete was already called - env.flop("subscriber::onComplete was called a second time, which is illegal according to Rule 1.7"); - } - } - - @Override - public void registerOnError(Throwable cause) { - try { - error.complete(cause); - } catch (IllegalStateException ex) { - // "Queue full", onError was already called - env.flop("subscriber::onError was called a second time, which is illegal according to Rule 1.7"); - } - } - - public T expectNext() throws InterruptedException { - return elements.next(env.defaultTimeoutMillis(), String.format("Subscriber %s did not call `registerOnNext(_)`", sub())); - } - - public void expectNext(T expected) throws InterruptedException { - expectNext(expected, env.defaultTimeoutMillis()); - } - - public void expectNext(T expected, long timeoutMillis) throws InterruptedException { - T received = elements.next(timeoutMillis, String.format("Subscriber %s did not call `registerOnNext(%s)`", sub(), expected)); - if (!received.equals(expected)) { - env.flop(String.format("Subscriber %s called `registerOnNext(%s)` rather than `registerOnNext(%s)`", sub(), received, expected)); - } - } - - public Subscriber sub() { - return subscriber.value(); - } - - public void expectCompletion() throws InterruptedException { - expectCompletion(env.defaultTimeoutMillis()); - } - - public void expectCompletion(long timeoutMillis) throws InterruptedException { - expectCompletion(timeoutMillis, String.format("Subscriber %s did not call `registerOnComplete()`", sub())); - } - - public void expectCompletion(long timeoutMillis, String msg) throws InterruptedException { - elements.expectCompletion(timeoutMillis, msg); - } - - @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - public void expectErrorWithMessage(Class expected, String requiredMessagePart) throws InterruptedException { - final E err = expectError(expected); - String message = err.getMessage(); - assertTrue(message.contains(requiredMessagePart), - String.format("Got expected exception %s but missing message [%s], was: %s", err.getClass(), requiredMessagePart, expected)); - } - - public E expectError(Class expected) throws InterruptedException { - return expectError(expected, env.defaultTimeoutMillis()); - } - - @SuppressWarnings({"unchecked", "ThrowableResultOfMethodCallIgnored"}) - public E expectError(Class expected, long timeoutMillis) throws InterruptedException { - error.expectCompletion(timeoutMillis, String.format("Subscriber %s did not call `registerOnError(%s)`", sub(), expected)); - if (error.value() == null) { - return env.flopAndFail(String.format("Subscriber %s did not call `registerOnError(%s)`", sub(), expected)); - } else if (expected.isInstance(error.value())) { - return (E) error.value(); - } else { - return env.flopAndFail(String.format("Subscriber %s called `registerOnError(%s)` rather than `registerOnError(%s)`", sub(), error.value(), expected)); - } - } - - public void expectError(Throwable expected) throws InterruptedException { - expectError(expected, env.defaultTimeoutMillis()); - } - - @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - public void expectError(Throwable expected, long timeoutMillis) throws InterruptedException { - error.expectCompletion(timeoutMillis, String.format("Subscriber %s did not call `registerOnError(%s)`", sub(), expected)); - if (error.value() != expected) { - env.flop(String.format("Subscriber %s called `registerOnError(%s)` rather than `registerOnError(%s)`", sub(), error.value(), expected)); - } - } - - public void expectNone() throws InterruptedException { - expectNone(env.defaultNoSignalsTimeoutMillis()); - } - - public void expectNone(long withinMillis) throws InterruptedException { - elements.expectNone(withinMillis, "Expected nothing"); - } - - } - - public static class WhiteboxSubscriberProbe extends BlackboxProbe implements SubscriberPuppeteer { - protected Promise puppet; - - public WhiteboxSubscriberProbe(TestEnvironment env, Promise> subscriber) { - super(env, subscriber); - puppet = new Promise(env); - } - - private SubscriberPuppet puppet() { - return puppet.value(); - } - - @Override - public void registerOnSubscribe(SubscriberPuppet p) { - if (!puppet.isCompleted()) { - puppet.complete(p); - } - } - - } - - public interface SubscriberPuppeteer { - - /** - * Must be called by the test subscriber when it has successfully registered a subscription - * inside the `onSubscribe` method. - */ - void registerOnSubscribe(SubscriberPuppet puppet); - } - - public interface SubscriberProbe { - - /** - * Must be called by the test subscriber when it has received an`onNext` event. - */ - void registerOnNext(T element); - - /** - * Must be called by the test subscriber when it has received an `onComplete` event. - */ - void registerOnComplete(); - - /** - * Must be called by the test subscriber when it has received an `onError` event. - */ - void registerOnError(Throwable cause); - - } - - /** - * Implement this puppet in your Whitebox style tests. - * The test suite will invoke the specific trigger/signal methods requesting you to execute the specific action. - * Since this is a whitebox style test, you're allowed and expected to use knowladge about your implementation to - * make implement these calls. - */ - public interface SubscriberPuppet { - - /** - * Ensure that at least {@code elements} are eventually requested by your {@link Subscriber}, if it hasn't already - * requested that many elements. - *

- * This does not necessarily have to correlate 1:1 with a {@code Subscription.request(elements)} call, but the sum - * of the elements requested by your {@code Subscriber} must eventually be at least the the sum of the elements - * triggered to be requested by all the invocations of this method. - *

- * Additionally, subscribers are permitted to delay requesting elements until previous requests for elements have - * been fulfilled. For example, a subscriber that only requests one element at a time may fulfill the request made - * by this method by requesting one element {@code elements} times, waiting for each element to arrive before the - * next request is made. - *

- * Before sending any element to the subscriber, the TCK must wait for the subscriber to request that element, and - * must be prepared for the subscriber to only request one element at a time, it is not enough for the TCK to - * simply invoke this method before sending elements. - *

- * An invocation of {@link #signalCancel()} may be coalesced into any elements that have not yet been requested, - * such that only a cancel signal is emitted. - */ - void triggerRequest(long elements); - - /** - * Trigger {@code cancel()} on your {@link Subscriber}. - *

- * An invocation of this method may be coalesced into any outstanding requests, as requested by - *{@link #triggerRequest(long)}, such that only a cancel signal is emitted. - */ - void signalCancel(); - } - - public void notVerified() { - throw new SkipException("Not verified using this TCK."); - } - - public void notVerified(String msg) { - throw new SkipException(msg); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/TestEnvironment.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/TestEnvironment.java deleted file mode 100644 index e32b58cbd13..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/TestEnvironment.java +++ /dev/null @@ -1,1168 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck; - -import org.reactivestreams.Publisher; -import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; -import org.reactivestreams.tck.flow.support.Optional; -import org.reactivestreams.tck.flow.support.SubscriberBufferOverflowException; - -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; - -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.NANOSECONDS; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.fail; - -public class TestEnvironment { - public static final int TEST_BUFFER_SIZE = 16; - - private static final String DEFAULT_TIMEOUT_MILLIS_ENV = "DEFAULT_TIMEOUT_MILLIS"; - private static final long DEFAULT_TIMEOUT_MILLIS = 100; - - private static final String DEFAULT_NO_SIGNALS_TIMEOUT_MILLIS_ENV = "DEFAULT_NO_SIGNALS_TIMEOUT_MILLIS"; - private static final String DEFAULT_POLL_TIMEOUT_MILLIS_ENV = "DEFAULT_POLL_TIMEOUT_MILLIS_ENV"; - - private final long defaultTimeoutMillis; - private final long defaultPollTimeoutMillis; - private final long defaultNoSignalsTimeoutMillis; - private final boolean printlnDebug; - - private CopyOnWriteArrayList asyncErrors = new CopyOnWriteArrayList(); - - /** - * Tests must specify the timeout for expected outcome of asynchronous - * interactions. Longer timeout does not invalidate the correctness of - * the implementation, but can in some cases result in longer time to - * run the tests. - * @param defaultTimeoutMillis default timeout to be used in all expect* methods - * @param defaultNoSignalsTimeoutMillis default timeout to be used when no further signals are expected anymore - * @param defaultPollTimeoutMillis default amount of time to poll for events if {@code defaultTimeoutMillis} isn't - * preempted by an asynchronous event. - * @param printlnDebug if true, signals such as OnNext / Request / OnComplete etc will be printed to standard output, - */ - public TestEnvironment(long defaultTimeoutMillis, long defaultNoSignalsTimeoutMillis, long defaultPollTimeoutMillis, - boolean printlnDebug) { - this.defaultTimeoutMillis = defaultTimeoutMillis; - this.defaultPollTimeoutMillis = defaultPollTimeoutMillis; - this.defaultNoSignalsTimeoutMillis = defaultNoSignalsTimeoutMillis; - this.printlnDebug = printlnDebug; - } - - /** - * Tests must specify the timeout for expected outcome of asynchronous - * interactions. Longer timeout does not invalidate the correctness of - * the implementation, but can in some cases result in longer time to - * run the tests. - * @param defaultTimeoutMillis default timeout to be used in all expect* methods - * @param defaultNoSignalsTimeoutMillis default timeout to be used when no further signals are expected anymore - * @param printlnDebug if true, signals such as OnNext / Request / OnComplete etc will be printed to standard output, - */ - public TestEnvironment(long defaultTimeoutMillis, long defaultNoSignalsTimeoutMillis, boolean printlnDebug) { - this(defaultTimeoutMillis, defaultNoSignalsTimeoutMillis, defaultTimeoutMillis, printlnDebug); - } - - /** - * Tests must specify the timeout for expected outcome of asynchronous - * interactions. Longer timeout does not invalidate the correctness of - * the implementation, but can in some cases result in longer time to - * run the tests. - * - * @param defaultTimeoutMillis default timeout to be used in all expect* methods - * @param defaultNoSignalsTimeoutMillis default timeout to be used when no further signals are expected anymore - * @param defaultPollTimeoutMillis default amount of time to poll for events if {@code defaultTimeoutMillis} isn't - * preempted by an asynchronous event. - */ - public TestEnvironment(long defaultTimeoutMillis, long defaultNoSignalsTimeoutMillis, long defaultPollTimeoutMillis) { - this(defaultTimeoutMillis, defaultNoSignalsTimeoutMillis, defaultPollTimeoutMillis, false); - } - - /** - * Tests must specify the timeout for expected outcome of asynchronous - * interactions. Longer timeout does not invalidate the correctness of - * the implementation, but can in some cases result in longer time to - * run the tests. - * - * @param defaultTimeoutMillis default timeout to be used in all expect* methods - * @param defaultNoSignalsTimeoutMillis default timeout to be used when no further signals are expected anymore - */ - public TestEnvironment(long defaultTimeoutMillis, long defaultNoSignalsTimeoutMillis) { - this(defaultTimeoutMillis, defaultTimeoutMillis, defaultNoSignalsTimeoutMillis); - } - - /** - * Tests must specify the timeout for expected outcome of asynchronous - * interactions. Longer timeout does not invalidate the correctness of - * the implementation, but can in some cases result in longer time to - * run the tests. - * - * @param defaultTimeoutMillis default timeout to be used in all expect* methods - */ - public TestEnvironment(long defaultTimeoutMillis) { - this(defaultTimeoutMillis, defaultTimeoutMillis, defaultTimeoutMillis); - } - - /** - * Tests must specify the timeout for expected outcome of asynchronous - * interactions. Longer timeout does not invalidate the correctness of - * the implementation, but can in some cases result in longer time to - * run the tests. - * - * The default timeout for all expect* methods will be obtained by either the env variable {@code DEFAULT_TIMEOUT_MILLIS} - * or the default value ({@link TestEnvironment#DEFAULT_TIMEOUT_MILLIS}) will be used. - * - * @param printlnDebug if true, signals such as OnNext / Request / OnComplete etc will be printed to standard output, - * often helpful to pinpoint simple race conditions etc. - */ - public TestEnvironment(boolean printlnDebug) { - this(envDefaultTimeoutMillis(), envDefaultNoSignalsTimeoutMillis(), envDefaultPollTimeoutMillis(), printlnDebug); - } - - /** - * Tests must specify the timeout for expected outcome of asynchronous - * interactions. Longer timeout does not invalidate the correctness of - * the implementation, but can in some cases result in longer time to - * run the tests. - * - * The default timeout for all expect* methods will be obtained by either the env variable {@code DEFAULT_TIMEOUT_MILLIS} - * or the default value ({@link TestEnvironment#DEFAULT_TIMEOUT_MILLIS}) will be used. - */ - public TestEnvironment() { - this(envDefaultTimeoutMillis(), envDefaultNoSignalsTimeoutMillis()); - } - - /** This timeout is used when waiting for a signal to arrive. */ - public long defaultTimeoutMillis() { - return defaultTimeoutMillis; - } - - /** - * This timeout is used when asserting that no further signals are emitted. - * Note that this timeout default - */ - public long defaultNoSignalsTimeoutMillis() { - return defaultNoSignalsTimeoutMillis; - } - - /** - * The default amount of time to poll for events if {@code defaultTimeoutMillis} isn't preempted by an asynchronous - * event. - */ - public long defaultPollTimeoutMillis() { - return defaultPollTimeoutMillis; - } - - /** - * Tries to parse the env variable {@code DEFAULT_TIMEOUT_MILLIS} as long and returns the value if present OR its default value. - * - * @throws java.lang.IllegalArgumentException when unable to parse the env variable - */ - public static long envDefaultTimeoutMillis() { - final String envMillis = System.getenv(DEFAULT_TIMEOUT_MILLIS_ENV); - if (envMillis == null) return DEFAULT_TIMEOUT_MILLIS; - else try { - return Long.parseLong(envMillis); - } catch (NumberFormatException ex) { - throw new IllegalArgumentException(String.format("Unable to parse %s env value [%s] as long!", DEFAULT_TIMEOUT_MILLIS_ENV, envMillis), ex); - } - } - - /** - * Tries to parse the env variable {@code DEFAULT_NO_SIGNALS_TIMEOUT_MILLIS} as long and returns the value if present OR its default value. - * - * @throws java.lang.IllegalArgumentException when unable to parse the env variable - */ - public static long envDefaultNoSignalsTimeoutMillis() { - final String envMillis = System.getenv(DEFAULT_NO_SIGNALS_TIMEOUT_MILLIS_ENV); - if (envMillis == null) return envDefaultTimeoutMillis(); - else try { - return Long.parseLong(envMillis); - } catch (NumberFormatException ex) { - throw new IllegalArgumentException(String.format("Unable to parse %s env value [%s] as long!", DEFAULT_NO_SIGNALS_TIMEOUT_MILLIS_ENV, envMillis), ex); - } - } - - /** - * Tries to parse the env variable {@code DEFAULT_POLL_TIMEOUT_MILLIS_ENV} as long and returns the value if present OR its default value. - * - * @throws java.lang.IllegalArgumentException when unable to parse the env variable - */ - public static long envDefaultPollTimeoutMillis() { - final String envMillis = System.getenv(DEFAULT_POLL_TIMEOUT_MILLIS_ENV); - if (envMillis == null) return envDefaultTimeoutMillis(); - else try { - return Long.parseLong(envMillis); - } catch (NumberFormatException ex) { - throw new IllegalArgumentException(String.format("Unable to parse %s env value [%s] as long!", DEFAULT_POLL_TIMEOUT_MILLIS_ENV, envMillis), ex); - } - } - - /** - * To flop means to "fail asynchronously", either by onErroring or by failing some TCK check triggered asynchronously. - * This method does *NOT* fail the test - it's up to inspections of the error to fail the test if required. - * - * Use {@code env.verifyNoAsyncErrorsNoDelay()} at the end of your TCK tests to verify there no flops called during it's execution. - * To check investigate asyncErrors more closely you can use {@code expectError} methods or collect the error directly - * from the environment using {@code env.dropAsyncError()}. - * - * To clear asyncErrors you can call {@link org.reactivestreams.tck.TestEnvironment#clearAsyncErrors()} - */ - public void flop(String msg) { - try { - fail(msg); - } catch (Throwable t) { - asyncErrors.add(t); - } - } - - /** - * To flop means to "fail asynchronously", either by onErroring or by failing some TCK check triggered asynchronously. - * This method does *NOT* fail the test - it's up to inspections of the error to fail the test if required. - * - * This overload keeps the passed in throwable as the asyncError, instead of creating an AssertionError for this. - * - * Use {@code env.verifyNoAsyncErrorsNoDelay()} at the end of your TCK tests to verify there no flops called during it's execution. - * To check investigate asyncErrors more closely you can use {@code expectError} methods or collect the error directly - * from the environment using {@code env.dropAsyncError()}. - * - * To clear asyncErrors you can call {@link org.reactivestreams.tck.TestEnvironment#clearAsyncErrors()} - */ - public void flop(Throwable thr, String msg) { - try { - fail(msg, thr); - } catch (Throwable t) { - asyncErrors.add(thr); - } - } - - /** - * To flop means to "fail asynchronously", either by onErroring or by failing some TCK check triggered asynchronously. - * This method does *NOT* fail the test - it's up to inspections of the error to fail the test if required. - * - * This overload keeps the passed in throwable as the asyncError, instead of creating an AssertionError for this. - * - * Use {@code env.verifyNoAsyncErrorsNoDelay()} at the end of your TCK tests to verify there no flops called during it's execution. - * To check investigate asyncErrors more closely you can use {@code expectError} methods or collect the error directly - * from the environment using {@code env.dropAsyncError()}. - * - * To clear asyncErrors you can call {@link org.reactivestreams.tck.TestEnvironment#clearAsyncErrors()} - */ - public void flop(Throwable thr) { - try { - fail(thr.getMessage(), thr); - } catch (Throwable t) { - asyncErrors.add(thr); - } - } - - /** - * To flop means to "fail asynchronously", either by onErroring or by failing some TCK check triggered asynchronously. - * - * This method DOES fail the test right away (it tries to, by throwing an AssertionException), - * in such it is different from {@link org.reactivestreams.tck.TestEnvironment#flop} which only records the error. - * - * Use {@code env.verifyNoAsyncErrorsNoDelay()} at the end of your TCK tests to verify there no flops called during it's execution. - * To check investigate asyncErrors more closely you can use {@code expectError} methods or collect the error directly - * from the environment using {@code env.dropAsyncError()}. - * - * To clear asyncErrors you can call {@link org.reactivestreams.tck.TestEnvironment#clearAsyncErrors()} - */ - public T flopAndFail(String msg) { - try { - fail(msg); - } catch (Throwable t) { - asyncErrors.add(t); - fail(msg, t); - } - return null; // unreachable, the previous block will always exit by throwing - } - - - - public void subscribe(Publisher pub, TestSubscriber sub) throws InterruptedException { - subscribe(pub, sub, defaultTimeoutMillis); - } - - public void subscribe(Publisher pub, TestSubscriber sub, long timeoutMillis) throws InterruptedException { - pub.subscribe(sub); - sub.subscription.expectCompletion(timeoutMillis, String.format("Could not subscribe %s to Publisher %s", sub, pub)); - verifyNoAsyncErrorsNoDelay(); - } - - public ManualSubscriber newBlackholeSubscriber(Publisher pub) throws InterruptedException { - ManualSubscriberWithSubscriptionSupport sub = new BlackholeSubscriberWithSubscriptionSupport(this); - subscribe(pub, sub, defaultTimeoutMillis()); - return sub; - } - - public ManualSubscriber newManualSubscriber(Publisher pub) throws InterruptedException { - return newManualSubscriber(pub, defaultTimeoutMillis()); - } - - public ManualSubscriber newManualSubscriber(Publisher pub, long timeoutMillis) throws InterruptedException { - ManualSubscriberWithSubscriptionSupport sub = new ManualSubscriberWithSubscriptionSupport(this); - subscribe(pub, sub, timeoutMillis); - return sub; - } - - public void clearAsyncErrors() { - asyncErrors.clear(); - } - - public Throwable dropAsyncError() { - try { - return asyncErrors.remove(0); - } catch (IndexOutOfBoundsException ex) { - return null; - } - } - - /** - * Waits for {@link TestEnvironment#defaultNoSignalsTimeoutMillis()} and then verifies that no asynchronous errors - * were signalled pior to, or during that time (by calling {@code flop()}). - */ - public void verifyNoAsyncErrors() { - verifyNoAsyncErrors(defaultNoSignalsTimeoutMillis()); - } - - /** - * This version of {@code verifyNoAsyncErrors} should be used when errors still could be signalled - * asynchronously during {@link TestEnvironment#defaultTimeoutMillis()} time. - *

- * It will immediatly check if any async errors were signaled (using {@link TestEnvironment#flop(String)}, - * and if no errors encountered wait for another default timeout as the errors may yet be signalled. - * The initial check is performed in order to fail-fast in case of an already failed test. - */ - public void verifyNoAsyncErrors(long delay) { - try { - verifyNoAsyncErrorsNoDelay(); - - Thread.sleep(delay); - verifyNoAsyncErrorsNoDelay(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - - /** - * Verifies that no asynchronous errors were signalled pior to calling this method (by calling {@code flop()}). - * This version of verifyNoAsyncError does not wait before checking for asynchronous errors, and is to be used - * for example in tight loops etc. - */ - public void verifyNoAsyncErrorsNoDelay() { - for (Throwable e : asyncErrors) { - if (e instanceof AssertionError) { - throw (AssertionError) e; - } else { - fail(String.format("Async error during test execution: %s", e.getMessage()), e); - } - } - } - - /** If {@code TestEnvironment#printlnDebug} is true, print debug message to std out. */ - public void debug(String msg) { - if (debugEnabled()) { - System.out.printf("[TCK-DEBUG] %s%n", msg); - } - } - - public final boolean debugEnabled() { - return printlnDebug; - } - - /** - * Looks for given {@code method} method in stack trace. - * Can be used to answer questions like "was this method called from onComplete?". - * - * @return the caller's StackTraceElement at which he the looked for method was found in the call stack, EMPTY otherwise - */ - public Optional findCallerMethodInStackTrace(String method) { - final Throwable thr = new Throwable(); // gets the stacktrace - - for (StackTraceElement stackElement : thr.getStackTrace()) { - if (stackElement.getMethodName().equals(method)) { - return Optional.of(stackElement); - } - } - return Optional.empty(); - } - - // ---- classes ---- - - /** - * {@link Subscriber} implementation which can be steered by test code and asserted on. - */ - public static class ManualSubscriber extends TestSubscriber { - Receptacle received; - - public ManualSubscriber(TestEnvironment env) { - super(env); - received = new Receptacle(this.env); - } - - @Override - public void onNext(T element) { - try { - received.add(element); - } catch (IllegalStateException ex) { - // error message refinement - throw new SubscriberBufferOverflowException( - String.format("Received more than bufferSize (%d) onNext signals. " + - "The Publisher probably emited more signals than expected!", - received.QUEUE_SIZE), ex); - } - } - - @Override - public void onComplete() { - received.complete(); - } - - public void request(long elements) { - subscription.value().request(elements); - } - - public T requestNextElement() throws InterruptedException { - return requestNextElement(env.defaultTimeoutMillis()); - } - - public T requestNextElement(long timeoutMillis) throws InterruptedException { - return requestNextElement(timeoutMillis, "Did not receive expected element"); - } - - public T requestNextElement(String errorMsg) throws InterruptedException { - return requestNextElement(env.defaultTimeoutMillis(), errorMsg); - } - - public T requestNextElement(long timeoutMillis, String errorMsg) throws InterruptedException { - request(1); - return nextElement(timeoutMillis, errorMsg); - } - - public Optional requestNextElementOrEndOfStream() throws InterruptedException { - return requestNextElementOrEndOfStream(env.defaultTimeoutMillis(), "Did not receive expected stream completion"); - } - - public Optional requestNextElementOrEndOfStream(String errorMsg) throws InterruptedException { - return requestNextElementOrEndOfStream(env.defaultTimeoutMillis(), errorMsg); - } - - public Optional requestNextElementOrEndOfStream(long timeoutMillis) throws InterruptedException { - return requestNextElementOrEndOfStream(timeoutMillis, "Did not receive expected stream completion"); - } - - public Optional requestNextElementOrEndOfStream(long timeoutMillis, String errorMsg) throws InterruptedException { - request(1); - return nextElementOrEndOfStream(timeoutMillis, errorMsg); - } - - public void requestEndOfStream() throws InterruptedException { - requestEndOfStream(env.defaultTimeoutMillis(), "Did not receive expected stream completion"); - } - - public void requestEndOfStream(long timeoutMillis) throws InterruptedException { - requestEndOfStream(timeoutMillis, "Did not receive expected stream completion"); - } - - public void requestEndOfStream(String errorMsg) throws InterruptedException { - requestEndOfStream(env.defaultTimeoutMillis(), errorMsg); - } - - public void requestEndOfStream(long timeoutMillis, String errorMsg) throws InterruptedException { - request(1); - expectCompletion(timeoutMillis, errorMsg); - } - - public List requestNextElements(long elements) throws InterruptedException { - request(elements); - return nextElements(elements, env.defaultTimeoutMillis()); - } - - public List requestNextElements(long elements, long timeoutMillis) throws InterruptedException { - request(elements); - return nextElements(elements, timeoutMillis, String.format("Did not receive %d expected elements", elements)); - } - - public List requestNextElements(long elements, long timeoutMillis, String errorMsg) throws InterruptedException { - request(elements); - return nextElements(elements, timeoutMillis, errorMsg); - } - - public T nextElement() throws InterruptedException { - return nextElement(env.defaultTimeoutMillis()); - } - - public T nextElement(long timeoutMillis) throws InterruptedException { - return nextElement(timeoutMillis, "Did not receive expected element"); - } - - public T nextElement(String errorMsg) throws InterruptedException { - return nextElement(env.defaultTimeoutMillis(), errorMsg); - } - - public T nextElement(long timeoutMillis, String errorMsg) throws InterruptedException { - return received.next(timeoutMillis, errorMsg); - } - - public Optional nextElementOrEndOfStream() throws InterruptedException { - return nextElementOrEndOfStream(env.defaultTimeoutMillis(), "Did not receive expected stream completion"); - } - - public Optional nextElementOrEndOfStream(long timeoutMillis) throws InterruptedException { - return nextElementOrEndOfStream(timeoutMillis, "Did not receive expected stream completion"); - } - - public Optional nextElementOrEndOfStream(long timeoutMillis, String errorMsg) throws InterruptedException { - return received.nextOrEndOfStream(timeoutMillis, errorMsg); - } - - public List nextElements(long elements) throws InterruptedException { - return nextElements(elements, env.defaultTimeoutMillis(), "Did not receive expected element or completion"); - } - - public List nextElements(long elements, String errorMsg) throws InterruptedException { - return nextElements(elements, env.defaultTimeoutMillis(), errorMsg); - } - - public List nextElements(long elements, long timeoutMillis) throws InterruptedException { - return nextElements(elements, timeoutMillis, "Did not receive expected element or completion"); - } - - public List nextElements(long elements, long timeoutMillis, String errorMsg) throws InterruptedException { - return received.nextN(elements, timeoutMillis, errorMsg); - } - - public void expectNext(T expected) throws InterruptedException { - expectNext(expected, env.defaultTimeoutMillis()); - } - - public void expectNext(T expected, long timeoutMillis) throws InterruptedException { - T received = nextElement(timeoutMillis, "Did not receive expected element on downstream"); - if (!received.equals(expected)) { - env.flop(String.format("Expected element %s on downstream but received %s", expected, received)); - } - } - - public void expectCompletion() throws InterruptedException { - expectCompletion(env.defaultTimeoutMillis(), "Did not receive expected stream completion"); - } - - public void expectCompletion(long timeoutMillis) throws InterruptedException { - expectCompletion(timeoutMillis, "Did not receive expected stream completion"); - } - - public void expectCompletion(String errorMsg) throws InterruptedException { - expectCompletion(env.defaultTimeoutMillis(), errorMsg); - } - - public void expectCompletion(long timeoutMillis, String errorMsg) throws InterruptedException { - received.expectCompletion(timeoutMillis, errorMsg); - } - - public void expectErrorWithMessage(Class expected, String requiredMessagePart) throws Exception { - expectErrorWithMessage(expected, Collections.singletonList(requiredMessagePart), env.defaultTimeoutMillis(), env.defaultPollTimeoutMillis()); - } - public void expectErrorWithMessage(Class expected, List requiredMessagePartAlternatives) throws Exception { - expectErrorWithMessage(expected, requiredMessagePartAlternatives, env.defaultTimeoutMillis(), env.defaultPollTimeoutMillis()); - } - - @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - public void expectErrorWithMessage(Class expected, String requiredMessagePart, long timeoutMillis) throws Exception { - expectErrorWithMessage(expected, Collections.singletonList(requiredMessagePart), timeoutMillis); - } - - public void expectErrorWithMessage(Class expected, List requiredMessagePartAlternatives, long timeoutMillis) throws Exception { - expectErrorWithMessage(expected, requiredMessagePartAlternatives, timeoutMillis, timeoutMillis); - } - - public void expectErrorWithMessage(Class expected, List requiredMessagePartAlternatives, - long totalTimeoutMillis, long pollTimeoutMillis) throws Exception { - final E err = expectError(expected, totalTimeoutMillis, pollTimeoutMillis); - final String message = err.getMessage(); - - boolean contains = false; - for (String requiredMessagePart : requiredMessagePartAlternatives) - if (message.contains(requiredMessagePart)) contains = true; // not short-circuting loop, it is expected to - assertTrue(contains, - String.format("Got expected exception [%s] but missing message part [%s], was: %s", - err.getClass(), "anyOf: " + requiredMessagePartAlternatives, err.getMessage())); - } - - public E expectError(Class expected) throws Exception { - return expectError(expected, env.defaultTimeoutMillis()); - } - - public E expectError(Class expected, long timeoutMillis) throws Exception { - return expectError(expected, timeoutMillis, env.defaultPollTimeoutMillis()); - } - - public E expectError(Class expected, String errorMsg) throws Exception { - return expectError(expected, env.defaultTimeoutMillis(), errorMsg); - } - - public E expectError(Class expected, long timeoutMillis, String errorMsg) throws Exception { - return expectError(expected, timeoutMillis, env.defaultPollTimeoutMillis(), errorMsg); - } - - public E expectError(Class expected, long totalTimeoutMillis, long pollTimeoutMillis) throws Exception { - return expectError(expected, totalTimeoutMillis, pollTimeoutMillis, String.format("Expected onError(%s)", expected.getName())); - } - - public E expectError(Class expected, long totalTimeoutMillis, long pollTimeoutMillis, - String errorMsg) throws Exception { - return received.expectError(expected, totalTimeoutMillis, pollTimeoutMillis, errorMsg); - } - - public void expectNone() throws InterruptedException { - expectNone(env.defaultNoSignalsTimeoutMillis()); - } - - public void expectNone(String errMsgPrefix) throws InterruptedException { - expectNone(env.defaultNoSignalsTimeoutMillis(), errMsgPrefix); - } - - public void expectNone(long withinMillis) throws InterruptedException { - expectNone(withinMillis, "Did not expect an element but got element"); - } - - public void expectNone(long withinMillis, String errMsgPrefix) throws InterruptedException { - received.expectNone(withinMillis, errMsgPrefix); - } - - } - - public static class ManualSubscriberWithSubscriptionSupport extends ManualSubscriber { - - public ManualSubscriberWithSubscriptionSupport(TestEnvironment env) { - super(env); - } - - @Override - public void onNext(T element) { - if (env.debugEnabled()) { - env.debug(String.format("%s::onNext(%s)", this, element)); - } - if (subscription.isCompleted()) { - super.onNext(element); - } else { - env.flop(String.format("Subscriber::onNext(%s) called before Subscriber::onSubscribe", element)); - } - } - - @Override - public void onComplete() { - if (env.debugEnabled()) { - env.debug(this + "::onComplete()"); - } - if (subscription.isCompleted()) { - super.onComplete(); - } else { - env.flop("Subscriber::onComplete() called before Subscriber::onSubscribe"); - } - } - - @Override - public void onSubscribe(Subscription s) { - if (env.debugEnabled()) { - env.debug(String.format("%s::onSubscribe(%s)", this, s)); - } - if (!subscription.isCompleted()) { - subscription.complete(s); - } else { - env.flop("Subscriber::onSubscribe called on an already-subscribed Subscriber"); - } - } - - @Override - public void onError(Throwable cause) { - if (env.debugEnabled()) { - env.debug(String.format("%s::onError(%s)", this, cause)); - } - if (subscription.isCompleted()) { - super.onError(cause); - } else { - env.flop(cause, String.format("Subscriber::onError(%s) called before Subscriber::onSubscribe", cause)); - } - } - } - - /** - * Similar to {@link org.reactivestreams.tck.TestEnvironment.ManualSubscriberWithSubscriptionSupport} - * but does not accumulate values signalled via onNext, thus it can not be used to assert - * values signalled to this subscriber. Instead it may be used to quickly drain a given publisher. - */ - public static class BlackholeSubscriberWithSubscriptionSupport - extends ManualSubscriberWithSubscriptionSupport { - - public BlackholeSubscriberWithSubscriptionSupport(TestEnvironment env) { - super(env); - } - - @Override - public void onNext(T element) { - if (env.debugEnabled()) { - env.debug(String.format("%s::onNext(%s)", this, element)); - } - if (!subscription.isCompleted()) { - env.flop(String.format("Subscriber::onNext(%s) called before Subscriber::onSubscribe", element)); - } - } - - @Override - public T nextElement(long timeoutMillis, String errorMsg) throws InterruptedException { - throw new RuntimeException("Can not expect elements from BlackholeSubscriber, use ManualSubscriber instead!"); - } - - @Override - public List nextElements(long elements, long timeoutMillis, String errorMsg) throws InterruptedException { - throw new RuntimeException("Can not expect elements from BlackholeSubscriber, use ManualSubscriber instead!"); - } - } - - public static class TestSubscriber implements Subscriber { - final Promise subscription; - - protected final TestEnvironment env; - - public TestSubscriber(TestEnvironment env) { - this.env = env; - subscription = new Promise(env); - } - - @Override - public void onError(Throwable cause) { - env.flop(cause, String.format("Unexpected Subscriber::onError(%s)", cause)); - } - - @Override - public void onComplete() { - env.flop("Unexpected Subscriber::onComplete()"); - } - - @Override - public void onNext(T element) { - env.flop(String.format("Unexpected Subscriber::onNext(%s)", element)); - } - - @Override - public void onSubscribe(Subscription subscription) { - env.flop(String.format("Unexpected Subscriber::onSubscribe(%s)", subscription)); - } - - public void cancel() { - if (subscription.isCompleted()) { - subscription.value().cancel(); - } else { - env.flop("Cannot cancel a subscription before having received it"); - } - } - } - - public static class ManualPublisher implements Publisher { - protected final TestEnvironment env; - - protected long pendingDemand = 0L; - protected Promise> subscriber; - - protected final Receptacle requests; - - protected final Latch cancelled; - - public ManualPublisher(TestEnvironment env) { - this.env = env; - requests = new Receptacle(env); - cancelled = new Latch(env); - subscriber = new Promise>(this.env); - } - - @Override - public void subscribe(Subscriber s) { - if (!subscriber.isCompleted()) { - subscriber.completeImmediatly(s); - - Subscription subs = new Subscription() { - @Override - public void request(long elements) { - requests.add(elements); - } - - @Override - public void cancel() { - cancelled.close(); - } - }; - s.onSubscribe(subs); - - } else { - env.flop("TestPublisher doesn't support more than one Subscriber"); - } - } - - public void sendNext(T element) { - if (subscriber.isCompleted()) { - subscriber.value().onNext(element); - } else { - env.flop("Cannot sendNext before having a Subscriber"); - } - } - - public void sendCompletion() { - if (subscriber.isCompleted()) { - subscriber.value().onComplete(); - } else { - env.flop("Cannot sendCompletion before having a Subscriber"); - } - } - - public void sendError(Throwable cause) { - if (subscriber.isCompleted()) { - subscriber.value().onError(cause); - } else { - env.flop("Cannot sendError before having a Subscriber"); - } - } - - public long expectRequest() throws InterruptedException { - return expectRequest(env.defaultTimeoutMillis()); - } - - public long expectRequest(long timeoutMillis) throws InterruptedException { - long requested = requests.next(timeoutMillis, "Did not receive expected `request` call"); - if (requested <= 0) { - return env.flopAndFail(String.format("Requests cannot be zero or negative but received request(%s)", requested)); - } else { - pendingDemand += requested; - return requested; - } - } - - - public long expectRequest(long timeoutMillis, String errorMessageAddendum) throws InterruptedException { - long requested = requests.next(timeoutMillis, String.format("Did not receive expected `request` call. %s", errorMessageAddendum)); - if (requested <= 0) { - return env.flopAndFail(String.format("Requests cannot be zero or negative but received request(%s)", requested)); - } else { - pendingDemand += requested; - return requested; - } - } - - public void expectExactRequest(long expected) throws InterruptedException { - expectExactRequest(expected, env.defaultTimeoutMillis()); - } - - public void expectExactRequest(long expected, long timeoutMillis) throws InterruptedException { - long requested = expectRequest(timeoutMillis); - if (requested != expected) { - env.flop(String.format("Received `request(%d)` on upstream but expected `request(%d)`", requested, expected)); - } - pendingDemand += requested; - } - - public void expectNoRequest() throws InterruptedException { - expectNoRequest(env.defaultTimeoutMillis()); - } - - public void expectNoRequest(long timeoutMillis) throws InterruptedException { - requests.expectNone(timeoutMillis, "Received an unexpected call to: request: "); - } - - public void expectCancelling() throws InterruptedException { - expectCancelling(env.defaultTimeoutMillis()); - } - - public void expectCancelling(long timeoutMillis) throws InterruptedException { - cancelled.expectClose(timeoutMillis, "Did not receive expected cancelling of upstream subscription"); - } - - public boolean isCancelled() throws InterruptedException { - return cancelled.isClosed(); - } - } - - /** - * Like a CountDownLatch, but resettable and with some convenience methods - */ - public static class Latch { - private final TestEnvironment env; - volatile private CountDownLatch countDownLatch = new CountDownLatch(1); - - public Latch(TestEnvironment env) { - this.env = env; - } - - public void reOpen() { - countDownLatch = new CountDownLatch(1); - } - - public boolean isClosed() { - return countDownLatch.getCount() == 0; - } - - public void close() { - countDownLatch.countDown(); - } - - public void assertClosed(String openErrorMsg) { - if (!isClosed()) { - env.flop(new ExpectedClosedLatchException(openErrorMsg)); - } - } - - public void assertOpen(String closedErrorMsg) { - if (isClosed()) { - env.flop(new ExpectedOpenLatchException(closedErrorMsg)); - } - } - - public void expectClose(String notClosedErrorMsg) throws InterruptedException { - expectClose(env.defaultTimeoutMillis(), notClosedErrorMsg); - } - - public void expectClose(long timeoutMillis, String notClosedErrorMsg) throws InterruptedException { - countDownLatch.await(timeoutMillis, TimeUnit.MILLISECONDS); - if (countDownLatch.getCount() > 0) { - env.flop(String.format("%s within %d ms", notClosedErrorMsg, timeoutMillis)); - } - } - - static final class ExpectedOpenLatchException extends RuntimeException { - public ExpectedOpenLatchException(String message) { - super(message); - } - } - - static final class ExpectedClosedLatchException extends RuntimeException { - public ExpectedClosedLatchException(String message) { - super(message); - } - } - - } - - // simple promise for *one* value, which cannot be reset - public static class Promise { - private final TestEnvironment env; - - public static Promise completed(TestEnvironment env, T value) { - Promise promise = new Promise(env); - promise.completeImmediatly(value); - return promise; - } - - public Promise(TestEnvironment env) { - this.env = env; - } - - private ArrayBlockingQueue abq = new ArrayBlockingQueue(1); - private AtomicReference _value = new AtomicReference(); - - public T value() { - final T value = _value.get(); - if (value != null) { - return value; - } else { - env.flop("Cannot access promise value before completion"); - return null; - } - } - - public boolean isCompleted() { - return _value.get() != null; - } - - /** - * Allows using expectCompletion to await for completion of the value and complete it _then_ - */ - public void complete(T value) { - if (_value.compareAndSet(null, value)) { - // we add the value to the queue such to wake up any expectCompletion which was triggered before complete() was called - abq.add(value); - } else { - env.flop(String.format("Cannot complete a promise more than once! Present value: %s, attempted to set: %s", _value.get(), value)); - } - } - - /** - * Same as complete. - * - * Keeping this method for binary compatibility. - */ - public void completeImmediatly(T value) { - complete(value); - } - - public void expectCompletion(long timeoutMillis, String errorMsg) throws InterruptedException { - if (!isCompleted()) { - T val = abq.poll(timeoutMillis, TimeUnit.MILLISECONDS); - - if (val == null) { - env.flop(String.format("%s within %d ms", errorMsg, timeoutMillis)); - } - } - } - } - - // a "Promise" for multiple values, which also supports "end-of-stream reached" - public static class Receptacle { - final int QUEUE_SIZE = 2 * TEST_BUFFER_SIZE; - private final TestEnvironment env; - - private final ArrayBlockingQueue> abq = new ArrayBlockingQueue>(QUEUE_SIZE); - - private final Latch completedLatch; - - Receptacle(TestEnvironment env) { - this.env = env; - this.completedLatch = new Latch(env); - } - - public void add(T value) { - completedLatch.assertOpen(String.format("Unexpected element %s received after stream completed", value)); - - abq.add(Optional.of(value)); - } - - public void complete() { - completedLatch.assertOpen("Unexpected additional complete signal received!"); - completedLatch.close(); - - abq.add(Optional.empty()); - } - - public T next(long timeoutMillis, String errorMsg) throws InterruptedException { - Optional value = abq.poll(timeoutMillis, TimeUnit.MILLISECONDS); - - if (value == null) { - return env.flopAndFail(String.format("%s within %d ms", errorMsg, timeoutMillis)); - } else if (value.isDefined()) { - return value.get(); - } else { - return env.flopAndFail("Expected element but got end-of-stream"); - } - } - - public Optional nextOrEndOfStream(long timeoutMillis, String errorMsg) throws InterruptedException { - Optional value = abq.poll(timeoutMillis, TimeUnit.MILLISECONDS); - - if (value == null) { - env.flop(String.format("%s within %d ms", errorMsg, timeoutMillis)); - return Optional.empty(); - } - - return value; - } - - /** - * @param timeoutMillis total timeout time for awaiting all {@code elements} number of elements - */ - public List nextN(long elements, long timeoutMillis, String errorMsg) throws InterruptedException { - List result = new LinkedList(); - long remaining = elements; - long deadline = System.currentTimeMillis() + timeoutMillis; - while (remaining > 0) { - long remainingMillis = deadline - System.currentTimeMillis(); - - result.add(next(remainingMillis, errorMsg)); - remaining--; - } - - return result; - } - - - public void expectCompletion(long timeoutMillis, String errorMsg) throws InterruptedException { - Optional value = abq.poll(timeoutMillis, TimeUnit.MILLISECONDS); - - if (value == null) { - env.flop(String.format("%s within %d ms", errorMsg, timeoutMillis)); - } else if (value.isDefined()) { - env.flop(String.format("Expected end-of-stream but got element [%s]", value.get())); - } // else, ok - } - - /** - * @deprecated Deprecated in favor of {@link #expectError(Class, long, long, String)}. - */ - @Deprecated - public E expectError(Class clazz, long timeoutMillis, String errorMsg) throws Exception { - return expectError(clazz, timeoutMillis, timeoutMillis, errorMsg); - } - - @SuppressWarnings("unchecked") - final E expectError(Class clazz, final long totalTimeoutMillis, - long pollTimeoutMillis, - String errorMsg) throws Exception { - long totalTimeoutRemainingNs = MILLISECONDS.toNanos(totalTimeoutMillis); - long timeStampANs = System.nanoTime(); - long timeStampBNs; - - for (;;) { - Thread.sleep(Math.min(pollTimeoutMillis, NANOSECONDS.toMillis(totalTimeoutRemainingNs))); - - if (env.asyncErrors.isEmpty()) { - timeStampBNs = System.nanoTime(); - totalTimeoutRemainingNs =- timeStampBNs - timeStampANs; - timeStampANs = timeStampBNs; - - if (totalTimeoutRemainingNs <= 0) { - return env.flopAndFail(String.format("%s within %d ms", errorMsg, totalTimeoutMillis)); - } - } else { - // ok, there was an expected error - Throwable thrown = env.asyncErrors.remove(0); - - if (clazz.isInstance(thrown)) { - return (E) thrown; - } else { - - return env.flopAndFail(String.format("%s within %d ms; Got %s but expected %s", - errorMsg, totalTimeoutMillis, thrown.getClass().getCanonicalName(), clazz.getCanonicalName())); - } - } - } - } - - public void expectNone(long withinMillis, String errorMsgPrefix) throws InterruptedException { - Thread.sleep(withinMillis); - Optional value = abq.poll(); - - if (value == null) { - // ok - } else if (value.isDefined()) { - env.flop(String.format("%s [%s]", errorMsgPrefix, value.get())); - } else { - env.flop("Expected no element but got end-of-stream"); - } - } - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/WithHelperPublisher.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/WithHelperPublisher.java deleted file mode 100644 index 2441a87f20c..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/WithHelperPublisher.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck; - -import org.reactivestreams.Publisher; -import org.reactivestreams.tck.flow.support.Function; -import org.reactivestreams.tck.flow.support.HelperPublisher; -import org.reactivestreams.tck.flow.support.InfiniteHelperPublisher; - -import java.util.concurrent.ExecutorService; - -/** - * Type which is able to create elements based on a seed {@code id} value. - *

- * Simplest implementations will simply return the incoming id as the element. - * - * @param type of element to be delivered to the Subscriber - */ -public abstract class WithHelperPublisher { - - /** ExecutorService to be used by the provided helper {@link org.reactivestreams.Publisher} */ - public abstract ExecutorService publisherExecutorService(); - - /** - * Implement this method to match your expected element type. - * In case of implementing a simple Subscriber which is able to consume any kind of element simply return the - * incoming {@code element} element. - *

- * Sometimes the Subscriber may be limited in what type of element it is able to consume, this you may have to implement - * this method such that the emitted element matches the Subscribers requirements. Simplest implementations would be - * to simply pass in the {@code element} as payload of your custom element, such as appending it to a String or other identifier. - *

- * Warning: This method may be called concurrently by the helper publisher, thus it should be implemented in a - * thread-safe manner. - * - * @return element of the matching type {@code T} that will be delivered to the tested Subscriber - */ - public abstract T createElement(int element); - - /** - * Helper method required for creating the Publisher to which the tested Subscriber will be subscribed and tested against. - *

- * By default an asynchronously signalling Publisher is provided, which will use {@link #createElement(int)} - * to generate elements type your Subscriber is able to consume. - *

- * Sometimes you may want to implement your own custom custom helper Publisher - to validate behaviour of a Subscriber - * when facing a synchronous Publisher for example. If you do, it MUST emit the exact number of elements asked for - * (via the {@code elements} parameter) and MUST also must treat the following numbers of elements in these specific ways: - *

    - *
  • - * If {@code elements} is {@code Long.MAX_VALUE} the produced stream must be infinite. - *
  • - *
  • - * If {@code elements} is {@code 0} the {@code Publisher} should signal {@code onComplete} immediatly. - * In other words, it should represent a "completed stream". - *
  • - *
- */ - @SuppressWarnings("unchecked") - public Publisher createHelperPublisher(long elements) { - final Function mkElement = new Function() { - @Override public T apply(Integer id) throws Throwable { - return createElement(id); - } - }; - - if (elements > Integer.MAX_VALUE) return new InfiniteHelperPublisher(mkElement, publisherExecutorService()); - else return new HelperPublisher(0, (int) elements, mkElement, publisherExecutorService()); - } - -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/FlowPublisherVerification.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/FlowPublisherVerification.java deleted file mode 100644 index 67bd47d67d4..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/FlowPublisherVerification.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.flow; - -import org.reactivestreams.Publisher; -import org.reactivestreams.FlowAdapters; -import org.reactivestreams.tck.PublisherVerification; -import org.reactivestreams.tck.TestEnvironment; - -import java.util.concurrent.Flow; - -/** - * Provides tests for verifying a Java 9+ {@link java.util.concurrent.Flow.Publisher} specification rules. - * - * @see java.util.concurrent.Flow.Publisher - */ -public abstract class FlowPublisherVerification extends PublisherVerification { - - public FlowPublisherVerification(TestEnvironment env, long publisherReferenceGCTimeoutMillis) { - super(env, publisherReferenceGCTimeoutMillis); - } - - public FlowPublisherVerification(TestEnvironment env) { - super(env); - } - - @Override - final public Publisher createPublisher(long elements) { - final Flow.Publisher flowPublisher = createFlowPublisher(elements); - return FlowAdapters.toPublisher(flowPublisher); - } - /** - * This is the main method you must implement in your test incarnation. - * It must create a Publisher for a stream with exactly the given number of elements. - * If `elements` is `Long.MAX_VALUE` the produced stream must be infinite. - */ - public abstract Flow.Publisher createFlowPublisher(long elements); - - @Override - final public Publisher createFailedPublisher() { - final Flow.Publisher failed = createFailedFlowPublisher(); - if (failed == null) return null; // because `null` means "SKIP" in createFailedPublisher - else return FlowAdapters.toPublisher(failed); - } - /** - * By implementing this method, additional TCK tests concerning a "failed" publishers will be run. - * - * The expected behaviour of the {@link Flow.Publisher} returned by this method is hand out a subscription, - * followed by signalling {@code onError} on it, as specified by Rule 1.9. - * - * If you ignore these additional tests, return {@code null} from this method. - */ - public abstract Flow.Publisher createFailedFlowPublisher(); -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/FlowSubscriberBlackboxVerification.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/FlowSubscriberBlackboxVerification.java deleted file mode 100644 index 810ba85d0ff..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/FlowSubscriberBlackboxVerification.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.flow; - -import org.reactivestreams.FlowAdapters; -import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; -import org.reactivestreams.tck.SubscriberBlackboxVerification; -import org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.support.SubscriberBlackboxVerificationRules; - -import java.util.concurrent.Flow; - -/** - * Provides tests for verifying {@link java.util.concurrent.Flow.Subscriber} and {@link java.util.concurrent.Flow.Subscription} - * specification rules, without any modifications to the tested implementation (also known as "Black Box" testing). - * - * This verification is NOT able to check many of the rules of the spec, and if you want more - * verification of your implementation you'll have to implement {@code org.reactivestreams.tck.SubscriberWhiteboxVerification} - * instead. - * - * @see java.util.concurrent.Flow.Subscriber - * @see java.util.concurrent.Flow.Subscription - */ -public abstract class FlowSubscriberBlackboxVerification extends SubscriberBlackboxVerification - implements SubscriberBlackboxVerificationRules { - - protected FlowSubscriberBlackboxVerification(TestEnvironment env) { - super(env); - } - - @Override - public final void triggerRequest(Subscriber subscriber) { - triggerFlowRequest(FlowAdapters.toFlowSubscriber(subscriber)); - } - /** - * Override this method if the {@link java.util.concurrent.Flow.Subscriber} implementation you are verifying - * needs an external signal before it signals demand to its Publisher. - * - * By default this method does nothing. - */ - public void triggerFlowRequest(Flow.Subscriber subscriber) { - // this method is intentionally left blank - } - - @Override - public final Subscriber createSubscriber() { - return FlowAdapters.toSubscriber(createFlowSubscriber()); - } - /** - * This is the main method you must implement in your test incarnation. - * It must create a new {@link Flow.Subscriber} instance to be subjected to the testing logic. - */ - abstract public Flow.Subscriber createFlowSubscriber(); - -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/FlowSubscriberWhiteboxVerification.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/FlowSubscriberWhiteboxVerification.java deleted file mode 100644 index 9b382700d4f..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/FlowSubscriberWhiteboxVerification.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.flow; - -import org.reactivestreams.FlowAdapters; -import org.reactivestreams.Subscriber; -import org.reactivestreams.tck.SubscriberWhiteboxVerification; -import org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.support.SubscriberWhiteboxVerificationRules; - -import java.util.concurrent.Flow; - -/** - * Provides whitebox style tests for verifying {@link java.util.concurrent.Flow.Subscriber} - * and {@link java.util.concurrent.Flow.Subscription} specification rules. - * - * @see java.util.concurrent.Flow.Subscriber - * @see java.util.concurrent.Flow.Subscription - */ -public abstract class FlowSubscriberWhiteboxVerification extends SubscriberWhiteboxVerification - implements SubscriberWhiteboxVerificationRules { - - protected FlowSubscriberWhiteboxVerification(TestEnvironment env) { - super(env); - } - - @Override - final public Subscriber createSubscriber(WhiteboxSubscriberProbe probe) { - return FlowAdapters.toSubscriber(createFlowSubscriber(probe)); - } - /** - * This is the main method you must implement in your test incarnation. - * It must create a new {@link org.reactivestreams.Subscriber} instance to be subjected to the testing logic. - * - * In order to be meaningfully testable your Subscriber must inform the given - * `WhiteboxSubscriberProbe` of the respective events having been received. - */ - protected abstract Flow.Subscriber createFlowSubscriber(WhiteboxSubscriberProbe probe); -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/IdentityFlowProcessorVerification.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/IdentityFlowProcessorVerification.java deleted file mode 100644 index 20dd71499eb..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/IdentityFlowProcessorVerification.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.flow; - -import org.reactivestreams.*; -import org.reactivestreams.tck.IdentityProcessorVerification; -import org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.support.SubscriberWhiteboxVerificationRules; -import org.reactivestreams.tck.flow.support.PublisherVerificationRules; - -import java.util.concurrent.Flow; - -public abstract class IdentityFlowProcessorVerification extends IdentityProcessorVerification - implements SubscriberWhiteboxVerificationRules, PublisherVerificationRules { - - public IdentityFlowProcessorVerification(TestEnvironment env) { - super(env); - } - - public IdentityFlowProcessorVerification(TestEnvironment env, long publisherReferenceGCTimeoutMillis) { - super(env, publisherReferenceGCTimeoutMillis); - } - - public IdentityFlowProcessorVerification(TestEnvironment env, long publisherReferenceGCTimeoutMillis, int processorBufferSize) { - super(env, publisherReferenceGCTimeoutMillis, processorBufferSize); - } - - /** - * By implementing this method, additional TCK tests concerning a "failed" Flow publishers will be run. - * - * The expected behaviour of the {@link Flow.Publisher} returned by this method is hand out a subscription, - * followed by signalling {@code onError} on it, as specified by Rule 1.9. - * - * If you want to ignore these additional tests, return {@code null} from this method. - */ - protected abstract Flow.Publisher createFailedFlowPublisher(); - - /** - * This is the main method you must implement in your test incarnation. - * It must create a {@link Flow.Processor}, which simply forwards all stream elements from its upstream - * to its downstream. It must be able to internally buffer the given number of elements. - * - * @param bufferSize number of elements the processor is required to be able to buffer. - */ - protected abstract Flow.Processor createIdentityFlowProcessor(int bufferSize); - - @Override - public final Processor createIdentityProcessor(int bufferSize) { - return FlowAdapters.toProcessor(createIdentityFlowProcessor(bufferSize)); - } - - @Override - public final Publisher createFailedPublisher() { - Flow.Publisher failed = createFailedFlowPublisher(); - if (failed == null) return null; // because `null` means "SKIP" in createFailedPublisher - else return FlowAdapters.toPublisher(failed); - } - -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/HelperPublisher.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/HelperPublisher.java deleted file mode 100644 index 120fd43e694..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/HelperPublisher.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.flow.support; - -import java.util.Collections; -import java.util.Iterator; -import java.util.concurrent.Executor; - -import org.reactivestreams.example.unicast.AsyncIterablePublisher; - -public class HelperPublisher extends AsyncIterablePublisher { - - public HelperPublisher(final int from, final int to, final Function create, final Executor executor) { - super(new Iterable() { - { if(from > to) throw new IllegalArgumentException("from must be equal or greater than to!"); } - @Override public Iterator iterator() { - return new Iterator() { - private int at = from; - @Override public boolean hasNext() { return at < to; } - @Override public T next() { - if (!hasNext()) return Collections.emptyList().iterator().next(); - else try { - return create.apply(at++); - } catch (Throwable t) { - throw new IllegalStateException(String.format("Failed to create element for id %d!", at - 1), t); - } - } - @Override public void remove() { throw new UnsupportedOperationException(); } - }; - } - }, executor); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/InfiniteHelperPublisher.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/InfiniteHelperPublisher.java deleted file mode 100644 index e3cfccb5978..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/InfiniteHelperPublisher.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.flow.support; - -import org.reactivestreams.example.unicast.AsyncIterablePublisher; - -import java.util.Iterator; -import java.util.concurrent.Executor; - -public class InfiniteHelperPublisher extends AsyncIterablePublisher { - - public InfiniteHelperPublisher(final Function create, final Executor executor) { - super(new Iterable() { - @Override public Iterator iterator() { - return new Iterator() { - private int at = 0; - - @Override public boolean hasNext() { return true; } - @Override public T next() { - try { - return create.apply(at++); // Wraps around on overflow - } catch (Throwable t) { - throw new IllegalStateException( - String.format("Failed to create element in %s for id %s!", getClass().getSimpleName(), at - 1), t); - } - } - @Override public void remove() { throw new UnsupportedOperationException(); } - }; - } - }, executor); - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/NonFatal.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/NonFatal.java deleted file mode 100644 index ee315931f72..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/NonFatal.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.flow.support; - - -/** - * Copy of scala.control.util.NonFatal in order to not depend on scala-library - */ -public class NonFatal { - private NonFatal() { - // no instances, please. - } - - /** - * Returns true if the provided `Throwable` is to be considered non-fatal, or false if it is to be considered fatal - * - * @param t throwable to be matched for fatal-ness - * @return true if is a non-fatal throwable, false otherwise - */ - public static boolean isNonFatal(Throwable t) { - if (t instanceof StackOverflowError) { - // StackOverflowError ok even though it is a VirtualMachineError - return true; - } else if (t instanceof VirtualMachineError || - t instanceof ThreadDeath || - t instanceof InterruptedException || - t instanceof LinkageError) { - // VirtualMachineError includes OutOfMemoryError and other fatal errors - return false; - } else { - return true; - } - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/Optional.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/Optional.java deleted file mode 100644 index d191fe0a39d..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/Optional.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.flow.support; - -import java.util.NoSuchElementException; - -// simplest possible version of Scala's Option type -public abstract class Optional { - - private static final Optional NONE = new Optional() { - @Override - public Object get() { - throw new NoSuchElementException(".get call on None!"); - } - - @Override - public boolean isEmpty() { - return true; - } - }; - - private Optional() { - } - - @SuppressWarnings("unchecked") - public static Optional empty() { - return (Optional) NONE; - } - - @SuppressWarnings("unchecked") - public static Optional of(T it) { - if (it == null) return (Optional) Optional.NONE; - else return new Some(it); - } - - public abstract T get(); - - public abstract boolean isEmpty(); - - public boolean isDefined() { - return !isEmpty(); - } - - public static class Some extends Optional { - private final T value; - - Some(T value) { - this.value = value; - } - - @Override - public T get() { - return value; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public String toString() { - return String.format("Some(%s)", value); - } - } - - @Override - public String toString() { - return "None"; - } -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/PublisherVerificationRules.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/PublisherVerificationRules.java deleted file mode 100644 index 823a5174652..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/PublisherVerificationRules.java +++ /dev/null @@ -1,658 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.flow.support; - -/** - * Internal TCK use only. - * Add / Remove tests for PublisherVerification here to make sure that they arre added/removed in the other places. - */ -public interface PublisherVerificationRules { - /** - * Validates that the override of {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} - * returns a non-negative value. - */ - void required_validate_maxElementsFromPublisher() throws Exception; - /** - * Validates that the override of {@link org.reactivestreams.tck.PublisherVerification#boundedDepthOfOnNextAndRequestRecursion()} - * returns a positive value. - */ - void required_validate_boundedDepthOfOnNextAndRequestRecursion() throws Exception; - /** - * Asks for a {@code Publisher} that should emit exactly one item and complete (both within a - * timeout specified by {@link org.reactivestreams.tck.TestEnvironment#defaultTimeoutMillis()}) - * in response to a request(1). - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} returns zero. - * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code Publisher.subscribe(Subscriber)} method has actual implementation,
  • - *
  • in the {@code Publisher.subscribe(Subscriber)} method, if there is an upstream {@code Publisher}, - * that {@code Publisher} is actually subscribed to,
  • - *
  • if the {@code Publisher} is part of a chain, all elements actually issue a {@code request()} call - * in response to the test subscriber or by default to their upstream,
  • - *
  • in the {@code Publisher.subscribe(Subscriber)} method, the {@code Subscriber.onSubscribe} is called - * as part of the preparation process (usually before subscribing to other {@code Publisher}s),
  • - *
  • if the {@code Publisher} implementation works for a consumer that calls {@code request(1)},
  • - *
  • if the {@code Publisher} implementation is able to emit an {@code onComplete} without requests,
  • - *
  • that the {@code Publisher} implementation does not emit more than the allowed elements (exactly one).
  • - *
- */ - void required_createPublisher1MustProduceAStreamOfExactly1Element() throws Throwable; - /** - * Asks for a {@code Publisher} that should emit exactly three items and complete (all within a - * timeout specified by {@link org.reactivestreams.tck.TestEnvironment#defaultTimeoutMillis()}). - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. - *

- * The tests requests one-by-one and verifies each single response item arrives in time. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code Publisher.subscribe(Subscriber)} method has actual implementation,
  • - *
  • in the {@code Publisher.subscribe(Subscriber)} method, if there is an upstream {@code Publisher}, - * that {@code Publisher} is actually subscribed to,
  • - *
  • if the {@code Publisher} is part of a chain, all elements actually issue a {@code request()} call - * in response to the test subscriber or by default to their upstream,
  • - *
  • in the {@code Publisher.subscribe(Subscriber)} method, the {@code Subscriber.onSubscribe} is called - * as part of the preparation process (usually before subscribing to other {@code Publisher}s),
  • - *
  • if the {@code Publisher} implementation works for a subscriber that calls {@code request(1)} after consuming an item,
  • - *
  • if the {@code Publisher} implementation is able to emit an {@code onComplete} without requests.
  • - *
- */ - void required_createPublisher3MustProduceAStreamOfExactly3Elements() throws Throwable; - /** - * Asks for a {@code Publisher} that responds to a request pattern of 0 (not requesting upfront), 1, 1 and 2 - * in a timely manner. - *

- * Verifies rule: 1.1 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 5. - *

- * This test ensures that the {@code Publisher} implementation correctly responds to {@code request()} calls that in - * total are less than the number of elements this {@code Publisher} could emit (thus the completion event won't be emitted). - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • if the {@code Publisher} implementation considers the cumulative request amount it receives,
  • - *
  • if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.
  • - *
- */ - void required_spec101_subscriptionRequestMustResultInTheCorrectNumberOfProducedElements() throws Throwable; - /** - * Asks for a short {@code Publisher} and verifies that requesting once and with more than the length (but bounded) results in the - * correct number of items to be emitted (i.e., length 3 and request 10) followed by an {@code onComplete} signal. - *

- * Verifies rule: 1.2 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. - *

- * This test ensures that the {@code Publisher} implementation can deal with larger requests than the number of items it can produce. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass.
  • - *
- */ - void required_spec102_maySignalLessThanRequestedAndTerminateSubscription() throws Throwable; - /** - * Asks for a short {@code Publisher} (i.e., length 10), repeatedly subscribes to this {@code Publisher}, requests items - * one by one and verifies the {@code Publisher} calls the {@code onXXX} methods non-overlappingly. - *

- * Verifies rule: 1.3 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 10. - *

- * Note that this test is probabilistic, that is, may not capture any concurrent invocation in a {code Publisher} implementation. - * Note also that this test is sensitive to cases when a {@code request()} call in {@code onSubscribe()} triggers an asynchronous - * call to the other {@code onXXX} methods. In contrast, the test allows synchronous call chain of - * {@code onSubscribe -> request -> onNext}. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • if a {@code request()} call from {@code onSubscribe()} could trigger an asynchronous call to {@code onNext()} and if so, make sure - * such {@code request()} calls are deferred until the call to {@code onSubscribe()} returns normally.
  • - *
- */ - void stochastic_spec103_mustSignalOnMethodsSequentially() throws Throwable; - /** - * Asks for an error {@code Publisher} that should call {@code onSubscribe} exactly once - * followed by a single call to {@code onError()} without receiving any requests and otherwise - * not throwing any exception. - *

- * Verifies rule: 1.4 - *

- * The test is not executed if {@code PublisherVerification.createErrorPublisher()} returns null. - *

- * If this test fails, the following could be checked within the error {@code Publisher} implementation: - *

    - *
  • the {@code Publisher.subscribe(Subscriber)} method has actual implementation,
  • - *
  • in the {@code Publisher.subscribe(Subscriber)} method, if there is an upstream {@code Publisher}, - * that {@code Publisher} is actually subscribed to,
  • - *
  • if the {@code Publisher} implementation does signal an {@code onSubscribe} before signalling {@code onError},
  • - *
  • if the {@code Publisher} implementation is able to emit an {@code onError} without requests,
  • - *
  • if the {@code Publisher} is non-empty as this test requires a {@code Publisher} to signal an - * {@code onError} eagerly.
  • - *
- */ - void optional_spec104_mustSignalOnErrorWhenFails() throws Throwable; - /** - * Asks for a short {@code Publisher} (i.e., length 3) and verifies, after requesting one by one, the sequence - * completes normally. - *

- * Verifies rule: 1.5 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. - *

- * Note that the tests requests 1 after the items have been received and before expecting an {@code onComplete} signal. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
- */ - void required_spec105_mustSignalOnCompleteWhenFiniteStreamTerminates() throws Throwable; - /** - * Asks for an empty {@code Publisher} (i.e., length 0) and verifies it completes in a timely manner. - *

- * Verifies rule: 1.5 - *

- * Note that the tests requests 1 before expecting an {@code onComplete} signal. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • if the {@code Publisher} is non-empty as this test requires a {@code Publisher} without items.
  • - *
- */ - void optional_spec105_emptyStreamMustTerminateBySignallingOnComplete() throws Throwable; - /** - * Currently, this test is skipped because it is unclear this rule can be effectively checked - * on a {@code Publisher} instance without looking into or hooking into the implementation of it. - *

- * Verifies rule: 1.6 - */ - void untested_spec106_mustConsiderSubscriptionCancelledAfterOnErrorOrOnCompleteHasBeenCalled() throws Throwable; - /** - * Asks for a single-element {@code Publisher} and checks if requesting after the terminal event doesn't - * lead to more items or terminal signals to be emitted. - *

- * Verifies rule: 1.7 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 1. - *

- * The tests requests more items than the expected {@code Publisher} length upfront and some more items after its completion. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • the indication for the terminal state is properly persisted and a request call can't trigger emission of more items or another - * terminal signal.
  • - *
- */ - void required_spec107_mustNotEmitFurtherSignalsOnceOnCompleteHasBeenSignalled() throws Throwable; - /** - * Currently, this test is skipped, although it is possible to validate an error {@code Publisher} along - * the same lines as {@link #required_spec107_mustNotEmitFurtherSignalsOnceOnCompleteHasBeenSignalled()}. - *

- * Verifies rule: 1.7 - */ - void untested_spec107_mustNotEmitFurtherSignalsOnceOnErrorHasBeenSignalled() throws Throwable; - /** - * Currently, this test is skipped because there was no agreement on how to verify its "eventually" requirement. - *

- * Verifies rule: 1.8 - */ - void untested_spec108_possiblyCanceledSubscriptionShouldNotReceiveOnErrorOrOnCompleteSignals() throws Throwable; - /** - * Asks for an empty {@code Publisher} and verifies if {@code onSubscribe} signal was emitted before - * any other {@code onNext}, {@code onError} or {@code onComplete} signal. - *

- * Verifies rule: 1.9 - *

- * Note that this test doesn't request anything, however, an {@code onNext} is not considered as a failure. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • the {@code Publisher.subscribe(Subscriber)} method has actual implementation,
  • - *
  • in the {@code Publisher.subscribe(Subscriber)} method, if there is an upstream {@code Publisher}, - * that {@code Publisher} is actually subscribed to,
  • - *
  • in the {@code Publisher.subscribe(Subscriber)} method, the {@code Subscriber.onSubscribe} is called - * as part of the preparation process (usually before subscribing to other {@code Publisher}s).
  • - *
- */ - void required_spec109_mustIssueOnSubscribeForNonNullSubscriber() throws Throwable; - /** - * Currently, this test is skipped because there is no common agreement on what is to be considered a fatal exception and - * besides, {@code Publisher.subscribe} is only allowed throw a {@code NullPointerException} and any other - * exception would require looking into or hooking into the implementation of the {@code Publisher}. - *

- * Verifies rule: 1.9 - */ - void untested_spec109_subscribeShouldNotThrowNonFatalThrowable() throws Throwable; - /** - * Asks for an empty {@code Publisher} and calls {@code subscribe} on it with {@code null} that should result in - * a {@code NullPointerException} to be thrown. - *

- * Verifies rule: 1.9 - *

- * If this test fails, check if the {@code subscribe()} implementation has an explicit null check (or a method dereference - * on the {@code Subscriber}), especially if the incoming {@code Subscriber} is wrapped or stored to be used later. - */ - void required_spec109_subscribeThrowNPEOnNullSubscriber() throws Throwable; - /** - * Asks for an error {@code Publisher} that should call {@code onSubscribe} exactly once - * followed by a single call to {@code onError()} without receiving any requests. - *

- * Verifies rule: 1.9 - *

- * The test is not executed if {@code PublisherVerification.createErrorPublisher()} returns null. - *

- * The difference between this test and {@link #optional_spec104_mustSignalOnErrorWhenFails()} is that there is - * no explicit verification if exceptions were thrown in addition to the regular {@code onSubscribe+onError} signal pair. - *

- * If this test fails, the following could be checked within the error {@code Publisher} implementation: - *

    - *
  • the {@code Publisher.subscribe(Subscriber)} method has actual implementation,
  • - *
  • in the {@code Publisher.subscribe(Subscriber)} method, if there is an upstream {@code Publisher}, - * that {@code Publisher} is actually subscribed to,
  • - *
  • if the {@code Publisher} implementation is able to emit an {@code onError} without requests,
  • - *
  • if the {@code Publisher} is non-empty as this test expects a {@code Publisher} without items.
  • - *
- */ - void required_spec109_mayRejectCallsToSubscribeIfPublisherIsUnableOrUnwillingToServeThemRejectionMustTriggerOnErrorAfterOnSubscribe() throws Throwable; - /** - * Currently, this test is skipped because enforcing rule §1.10 requires unlimited retention and reference-equal checks on - * all incoming {@code Subscriber} which is generally infeasible, plus reusing the same {@code Subscriber} instance is - * better detected (or ignored) inside {@code Subscriber.onSubscribe} when the method is called multiple times. - *

- * Verifies rule: 1.10 - */ - void untested_spec110_rejectASubscriptionRequestIfTheSameSubscriberSubscribesTwice() throws Throwable; - /** - * Asks for a single-element {@code Publisher} and subscribes to it twice, without consuming with either - * {@code Subscriber} instance - * (i.e., no requests are issued). - *

- * Verifies rule: 1.11 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 1. - *

- * Note that this test ignores what signals the {@code Publisher} emits. Any exception thrown through non-regular - * means will indicate a skipped test. - */ - void optional_spec111_maySupportMultiSubscribe() throws Throwable; - /** - * Asks for a single-element {@code Publisher} and subscribes to it twice. - * Each {@code Subscriber} requests for 1 element and checks if onNext or onComplete signals was received. - *

- * Verifies rule: 1.11, - * and depends on valid implementation of rule 1.5 - * in order to verify this. - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 1. - *

- * Any exception thrown through non-regular means will indicate a skipped test. - */ - void optional_spec111_registeredSubscribersMustReceiveOnNextOrOnCompleteSignals() throws Throwable; - /** - * Asks for a short {@code Publisher} (length 5), subscribes 3 {@code Subscriber}s to it, requests with different - * patterns and checks if all 3 received the same events in the same order. - *

- * Verifies rule: 1.11 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 5. - *

- * The request pattern for the first {@code Subscriber} is (1, 1, 2, 1); for the second is (2, 3) and for the third is (3, 1, 1). - *

- * Note that this test requires a {@code Publisher} that always emits the same signals to any {@code Subscriber}, regardless of - * when they subscribe and how they request elements. I.e., a "live" {@code Publisher} emitting the current time would not pass this test. - *

- * Note that this test is optional and may appear skipped even if the behavior should be actually supported by the {@code Publisher}, - * see the skip message for an indication of this. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • if the {@code Publisher} implementation considers the cumulative request amount it receives,
  • - *
  • if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.
  • - *
- */ - void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingOneByOne() throws Throwable; - /** - * Asks for a short {@code Publisher} (length 3), subscribes 3 {@code Subscriber}s to it, requests more than the length items - * upfront with each and verifies they all received the same items in the same order (but does not verify they all complete). - *

- * Verifies rule: 1.11 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. - *

- * Note that this test requires a {@code Publisher} that always emits the same signals to any {@code Subscriber}, regardless of - * when they subscribe and how they request elements. I.e., a "live" {@code Publisher} emitting the current time would not pass this test. - *

- * Note that this test is optional and may appear skipped even if the behavior should be actually supported by the {@code Publisher}, - * see the skip message for an indication of this. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • if the {@code Publisher} implementation considers the cumulative request amount it receives,
  • - *
  • if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.
  • - *
- */ - void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfront() throws Throwable; - /** - * Asks for a short {@code Publisher} (length 3), subscribes 3 {@code Subscriber}s to it, requests more than the length items - * upfront with each and verifies they all received the same items in the same order followed by an {@code onComplete} signal. - *

- * Verifies rule: 1.11 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. - *

- * Note that this test requires a {@code Publisher} that always emits the same signals to any {@code Subscriber}, regardless of - * when they subscribe and how they request elements. I.e., a "live" {@code Publisher} emitting the current time would not pass this test. - *

- * Note that this test is optional and may appear skipped even if the behavior should be actually supported by the {@code Publisher}, - * see the skip message for an indication of this. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • if the {@code Publisher} implementation considers the cumulative request amount it receives,
  • - *
  • if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.
  • - *
- */ - void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfrontAndCompleteAsExpected() throws Throwable; - /** - * Asks for a short {@code Publisher} (length 6), requests several times from within {@code onSubscribe} and then requests - * one-by-one from {@code onNext}. - *

- * Verifies rule: 3.2 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 6. - *

- * The request pattern is 3 x 1 from within {@code onSubscribe} and one from within each {@code onNext} invocation. - *

- * The test consumes the {@code Publisher} but otherwise doesn't verify the {@code Publisher} completes (however, it checks - * for errors). - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • if the {@code Publisher} implementation considers the cumulative request amount it receives,
  • - *
  • if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.
  • - *
- */ - void required_spec302_mustAllowSynchronousRequestCallsFromOnNextAndOnSubscribe() throws Throwable; - /** - * Asks for a {@code Publisher} with length equal to the value returned by {@link #required_validate_boundedDepthOfOnNextAndRequestRecursion()} plus 1, - * calls {@code request(1)} externally and then from within {@code onNext} and checks if the stack depth did not increase beyond the - * amount permitted by {@link #required_validate_boundedDepthOfOnNextAndRequestRecursion()}. - *

- * Verifies rule: 3.3 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than - * {@link #required_validate_boundedDepthOfOnNextAndRequestRecursion()} plus 1. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • the implementation doesn't allow unbounded recursion when {@code request()} is called from within {@code onNext}, i.e., the lack of - * reentrant-safe state machine around the request amount (such as a for loop with a bound on the parameter {@code n} that calls {@code onNext}). - *
- */ - void required_spec303_mustNotAllowUnboundedRecursion() throws Throwable; - /** - * Currently, this test is skipped because a {@code request} could enter into a synchronous computation via {@code onNext} - * legally and otherwise there is no common agreement how to detect such heavy computation reliably. - *

- * Verifies rule: 3.4 - */ - void untested_spec304_requestShouldNotPerformHeavyComputations() throws Exception; - /** - * Currently, this test is skipped because there is no reliable agreed upon way to detect a heavy computation. - *

- * Verifies rule: 3.5 - */ - void untested_spec305_cancelMustNotSynchronouslyPerformHeavyComputation() throws Exception; - /** - * Asks for a short {@code Publisher} (length 3) and verifies that cancelling without requesting anything, then requesting - * items should result in no signals to be emitted. - *

- * Verifies rule: 3.6 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. - *

- * The post-cancellation request pattern is (1, 1, 1). - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • the cancellation indicator flag is properly persisted (may require volatile) and checked as part of the signal emission process.
  • - *
- */ - void required_spec306_afterSubscriptionIsCancelledRequestMustBeNops() throws Throwable; - /** - * Asks for a single-element {@code Publisher} and verifies that without requesting anything, cancelling the sequence - * multiple times should result in no signals to be emitted and should result in an thrown exception. - *

- * Verifies rule: 3.7 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 1. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • the cancellation indicator flag is properly persisted (may require volatile) and checked as part of the signal emission process.
  • - *
- */ - void required_spec307_afterSubscriptionIsCancelledAdditionalCancelationsMustBeNops() throws Throwable; - /** - * Asks for a short {@code Publisher} (length 10) and issues a {@code request(0)} which should trigger an {@code onError} call - * with an {@code IllegalArgumentException}. - *

- * Verifies rule: 3.9 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 10. - *

- * Note that this test expects the {@code IllegalArgumentException} being signalled through {@code onError}, not by - * throwing from {@code request()} (which is also forbidden) or signalling the error by any other means (i.e., through the - * {@code Thread.currentThread().getUncaughtExceptionHandler()} for example). - *

- * Note also that requesting and emission may happen concurrently and honoring this rule may require extra coordination within - * the {@code Publisher}. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • the {@code Publisher} can emit an {@code onError} in this particular case, even if there was no prior and legal - * {@code request} call and even if the {@code Publisher} would like to emit items first before emitting an {@code onError} - * in general. - *
- */ - void required_spec309_requestZeroMustSignalIllegalArgumentException() throws Throwable; - /** - * Asks for a short {@code Publisher} (length 10) and issues a random, negative {@code request()} call which should - * trigger an {@code onError} call with an {@code IllegalArgumentException}. - *

- * Verifies rule: 3.9 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 10. - *

- * Note that this test expects the {@code IllegalArgumentException} being signalled through {@code onError}, not by - * throwing from {@code request()} (which is also forbidden) or signalling the error by any other means (i.e., through the - * {@code Thread.currentThread().getUncaughtExceptionHandler()} for example). - *

- * Note also that requesting and emission may happen concurrently and honoring this rule may require extra coordination within - * the {@code Publisher}. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • the {@code Publisher} can emit an {@code onError} in this particular case, even if there was no prior and legal - * {@code request} call and even if the {@code Publisher} would like to emit items first before emitting an {@code onError} - * in general. - *
- */ - void required_spec309_requestNegativeNumberMustSignalIllegalArgumentException() throws Throwable; - /** - * Asks for a short {@code Publisher} (length 10) and issues a random, negative {@code request()} call which should - * trigger an {@code onError} call with an {@code IllegalArgumentException}. - *

- * Verifies rule: 3.9 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 10. - *

- * Note that this test expects the {@code IllegalArgumentException} being signalled through {@code onError}, not by - * throwing from {@code request()} (which is also forbidden) or signalling the error by any other means (i.e., through the - * {@code Thread.currentThread().getUncaughtExceptionHandler()} for example). - *

- * Note also that requesting and emission may happen concurrently and honoring this rule may require extra coordination within - * the {@code Publisher}. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • the {@code Publisher} can emit an {@code onError} in this particular case, even if there was no prior and legal - * {@code request} call and even if the {@code Publisher} would like to emit items first before emitting an {@code onError} - * in general. - *
- */ - void optional_spec309_requestNegativeNumberMaySignalIllegalArgumentExceptionWithSpecificMessage() throws Throwable; - /** - * Asks for a short {@code Publisher} (length 20), requests some items (less than the length), consumes one item then - * cancels the sequence and verifies the publisher emitted at most the requested amount and stopped emitting (or terminated). - *

- * Verifies rule: 3.12 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 20. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • the cancellation indicator flag is properly persisted (may require volatile) and checked as part of the signal emission process.
  • - *
- */ - void required_spec312_cancelMustMakeThePublisherToEventuallyStopSignaling() throws Throwable; - /** - * Asks for a short {@code Publisher} (length 3) requests and consumes one element from it, cancels the {@code Subscription} - * , calls {@code System.gc()} and then checks if all references to the test {@code Subscriber} has been dropped (by checking - * the {@code WeakReference} has been emptied). - *

- * Verifies rule: 3.13 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • the cancellation indicator flag is properly persisted (may require volatile) and checked as part of the signal emission process.
  • - *
  • the {@code Publisher} stores the {@code Subscriber} reference somewhere which is then not cleaned up when the {@code Subscriber} is cancelled. - * Note that this may happen on many code paths in a {@code Publisher}, for example in an emission loop that terminates because of the - * {@code cancel} signal or because reaching a terminal state. Note also that eagerly nulling {@code Subscriber} references may not be necessary - * for this test to pass in case there is a self-contained chain of them (i.e., {@code Publisher.subscribe()} creates a chain of fresh - * {@code Subscriber} instances where each of them only references their downstream {@code Subscriber} thus the chain can get GC'd - * when the reference to the final {@code Subscriber} is dropped). - *
- */ - void required_spec313_cancelMustMakeThePublisherEventuallyDropAllReferencesToTheSubscriber() throws Throwable; - /** - * Asks for a short {@code Publisher} (length 3) and requests {@code Long.MAX_VALUE} from it, verifying that the - * {@code Publisher} emits all of its items and completes normally - * and does not keep spinning attempting to fulfill the {@code Long.MAX_VALUE} demand by some means. - *

- * Verifies rule: 3.17 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • if the {@code Publisher} implementation considers the cumulative request amount it receives,
  • - *
  • if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.
  • - *
- */ - void required_spec317_mustSupportAPendingElementCountUpToLongMaxValue() throws Throwable; - /** - * Asks for a short {@code Publisher} (length 3) and requests {@code Long.MAX_VALUE} from it in total (split across - * two {@code Long.MAX_VALUE / 2} and one {@code request(1)}), verifying that the - * {@code Publisher} emits all of its items and completes normally. - *

- * Verifies rule: 3.17 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • if the {@code Publisher} implementation considers the cumulative request amount it receives,
  • - *
  • if the {@code Publisher} implements adding individual request amounts together properly (not overflowing into zero or negative pending request amounts) - * or not properly deducing the number of emitted items from the pending amount,
  • - *
  • if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.
  • - *
- */ - void required_spec317_mustSupportACumulativePendingElementCountUpToLongMaxValue() throws Throwable; - /** - * Asks for a very long {@code Publisher} (up to {@code Integer.MAX_VALUE}), requests {@code Long.MAX_VALUE - 1} after - * each received item and expects no failure due to a potential overflow in the pending emission count while consuming - * 10 items and cancelling the sequence. - *

- * Verifies rule: 3.17 - *

- * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than {@code Integer.MAX_VALUE}. - *

- * The request pattern is one {@code request(1)} upfront and ten {@code request(Long.MAX_VALUE - 1)} after. - *

- * If this test fails, the following could be checked within the {@code Publisher} implementation: - *

    - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,
  • - *
  • make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,
  • - *
  • if the {@code Publisher} implementation considers the cumulative request amount it receives,
  • - *
  • if the {@code Publisher} implements adding individual request amounts together properly (not overflowing into zero or negative pending request amounts) - * or not properly deducing the number of emitted items from the pending amount,
  • - *
  • if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.
  • - *
- */ - void required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue() throws Throwable; -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/SubscriberBlackboxVerificationRules.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/SubscriberBlackboxVerificationRules.java deleted file mode 100644 index 6526e238621..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/SubscriberBlackboxVerificationRules.java +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.flow.support; - -import org.reactivestreams.tck.SubscriberBlackboxVerification; - -/** - * Internal TCK use only. - * Add / Remove tests for SubscriberBlackboxVerification here to make sure that they arre added/removed in the other places. - */ -public interface SubscriberBlackboxVerificationRules { - /** - * Asks for a {@code Subscriber} instance, expects it to call {@code request()} in - * a timely manner and signals as many {@code onNext} items as the very first request - * amount specified by the {@code Subscriber}. - *

- * Verifies rule: 2.1 - *

- * Notes: - *

    - *
  • This test emits the number of items requested thus the {@code Subscriber} implementation - * should not request too much.
  • - *
  • Only the very first {@code request} amount is considered.
  • - *
  • This test doesn't signal {@code onComplete} after the first set of {@code onNext} signals - * has been emitted and may cause resource leak in - * {@code Subscriber}s that expect a finite {@code Publisher}.
  • - *
  • The test ignores cancellation from the {@code Subscriber} and emits the requested amount regardless.
  • - *
- *

- * If this test fails, the following could be checked within the {@code Subscriber} implementation: - *

    - *
  • if the {@code Subscriber} requires external stimulus to begin requesting; override the - * {@link SubscriberBlackboxVerification#triggerRequest(org.reactivestreams.Subscriber)} method - * in this case,
  • - *
  • the {@code TestEnvironment} has large enough timeout specified in case the {@code Subscriber} has some time-delay behavior,
  • - *
  • if the {@code Subscriber} requests zero or a negative value in some circumstances,
  • - *
  • if the {@code Subscriber} throws an unchecked exception from its {@code onSubscribe} or - * {@code onNext} methods. - *
- */ - void required_spec201_blackbox_mustSignalDemandViaSubscriptionRequest() throws Throwable; - /** - * Currently, this test is skipped because there is no agreed upon approach how - * to detect if the {@code Subscriber} really goes async or just responds in - * a timely manner. - *

- * Verifies rule: 2.2 - */ - void untested_spec202_blackbox_shouldAsynchronouslyDispatch() throws Exception; - /** - * Asks for a {@code Subscriber}, signals an {@code onSubscribe} followed by an {@code onComplete} synchronously, - * and checks if neither {@code request} nor {@code cancel} was called from within the {@code Subscriber}'s - * {@code onComplete} implementation. - *

- * Verifies rule: 2.3 - *

- * Notes: - *

    - *
  • The test checks for the presensce of method named "onComplete" in the current stacktrace when handling - * the {@code request} or {@code cancel} calls in the test's own {@code Subscription}. - *
- *

- * If this test fails, the following could be checked within the {@code Subscriber} implementation: - *

    - *
  • no calls happen to {@code request} or {@code cancel} in response to an {@code onComplete} - * directly or indirectly,
  • - *
  • if the {@code Subscriber} throws an unchecked exception from its {@code onSubscribe} or - * {@code onComplete} methods. - *
- */ - void required_spec203_blackbox_mustNotCallMethodsOnSubscriptionOrPublisherInOnComplete() throws Throwable; - /** - * Asks for a {@code Subscriber}, signals an {@code onSubscribe} followed by an {@code onError} synchronously, - * and checks if neither {@code request} nor {@code cancel} was called from within the {@code Subscriber}'s - * {@code onComplete} implementation. - *

- * Verifies rule: 2.3 - *

- * Notes: - *

    - *
  • The test checks for the presensce of method named "onError" in the current stacktrace when handling - * the {@code request} or {@code cancel} calls in the test's own {@code Subscription}. - *
- *

- * If this test fails, the following could be checked within the {@code Subscriber} implementation: - *

    - *
  • no calls happen to {@code request} or {@code cancel} in response to an {@code onError} - * directly or indirectly,
  • - *
  • if the {@code Subscriber} throws an unchecked exception from its {@code onSubscribe} or - * {@code onError} methods. - *
- */ - void required_spec203_blackbox_mustNotCallMethodsOnSubscriptionOrPublisherInOnError() throws Throwable; - /** - * Currently, this test is skipped because there is no way to check what the {@code Subscriber} "considers" - * since rule §2.3 forbids interaction from within the {@code onError} and {@code onComplete} methods. - *

- * Verifies rule: 2.4 - *

- * Notes: - *

    - *
  • It would be possible to check if there was an async interaction with the test's {@code Subscription} - * within a grace period but such check is still not generally decisive.
  • - *
- */ - void untested_spec204_blackbox_mustConsiderTheSubscriptionAsCancelledInAfterRecievingOnCompleteOrOnError() throws Exception; - /** - * Asks for a {@code Subscriber}, signals {@code onSubscribe} twice synchronously and expects the second {@code Subscription} gets - * cancelled in a timely manner and without any calls to its {@code request} method. - *

- * Verifies rule: 2.5 - *

- * Notes: - *

    - *
  • The test doesn't signal any other events than {@code onSubscribe} and may cause resource leak in - * {@code Subscriber}s that expect a finite {@code Publisher}. - *
- *

- * If this test fails, the following could be checked within the {@code Subscriber} implementation: - *

    - *
  • if the {@code Subscribe.onSubscribe} implementation actually tries to detect multiple calls to it,
  • - *
  • if the second {@code Subscription} is cancelled asynchronously and that takes longer time than - * the {@code TestEnvironment}'s timeout permits.
  • - *
- */ - void required_spec205_blackbox_mustCallSubscriptionCancelIfItAlreadyHasAnSubscriptionAndReceivesAnotherOnSubscribeSignal() throws Exception; - - /** - * Currently, this test is skipped because it requires more control over the {@code Subscriber} implementation - * to make it cancel the {@code Subscription} for some external condition. - *

- * Verifies rule: 2.6 - */ - void untested_spec206_blackbox_mustCallSubscriptionCancelIfItIsNoLongerValid() throws Exception; - /** - * Currently, this test is skipped because it requires more control over the {@code Subscriber} implementation - * to issue requests based on external stimulus. - *

- * Verifies rule: 2.7 - */ - void untested_spec207_blackbox_mustEnsureAllCallsOnItsSubscriptionTakePlaceFromTheSameThreadOrTakeCareOfSynchronization() throws Exception; - /** - * Currently, this test is skipped because there is no way to make the {@code Subscriber} implementation - * cancel the test's {@code Subscription} and check the outcome of sending {@code onNext}s after such - * cancel. - *

- * Verifies rule: 2.8 - */ - void untested_spec208_blackbox_mustBePreparedToReceiveOnNextSignalsAfterHavingCalledSubscriptionCancel() throws Throwable; - /** - * Asks for a {@code Subscriber}, expects it to request some amount and in turn be able to receive an {@code onComplete} - * synchronously from the {@code request} call without any {@code onNext} signals before that. - *

- * Verifies rule: 2.9 - *

- * Notes: - *

    - *
  • The test ignores cancellation from the {@code Subscriber}.
  • - *
  • Invalid request amounts are ignored by this test.
  • - *
  • Concurrent calls to the test's {@code Subscription.request()} must be externally synchronized, otherwise - * such case results probabilistically in multiple {@code onComplete} calls by the test.
  • - *
- *

- * If this test fails, the following could be checked within the {@code Subscriber} implementation: - *

    - *
  • if the {@code Subscriber} throws an unchecked exception from its {@code onSubscribe} or - * {@code onComplete} methods. - *
  • if the {@code Subscriber} requires external stimulus to begin requesting; override the - * {@link SubscriberBlackboxVerification#triggerRequest(org.reactivestreams.Subscriber)} method - * in this case,
  • - *
- */ - void required_spec209_blackbox_mustBePreparedToReceiveAnOnCompleteSignalWithPrecedingRequestCall() throws Throwable; - /** - * Asks for a {@code Subscriber} and expects it to handle {@code onComplete} independent of whether the {@code Subscriber} - * requests items or not. - *

- * Verifies rule: 2.9 - *

- * Notes: - *

    - *
  • Currently, the test doesn't call {@code onSubscribe} on the {@code Subscriber} which violates §1.9. - *
- *

- * If this test fails, the following could be checked within the {@code Subscriber} implementation: - *

    - *
  • if the {@code Subscriber} throws an unchecked exception from its {@code onSubscribe} or - * {@code onComplete} methods. - *
- */ - void required_spec209_blackbox_mustBePreparedToReceiveAnOnCompleteSignalWithoutPrecedingRequestCall() throws Throwable; - /** - * Asks for a {@code Subscriber}, signals {@code onSubscribe} followed by an {@code onError} synchronously. - *

- * Verifies rule: 2.10 - *

- * Notes: - *

    - *
  • Despite the method name, the test doesn't expect a request signal from {@code Subscriber} and emits the - * {@code onError} signal anyway. - *
- *

- * If this test fails, the following could be checked within the {@code Subscriber} implementation: - *

    - *
  • if the {@code Subscriber} throws an unchecked exception from its {@code onSubscribe} or - * {@code onError} methods. - *
- */ - void required_spec210_blackbox_mustBePreparedToReceiveAnOnErrorSignalWithPrecedingRequestCall() throws Throwable; - - /** - * Asks for a {@code Subscriber}, signals {@code onSubscribe} followed by an {@code onError} synchronously. - *

- * Verifies rule: 2.10 - *

- * If this test fails, the following could be checked within the {@code Subscriber} implementation: - *

    - *
  • if the {@code Subscriber} throws an unchecked exception from its {@code onSubscribe} or - * {@code onError} methods. - *
- */ - void required_spec210_blackbox_mustBePreparedToReceiveAnOnErrorSignalWithoutPrecedingRequestCall() throws Throwable; - - /** - * Currently, this test is skipped because it would require analyzing what the {@code Subscriber} implementation - * does. - *

- * Verifies rule: 2.11 - */ - void untested_spec211_blackbox_mustMakeSureThatAllCallsOnItsMethodsHappenBeforeTheProcessingOfTheRespectiveEvents() throws Exception; - /** - * Currently, this test is skipped because the test for - * {@link #required_spec205_blackbox_mustCallSubscriptionCancelIfItAlreadyHasAnSubscriptionAndReceivesAnotherOnSubscribeSignal §2.5} - * is in a better position to test for handling the reuse of the same {@code Subscriber}. - *

- * Verifies rule: 2.12 - *

- * Notes: - *

    - *
  • In addition to §2.5, this rule could be better verified when testing a {@code Publisher}'s subscription behavior. - *
- */ - void untested_spec212_blackbox_mustNotCallOnSubscribeMoreThanOnceBasedOnObjectEquality() throws Throwable; - /** - * Currently, this test is skipped because it would require more control over the {@code Subscriber} to - * fail internally in response to a set of legal event emissions, not throw any exception from the {@code Subscriber} - * methods and have it cancel the {@code Subscription}. - *

- * Verifies rule: 2.13 - */ - void untested_spec213_blackbox_failingOnSignalInvocation() throws Exception; - /** - * Asks for a {@code Subscriber} and signals an {@code onSubscribe} event with {@code null} as a parameter and - * expects an immediate {@code NullPointerException} to be thrown by the {@code Subscriber.onSubscribe} method. - *

- * Verifies rule: 2.13 - *

- * If this test fails, the following could be checked within the {@code Subscriber} implementation: - *

    - *
  • if the {@code Subscriber} throws a {@code NullPointerException} from its {@code onSubscribe} method - * in response to a {@code null} parameter and not some other unchecked exception or no exception at all. - *
- */ - void required_spec213_blackbox_onSubscribe_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable; - /** - * Asks for a {@code Subscriber}, signals an {@code onSubscribe} event followed by a - * {@code onNext} with {@code null} as a parameter and - * expects an immediate {@code NullPointerException} to be thrown by the {@code Subscriber.onNext} method. - *

- * Verifies rule: 2.13 - *

- * Notes: - *

    - *
  • The test ignores cancellation and requests from the {@code Subscriber} and emits the {@code onNext} - * signal with a {@code null} parameter anyway.
  • - *
- *

- * If this test fails, the following could be checked within the {@code Subscriber} implementation: - *

    - *
  • if the {@code Subscriber} throws a {@code NullPointerException} from its {@code onNext} method - * in response to a {@code null} parameter and not some other unchecked exception or no exception at all. - *
- */ - void required_spec213_blackbox_onNext_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable; - /** - * Asks for a {@code Subscriber}, signals an {@code onSubscribe} event followed by a - * {@code onError} with {@code null} as a parameter and - * expects an immediate {@code NullPointerException} to be thrown by the {@code Subscriber.onError} method. - *

- * Verifies rule: 2.13 - *

- * Notes: - *

    - *
  • The test ignores cancellation from the {@code Subscriber} and emits the {@code onError} - * signal with a {@code null} parameter anyway.
  • - *
- *

- * If this test fails, the following could be checked within the {@code Subscriber} implementation: - *

    - *
  • if the {@code Subscriber} throws a {@code NullPointerException} from its {@code onNext} method - * in response to a {@code null} parameter and not some other unchecked exception or no exception at all. - *
- */ - void required_spec213_blackbox_onError_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable; - /** - * Currently, this test is skipped because there is no agreed upon way for specifying, enforcing and testing - * a {@code Subscriber} with an arbitrary context. - *

- * Verifies rule: 3.1 - */ - void untested_spec301_blackbox_mustNotBeCalledOutsideSubscriberContext() throws Exception; - /** - * Currently, this test is skipped because element production is the responsibility of the {@code Publisher} and - * a {@code Subscription} is not expected to be the active element in an established subscription. - *

- * Verifies rule: 3.8 - */ - void untested_spec308_blackbox_requestMustRegisterGivenNumberElementsToBeProduced() throws Throwable; - /** - * Currently, this test is skipped because element production is the responsibility of the {@code Publisher} and - * a {@code Subscription} is not expected to be the active element in an established subscription. - *

- * Verifies rule: 3.10 - *

- * Notes: - *

    - *
  • This could be tested with a synchronous source currently not available within the TCK.
  • - *
- */ - void untested_spec310_blackbox_requestMaySynchronouslyCallOnNextOnSubscriber() throws Exception; - /** - * Currently, this test is skipped because signal production is the responsibility of the {@code Publisher} and - * a {@code Subscription} is not expected to be the active element in an established subscription. - *

- * Verifies rule: 3.11 - *

- * Notes: - *

    - *
  • Tests {@link #required_spec209_blackbox_mustBePreparedToReceiveAnOnCompleteSignalWithPrecedingRequestCall() §2.9} - * and {@link #required_spec210_blackbox_mustBePreparedToReceiveAnOnErrorSignalWithPrecedingRequestCall() §2.10} are - * supposed to cover this case from the {@code Subscriber's} perspective.
  • - *
- */ - void untested_spec311_blackbox_requestMaySynchronouslyCallOnCompleteOrOnError() throws Exception; - /** - * Currently, this test is skipped because it is the responsibility of the {@code Publisher} deal with the case - * that all subscribers have cancelled their subscription. - *

- * Verifies rule: 3.14 - *

- * Notes: - *

    - *
  • The specification lists this as an optional behavior because only some {@code Publisher} implementations - * (most likely {@code Processor}s) would coordinate with multiple {@code Subscriber}s.
  • - *
- */ - void untested_spec314_blackbox_cancelMayCauseThePublisherToShutdownIfNoOtherSubscriptionExists() throws Exception; - /** - * Currently, this test is skipped because it requires more control over the {@code Subscriber} implementation - * thus there is no way to detect that the {@code Subscriber} called its own {@code onError} method in response - * to an exception thrown from {@code Subscription.cancel}. - *

- * Verifies rule: 3.15 - */ - void untested_spec315_blackbox_cancelMustNotThrowExceptionAndMustSignalOnError() throws Exception; - /** - * Currently, this test is skipped because it requires more control over the {@code Subscriber} implementation - * thus there is no way to detect that the {@code Subscriber} called its own {@code onError} method in response - * to an exception thrown from {@code Subscription.request}. - *

- * Verifies rule: 3.16 - */ - void untested_spec316_blackbox_requestMustNotThrowExceptionAndMustOnErrorTheSubscriber() throws Exception; -} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/SubscriberWhiteboxVerificationRules.java b/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/SubscriberWhiteboxVerificationRules.java deleted file mode 100644 index e8f1e835a06..00000000000 --- a/test/jdk/java/net/httpclient/reactivestreams-tck/org/reactivestreams/tck/flow/support/SubscriberWhiteboxVerificationRules.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2019, 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 org.reactivestreams.tck.flow.support; - -/** - * Internal TCK use only. - * Add / Remove tests for PublisherVerificaSubscriberWhiteboxVerification here to make sure that they arre added/removed in the other places. - */ -public interface SubscriberWhiteboxVerificationRules { - void required_exerciseWhiteboxHappyPath() throws Throwable; - void required_spec201_mustSignalDemandViaSubscriptionRequest() throws Throwable; - void untested_spec202_shouldAsynchronouslyDispatch() throws Exception; - void required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnComplete() throws Throwable; - void required_spec203_mustNotCallMethodsOnSubscriptionOrPublisherInOnError() throws Throwable; - void untested_spec204_mustConsiderTheSubscriptionAsCancelledInAfterRecievingOnCompleteOrOnError() throws Exception; - void required_spec205_mustCallSubscriptionCancelIfItAlreadyHasAnSubscriptionAndReceivesAnotherOnSubscribeSignal() throws Throwable; - void untested_spec206_mustCallSubscriptionCancelIfItIsNoLongerValid() throws Exception; - void untested_spec207_mustEnsureAllCallsOnItsSubscriptionTakePlaceFromTheSameThreadOrTakeCareOfSynchronization() throws Exception; - void required_spec208_mustBePreparedToReceiveOnNextSignalsAfterHavingCalledSubscriptionCancel() throws Throwable; - void required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithPrecedingRequestCall() throws Throwable; - void required_spec209_mustBePreparedToReceiveAnOnCompleteSignalWithoutPrecedingRequestCall() throws Throwable; - void required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithPrecedingRequestCall() throws Throwable; - void required_spec210_mustBePreparedToReceiveAnOnErrorSignalWithoutPrecedingRequestCall() throws Throwable; - void untested_spec211_mustMakeSureThatAllCallsOnItsMethodsHappenBeforeTheProcessingOfTheRespectiveEvents() throws Exception; - void untested_spec212_mustNotCallOnSubscribeMoreThanOnceBasedOnObjectEquality_specViolation() throws Throwable; - void untested_spec213_failingOnSignalInvocation() throws Exception; - void required_spec213_onSubscribe_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable; - void required_spec213_onNext_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable; - void required_spec213_onError_mustThrowNullPointerExceptionWhenParametersAreNull() throws Throwable; - void untested_spec301_mustNotBeCalledOutsideSubscriberContext() throws Exception; - void required_spec308_requestMustRegisterGivenNumberElementsToBeProduced() throws Throwable; - void untested_spec310_requestMaySynchronouslyCallOnNextOnSubscriber() throws Exception; - void untested_spec311_requestMaySynchronouslyCallOnCompleteOrOnError() throws Exception; - void untested_spec314_cancelMayCauseThePublisherToShutdownIfNoOtherSubscriptionExists() throws Exception; - void untested_spec315_cancelMustNotThrowExceptionAndMustSignalOnError() throws Exception; - void untested_spec316_requestMustNotThrowExceptionAndMustOnErrorTheSubscriber() throws Exception; -} diff --git a/test/jdk/java/net/httpclient/security/0.policy b/test/jdk/java/net/httpclient/security/0.policy index 32a1e54da52..2e2b4588168 100644 --- a/test/jdk/java/net/httpclient/security/0.policy +++ b/test/jdk/java/net/httpclient/security/0.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -29,7 +29,8 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; @@ -39,8 +40,8 @@ grant { // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/1.policy b/test/jdk/java/net/httpclient/security/1.policy index 3c5d96da67d..ee9e021c50e 100644 --- a/test/jdk/java/net/httpclient/security/1.policy +++ b/test/jdk/java/net/httpclient/security/1.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -28,17 +28,19 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:${port.number}/files/foo.txt", "GET"; + permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET"; + permission java.net.URLPermission "http://[::1]:${port.number}/files/foo.txt", "GET"; }; // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/10.policy b/test/jdk/java/net/httpclient/security/10.policy index f131a44dcfd..a83bf44153c 100644 --- a/test/jdk/java/net/httpclient/security/10.policy +++ b/test/jdk/java/net/httpclient/security/10.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -28,16 +28,18 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:${port.number}/files/foo.txt", "GET:*"; + permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET:*"; + permission java.net.URLPermission "http://[::1]:${port.number}/files/foo.txt", "GET:*"; }; // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/11.policy b/test/jdk/java/net/httpclient/security/11.policy index 51fee36bc17..f75fdcc7dfd 100644 --- a/test/jdk/java/net/httpclient/security/11.policy +++ b/test/jdk/java/net/httpclient/security/11.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -28,18 +28,26 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:${port.number}/files/foo.txt", "GET:*"; + permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET:*"; + permission java.net.URLPermission "socket://127.0.0.1:${port.number1}", "CONNECT"; + // ipv6 + permission java.net.URLPermission "http://[::1]:${port.number}/files/foo.txt", "GET:*"; + permission java.net.URLPermission "socket://[::1]:${port.number1}", "CONNECT"; + // this specific test uses a proxy configured to loopback address. the httpclient implementation + // during permissions check uses the InetAddress.hostString() API which can return resolved + // hostname, so we use include a permission for "localhost" to cover that case too permission java.net.URLPermission "socket://localhost:${port.number1}", "CONNECT"; }; // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/12.policy b/test/jdk/java/net/httpclient/security/12.policy index 51fee36bc17..f75fdcc7dfd 100644 --- a/test/jdk/java/net/httpclient/security/12.policy +++ b/test/jdk/java/net/httpclient/security/12.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -28,18 +28,26 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:${port.number}/files/foo.txt", "GET:*"; + permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET:*"; + permission java.net.URLPermission "socket://127.0.0.1:${port.number1}", "CONNECT"; + // ipv6 + permission java.net.URLPermission "http://[::1]:${port.number}/files/foo.txt", "GET:*"; + permission java.net.URLPermission "socket://[::1]:${port.number1}", "CONNECT"; + // this specific test uses a proxy configured to loopback address. the httpclient implementation + // during permissions check uses the InetAddress.hostString() API which can return resolved + // hostname, so we use include a permission for "localhost" to cover that case too permission java.net.URLPermission "socket://localhost:${port.number1}", "CONNECT"; }; // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/14.policy b/test/jdk/java/net/httpclient/security/14.policy index 0a6562b2691..39bdbea6654 100644 --- a/test/jdk/java/net/httpclient/security/14.policy +++ b/test/jdk/java/net/httpclient/security/14.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -28,17 +28,19 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:*/files/foo.txt", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET"; + permission java.net.URLPermission "http://[::1]:*/files/foo.txt", "GET"; }; // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/15.policy b/test/jdk/java/net/httpclient/security/15.policy index 6fa7a0d4a17..ba6b9feb363 100644 --- a/test/jdk/java/net/httpclient/security/15.policy +++ b/test/jdk/java/net/httpclient/security/15.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -28,12 +28,14 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:*/files/foo.txt", "GET:*"; + permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET:*"; + permission java.net.URLPermission "http://[::1]:*/files/foo.txt", "GET:*"; // Test checks for this explicitly permission java.lang.RuntimePermission "foobar"; @@ -42,6 +44,6 @@ grant { // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/16.policy b/test/jdk/java/net/httpclient/security/16.policy index 5d9939fa00c..7d755cfff94 100644 --- a/test/jdk/java/net/httpclient/security/16.policy +++ b/test/jdk/java/net/httpclient/security/16.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -29,17 +29,19 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:${port.number}/files/foo.txt", "GET:Host"; + permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET:Host"; + permission java.net.URLPermission "http://[::1]:${port.number}/files/foo.txt", "GET:Host"; }; // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/17.policy b/test/jdk/java/net/httpclient/security/17.policy index ae26c857b02..92ee7f3d609 100644 --- a/test/jdk/java/net/httpclient/security/17.policy +++ b/test/jdk/java/net/httpclient/security/17.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -28,18 +28,20 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:${port.number}/files/foo.txt", "GET:Host"; + permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET:Host"; + permission java.net.URLPermission "http://[::1]:${port.number}/files/foo.txt", "GET:Host"; permission java.net.URLPermission "http://foohost:123/files/foo.txt", "GET:Host"; }; // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/2.policy b/test/jdk/java/net/httpclient/security/2.policy index 4d7f859556b..b69c589ee68 100644 --- a/test/jdk/java/net/httpclient/security/2.policy +++ b/test/jdk/java/net/httpclient/security/2.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -28,17 +28,19 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:*/files/*", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/files/*", "GET"; + permission java.net.URLPermission "http://[::1]:*/files/*", "GET"; }; // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/3.policy b/test/jdk/java/net/httpclient/security/3.policy index 81837843368..32383fe88d3 100644 --- a/test/jdk/java/net/httpclient/security/3.policy +++ b/test/jdk/java/net/httpclient/security/3.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -28,17 +28,19 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:*/redirect/foo.txt", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/redirect/foo.txt", "GET"; + permission java.net.URLPermission "http://[::1]:*/redirect/foo.txt", "GET"; }; // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/4.policy b/test/jdk/java/net/httpclient/security/4.policy index 5ea9284a4f1..7973c76d981 100644 --- a/test/jdk/java/net/httpclient/security/4.policy +++ b/test/jdk/java/net/httpclient/security/4.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -28,18 +28,22 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:*/redirect/foo.txt", "GET"; - permission java.net.URLPermission "http://localhost:*/redirect/bar.txt", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/redirect/foo.txt", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/redirect/bar.txt", "GET"; + // ipv6 + permission java.net.URLPermission "http://[::1]:*/redirect/foo.txt", "GET"; + permission java.net.URLPermission "http://[::1]:*/redirect/bar.txt", "GET"; }; // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/5.policy b/test/jdk/java/net/httpclient/security/5.policy index b20917a9444..0b480f95234 100644 --- a/test/jdk/java/net/httpclient/security/5.policy +++ b/test/jdk/java/net/httpclient/security/5.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -28,17 +28,19 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:*/redirect/bar.txt", "GET"; + permission java.net.URLPermission "http://127.0.0.1:*/redirect/bar.txt", "GET"; + permission java.net.URLPermission "http://[::1]:*/redirect/bar.txt", "GET"; }; // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/6.policy b/test/jdk/java/net/httpclient/security/6.policy index f535b51ec20..80d2838bebe 100644 --- a/test/jdk/java/net/httpclient/security/6.policy +++ b/test/jdk/java/net/httpclient/security/6.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -28,17 +28,19 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:*/files/foo.txt", "POST"; + permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "POST"; + permission java.net.URLPermission "http://[::1]:*/files/foo.txt", "POST"; }; // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/7.policy b/test/jdk/java/net/httpclient/security/7.policy index 29564ef73a1..8fddf36c66e 100644 --- a/test/jdk/java/net/httpclient/security/7.policy +++ b/test/jdk/java/net/httpclient/security/7.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -28,17 +28,20 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:*/files/foo.txt", "GET:X-Bar"; + permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET:X-Bar"; + permission java.net.URLPermission "http://[::1]:*/files/foo.txt", "GET:X-Bar"; + }; // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/8.policy b/test/jdk/java/net/httpclient/security/8.policy index 7a2cd1b4904..4bc507b3e31 100644 --- a/test/jdk/java/net/httpclient/security/8.policy +++ b/test/jdk/java/net/httpclient/security/8.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -28,17 +28,19 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:*/files/foo.txt", "GET:X-Foo1,X-Foo,X-Bar"; + permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET:X-Foo1,X-Foo,X-Bar"; + permission java.net.URLPermission "http://[::1]:*/files/foo.txt", "GET:X-Foo1,X-Foo,X-Bar"; }; // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/9.policy b/test/jdk/java/net/httpclient/security/9.policy index 79cdee73b73..ce7336c2975 100644 --- a/test/jdk/java/net/httpclient/security/9.policy +++ b/test/jdk/java/net/httpclient/security/9.policy @@ -1,5 +1,5 @@ // -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2023, 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 @@ -28,17 +28,19 @@ grant { permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete"; permission java.lang.RuntimePermission "modifyThread"; permission java.util.logging.LoggingPermission "control", ""; - permission java.net.SocketPermission "localhost:1024-", "accept,listen"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen"; permission java.io.FilePermission "${test.src}${/}docs${/}-", "read"; permission java.lang.RuntimePermission "createClassLoader"; // permissions specific to this test - permission java.net.URLPermission "http://localhost:*/files/foo.txt", "GET:*"; + permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET:*"; + permission java.net.URLPermission "http://[::1]:*/files/foo.txt", "GET:*"; }; // For proxy only. Not being tested grant codebase "file:${test.classes}/proxydir/-" { - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect"; - permission java.net.SocketPermission "localhost:1024-", "connect,resolve"; + permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; + permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; }; diff --git a/test/jdk/java/net/httpclient/security/Security.java b/test/jdk/java/net/httpclient/security/Security.java index fc2fcd1503e..5e6566dcd82 100644 --- a/test/jdk/java/net/httpclient/security/Security.java +++ b/test/jdk/java/net/httpclient/security/Security.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -103,6 +103,7 @@ public class Security { static String httproot, fileuri, fileroot, redirectroot; static List clients = new LinkedList<>(); static URI uri; + static String serverAuthority; interface ThrowingRunnable { void run() throws Throwable; } @@ -201,56 +202,56 @@ static TestAndResult[] createTests() { return new TestAndResult[] { // (0) policy does not have permission for file. Should fail TestAndResult.of(true, () -> { // Policy 0 - URI u = URI.create("http://localhost:" + port + "/files/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/files/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u).GET().build(); HttpResponse response = client.send(request, ofString()); System.out.println("Received response:" + response); }), // (1) policy has permission for file URL TestAndResult.of(false, () -> { //Policy 1 - URI u = URI.create("http://localhost:" + port + "/files/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/files/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u).GET().build(); HttpResponse response = client.send(request, ofString()); System.out.println("Received response:" + response); }), // (2) policy has permission for all file URLs under /files TestAndResult.of(false, () -> { // Policy 2 - URI u = URI.create("http://localhost:" + port + "/files/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/files/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u).GET().build(); HttpResponse response = client.send(request, ofString()); System.out.println("Received response:" + response); }), // (3) policy has permission for first URL but not redirected URL TestAndResult.of(true, () -> { // Policy 3 - URI u = URI.create("http://localhost:" + port + "/redirect/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/redirect/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u).GET().build(); HttpResponse response = client.send(request, ofString()); System.out.println("Received response:" + response); }), // (4) policy has permission for both first URL and redirected URL TestAndResult.of(false, () -> { // Policy 4 - URI u = URI.create("http://localhost:" + port + "/redirect/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/redirect/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u).GET().build(); HttpResponse response = client.send(request, ofString()); System.out.println("Received response:" + response); }), // (5) policy has permission for redirected but not first URL TestAndResult.of(true, () -> { // Policy 5 - URI u = URI.create("http://localhost:" + port + "/redirect/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/redirect/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u).GET().build(); HttpResponse response = client.send(request, ofString()); System.out.println("Received response:" + response); }), // (6) policy has permission for file URL, but not method TestAndResult.of(true, () -> { //Policy 6 - URI u = URI.create("http://localhost:" + port + "/files/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/files/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u).GET().build(); HttpResponse response = client.send(request, ofString()); System.out.println("Received response:" + response); }), // (7) policy has permission for file URL, method, but not header TestAndResult.of(true, () -> { //Policy 7 - URI u = URI.create("http://localhost:" + port + "/files/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/files/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u) .header("X-Foo", "bar") .GET() @@ -260,7 +261,7 @@ static TestAndResult[] createTests() { }), // (8) policy has permission for file URL, method and header TestAndResult.of(false, () -> { //Policy 8 - URI u = URI.create("http://localhost:" + port + "/files/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/files/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u) .header("X-Foo", "bar") .GET() @@ -270,7 +271,7 @@ static TestAndResult[] createTests() { }), // (9) policy has permission for file URL, method and header TestAndResult.of(false, () -> { //Policy 9 - URI u = URI.create("http://localhost:" + port + "/files/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/files/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u) .headers("X-Foo", "bar", "X-Bar", "foo") .GET() @@ -292,7 +293,7 @@ static TestAndResult[] createTests() { }), // (13) async version of test 0 TestAndResult.of(true, () -> { // Policy 0 - URI u = URI.create("http://localhost:" + port + "/files/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/files/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u).GET().build(); try { HttpResponse response = client.sendAsync(request, ofString()).get(); @@ -307,14 +308,14 @@ static TestAndResult[] createTests() { }), // (14) async version of test 1 TestAndResult.of(false, () -> { //Policy 1 - URI u = URI.create("http://localhost:" + port + "/files/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/files/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u).GET().build(); try { HttpResponse response = client.sendAsync(request, ofString()).get(); System.out.println("Received response:" + response); } catch (ExecutionException e) { - if (e.getCause() instanceof SecurityException) { - throw (SecurityException)e.getCause(); + if (e.getCause() instanceof SecurityException se) { + throw se; } else { throw new RuntimeException(e); } @@ -323,7 +324,7 @@ static TestAndResult[] createTests() { // (15) check that user provided unprivileged code running on a worker // thread does not gain ungranted privileges. TestAndResult.of(true, () -> { //Policy 12 - URI u = URI.create("http://localhost:" + port + "/files/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/files/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u).GET().build(); HttpResponse.BodyHandler sth = ofString(); @@ -369,18 +370,18 @@ public void onComplete() { System.out.println("Received response:" + response); } catch (CompletionException e) { Throwable t = e.getCause(); - if (t instanceof SecurityException) - throw (SecurityException)t; + if (t instanceof SecurityException se) + throw se; else if ((t instanceof IOException) - && (t.getCause() instanceof SecurityException)) - throw ((SecurityException)t.getCause()); + && (t.getCause() instanceof SecurityException se)) + throw se; else throw new RuntimeException(t); } }), // (16) allowed to set Host header but does not have permission TestAndResult.of(true, () -> { //Policy 16 - URI u = URI.create("http://localhost:" + port + "/files/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/files/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u) .header("Host", "foohost:123") .GET().build(); @@ -389,7 +390,7 @@ else if ((t instanceof IOException) }), // (17) allowed to set Host header and does have permission TestAndResult.of(false, () -> { //Policy 17 - URI u = URI.create("http://localhost:" + port + "/files/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/files/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u) .header("Host", "foohost:123") .GET().build(); @@ -426,14 +427,13 @@ private static void directProxyTest(int proxyPort, boolean samePort) } System.out.println("Proxy port, p:" + p); - InetSocketAddress addr = new InetSocketAddress(InetAddress.getLoopbackAddress(), - p); + InetSocketAddress addr = new InetSocketAddress(InetAddress.getLoopbackAddress(), p); HttpClient cl = HttpClient.newBuilder() .proxy(ProxySelector.of(addr)) .build(); clients.add(cl); - URI u = URI.create("http://localhost:" + port + "/files/foo.txt"); + URI u = URI.create("http://" + serverAuthority + "/files/foo.txt"); HttpRequest request = HttpRequest.newBuilder(u) .headers("X-Foo", "bar", "X-Bar", "foo") .build(); @@ -498,13 +498,20 @@ public static void initServer() throws Exception { throw new RuntimeException("Error wrong port"); System.out.println("Port was assigned by Driver"); } - System.out.println("HTTP server port = " + port); - httproot = "http://localhost:" + port + "/files/"; - redirectroot = "http://localhost:" + port + "/redirect/"; + serverAuthority = makeServerAuthority(addr.getAddress().getHostAddress(), port); + System.out.println("HTTP server started at " + serverAuthority); + httproot = "http://" + serverAuthority + "/files/"; + redirectroot = "http://" + serverAuthority + "/redirect/"; uri = new URI(httproot); fileuri = httproot + "foo.txt"; } + private static String makeServerAuthority(final String host, final int port) { + // escape for ipv6 + final String h = host.contains(":") ? "[" + host + "]" : host; + return h + ":" + port; + } + static class RedirectHandler implements HttpHandler { String root; diff --git a/test/jdk/java/nio/channels/FileChannel/FileExtensionAndMap.java b/test/jdk/java/nio/channels/FileChannel/FileExtensionAndMap.java deleted file mode 100644 index 84feb55cdb7..00000000000 --- a/test/jdk/java/nio/channels/FileChannel/FileExtensionAndMap.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2016, 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 - * @ignore This test has huge disk space requirements - * @bug 8168628 - * @summary Test extending files to very large sizes without hitting a SIGBUS - * @requires (os.family == "linux") - * @run main/othervm/timeout=600 -Xms4g -Xmx4g FileExtensionAndMap - * @run main/othervm/timeout=600 -Xms4g -Xmx4g FileExtensionAndMap true - */ - -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.MappedByteBuffer; -import java.nio.channels.ClosedChannelException; -import java.nio.channels.FileChannel; -import java.nio.channels.FileChannel.MapMode; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.nio.file.StandardOpenOption; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ForkJoinPool; -import java.util.concurrent.Semaphore; -import java.util.stream.IntStream; - -public class FileExtensionAndMap { - - private static final ExecutorService CACHED_EXECUTORSERVICE = - Executors.newCachedThreadPool(); - - private static final String TMPDIR = System.getProperty("test.dir", "."); - - private static boolean useRaf = false; - - public static void main(String args[]) throws Exception { - if (args.length > 2) { - throw new IllegalArgumentException - ("Arguments: [true|false [targetFolder]]"); - } - - String defaultFolder = TMPDIR + File.separator + "target"; - if (args.length > 0) { - useRaf = Boolean.valueOf(args[0]); - if (args.length > 1) { - defaultFolder = args[1]; - } - } - final String targetFolder = defaultFolder; - Path p = Paths.get(targetFolder); - boolean targetExists = Files.exists(p); - if (!targetExists) { - Files.createDirectory(p); - } - - System.out.printf("Using RandomAccessFile: %s; target folder: %s%n", - useRaf, targetFolder); - - ForkJoinPool fjPool = new ForkJoinPool(3); - fjPool.submit(() -> { - IntStream.range(0, 20).parallel().forEach((index) -> { - String fileName = "testBigFile_" + index + ".dat"; - Path source = null; - Path target = null; - try { - source = Paths.get(TMPDIR, fileName); - testCreateBigFile(source); - target = Paths.get(targetFolder, fileName); - testFileCopy(source, target); - } catch (Throwable th) { - System.err.println("Error copying file with fileName: " - + fileName + " : " + th.getMessage()); - th.printStackTrace(System.err); - } finally { - try { - if (source != null) { - Files.deleteIfExists(source); - } - } catch (Throwable ignored) { - } - try { - if (target != null) { - Files.deleteIfExists(target); - } - } catch (Throwable ignored) { - } - } - }); - }).join(); - - if (!targetExists) { - Files.delete(p); - } - } - - private static void testFileCopy(Path source, Path target) - throws IOException { - Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); - System.out.println("Finished copying file with fileName: " - + source.getFileName()); - } - - private static void testCreateBigFile(Path segmentFile) - throws IOException { - final Semaphore concurrencySemaphore = new Semaphore(5); - long fileSize = 3L * 1024L * 1024L * 1024L; - int blockSize = 10 * 1024 * 1024; - int loopCount = (int) Math.floorDiv(fileSize, blockSize); - - String fileName = segmentFile.getFileName().toString(); - if (useRaf) { - try (RandomAccessFile raf - = new RandomAccessFile(segmentFile.toFile(), "rw")) { - raf.setLength(fileSize); - try (FileChannel fc = raf.getChannel()) { - for (int i = 0; i < loopCount; i++) { - final long startPosition = 1L * blockSize * i; - concurrencySemaphore.acquireUninterruptibly(); - CACHED_EXECUTORSERVICE.submit(() -> { - writeTemplateData(fileName, fc, startPosition, - blockSize, concurrencySemaphore); - }); - } - } finally { - concurrencySemaphore.acquireUninterruptibly(5); - } - } - } else { - Path file = Files.createFile(segmentFile); - try (FileChannel fc = FileChannel.open(file, - StandardOpenOption.READ, StandardOpenOption.WRITE)) { - for (int i = 0; i < loopCount; i++) { - final long startPosition = 1L * blockSize * i; - concurrencySemaphore.acquireUninterruptibly(); - CACHED_EXECUTORSERVICE.submit(() -> { - writeTemplateData(fileName, fc, startPosition, - blockSize, concurrencySemaphore); - }); - } - } - } - } - - private static void writeTemplateData(String fileName, - FileChannel fc, long startPosition, int blockSize, - Semaphore concurrencySemaphore) { - try { - byte[] EMPTY_RECORD = new byte[blockSize / 256]; - - MappedByteBuffer mappedByteBuffer = fc.map(MapMode.READ_WRITE, - startPosition, blockSize); - IntStream.range(0, 256).forEach((recordIndex) -> { - try { - mappedByteBuffer.position((int) (recordIndex * - EMPTY_RECORD.length)); - mappedByteBuffer.put(EMPTY_RECORD, 0, EMPTY_RECORD.length); - } catch (Throwable th) { - System.err.println - ("Error in FileExtensionAndMap.writeTemplateData empty record for fileName: " - + fileName + ", startPosition: " + startPosition + ", recordIndex: " - + recordIndex + " : " + th.getMessage()); - th.printStackTrace(System.err); - } - }); - - mappedByteBuffer.force(); - } catch (Throwable th) { - if (!(th instanceof ClosedChannelException)) { - System.err.println - ("Error in FileExtensionAndMap.writeTemplateData empty record for fileName: " - + fileName + ", startPosition: " + startPosition + " : " - + th.getMessage()); - th.printStackTrace(System.err); - } - } finally { - concurrencySemaphore.release(); - } - } -} diff --git a/test/jdk/java/nio/file/Files/probeContentType/Basic.java b/test/jdk/java/nio/file/Files/probeContentType/Basic.java index c73f6ce6ef4..6a48e38c639 100644 --- a/test/jdk/java/nio/file/Files/probeContentType/Basic.java +++ b/test/jdk/java/nio/file/Files/probeContentType/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -23,25 +23,28 @@ /* @test * @bug 4313887 8129632 8129633 8162624 8146215 8162745 8273655 8274171 + * @library /test/lib + * @modules java.base/jdk.internal.util * @summary Unit test for probeContentType method * @library ../.. - * @build Basic SimpleFileTypeDetector + * @build jdk.test.lib.OSVersion jdk.test.lib.Platform Basic SimpleFileTypeDetector * @run main/othervm Basic */ import java.io.*; import java.nio.file.*; +import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; +import jdk.test.lib.Platform; +import jdk.test.lib.OSVersion; + /** * Uses Files.probeContentType to probe html file, custom file type, and minimal * set of file extension to content type mappings. */ public class Basic { - private static final boolean IS_UNIX = - ! System.getProperty("os.name").startsWith("Windows"); - static Path createHtmlFile() throws IOException { Path file = Files.createTempFile("foo", ".html"); try (OutputStream out = Files.newOutputStream(file)) { @@ -77,7 +80,7 @@ private static int checkContentTypes(String expected, String actual) { assert actual != null; if (!expected.equals(actual)) { - if (IS_UNIX) { + if (!Platform.isWindows()) { Path userMimeTypes = Paths.get(System.getProperty("user.home"), ".mime.types"); checkMimeTypesFile(userMimeTypes); @@ -96,12 +99,12 @@ private static int checkContentTypes(String expected, String actual) { return 0; } - static int checkContentTypes(ExType[] exTypes) + static int checkContentTypes(List exTypes) throws IOException { int failures = 0; - for (int i = 0; i < exTypes.length; i++) { - String extension = exTypes[i].extension(); - List expectedTypes = exTypes[i].expectedTypes(); + for (ExType exType : exTypes) { + String extension = exType.extension(); + List expectedTypes = exType.expectedTypes(); Path file = Files.createTempFile("foo", "." + extension); try { String type = Files.probeContentType(file); @@ -153,39 +156,55 @@ public static void main(String[] args) throws IOException { } // Verify that certain extensions are mapped to the correct type. - var exTypes = new ExType[] { - new ExType("adoc", List.of("text/plain")), - new ExType("bz2", List.of("application/bz2", "application/x-bzip2", "application/x-bzip")), - new ExType("css", List.of("text/css")), - new ExType("csv", List.of("text/csv")), - new ExType("doc", List.of("application/msword")), - new ExType("docx", List.of("application/vnd.openxmlformats-officedocument.wordprocessingml.document")), - new ExType("gz", List.of("application/gzip", "application/x-gzip")), - new ExType("jar", List.of("application/java-archive", "application/x-java-archive", "application/jar")), - new ExType("jpg", List.of("image/jpeg")), - new ExType("js", List.of("text/javascript", "application/javascript")), - new ExType("json", List.of("application/json")), - new ExType("markdown", List.of("text/markdown")), - new ExType("md", List.of("text/markdown", "application/x-genesis-rom")), - new ExType("mp3", List.of("audio/mpeg")), - new ExType("mp4", List.of("video/mp4")), - new ExType("odp", List.of("application/vnd.oasis.opendocument.presentation")), - new ExType("ods", List.of("application/vnd.oasis.opendocument.spreadsheet")), - new ExType("odt", List.of("application/vnd.oasis.opendocument.text")), - new ExType("pdf", List.of("application/pdf")), - new ExType("php", List.of("text/plain", "text/php", "application/x-php")), - new ExType("png", List.of("image/png")), - new ExType("ppt", List.of("application/vnd.ms-powerpoint")), - new ExType("pptx",List.of("application/vnd.openxmlformats-officedocument.presentationml.presentation")), - new ExType("py", List.of("text/plain", "text/x-python", "text/x-python-script")), - new ExType("rar", List.of("application/rar", "application/vnd.rar", "application/x-rar", "application/x-rar-compressed")), - new ExType("rtf", List.of("application/rtf", "text/rtf")), - new ExType("webm", List.of("video/webm")), - new ExType("webp", List.of("image/webp")), - new ExType("xls", List.of("application/vnd.ms-excel")), - new ExType("xlsx", List.of("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")), - new ExType("7z", List.of("application/x-7z-compressed")), - }; + List exTypes = new ArrayList(); + + // extensions with consistent content type + exTypes.add(new ExType("adoc", List.of("text/plain"))); + exTypes.add(new ExType("css", List.of("text/css"))); + exTypes.add(new ExType("doc", List.of("application/msword"))); + exTypes.add(new ExType("docx", List.of("application/vnd.openxmlformats-officedocument.wordprocessingml.document"))); + exTypes.add(new ExType("gz", List.of("application/gzip", "application/x-gzip"))); + exTypes.add(new ExType("jar", List.of("application/java-archive", "application/x-java-archive", "application/jar"))); + exTypes.add(new ExType("jpg", List.of("image/jpeg"))); + exTypes.add(new ExType("js", List.of("text/plain", "text/javascript", "application/javascript"))); + exTypes.add(new ExType("json", List.of("application/json"))); + exTypes.add(new ExType("markdown", List.of("text/markdown"))); + exTypes.add(new ExType("md", List.of("text/markdown", "application/x-genesis-rom"))); + exTypes.add(new ExType("mp3", List.of("audio/mpeg"))); + exTypes.add(new ExType("mp4", List.of("video/mp4"))); + exTypes.add(new ExType("odp", List.of("application/vnd.oasis.opendocument.presentation"))); + exTypes.add(new ExType("ods", List.of("application/vnd.oasis.opendocument.spreadsheet"))); + exTypes.add(new ExType("odt", List.of("application/vnd.oasis.opendocument.text"))); + exTypes.add(new ExType("pdf", List.of("application/pdf"))); + exTypes.add(new ExType("php", List.of("text/plain", "text/php", "application/x-php"))); + exTypes.add(new ExType("png", List.of("image/png"))); + exTypes.add(new ExType("ppt", List.of("application/vnd.ms-powerpoint"))); + exTypes.add(new ExType("pptx", List.of("application/vnd.openxmlformats-officedocument.presentationml.presentation"))); + exTypes.add(new ExType("py", List.of("text/plain", "text/x-python", "text/x-python-script"))); + exTypes.add(new ExType("webm", List.of("video/webm"))); + exTypes.add(new ExType("webp", List.of("image/webp"))); + exTypes.add(new ExType("xls", List.of("application/vnd.ms-excel"))); + exTypes.add(new ExType("xlsx", List.of("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))); + // exTypes.add(new ExType("wasm", List.of("application/wasm"))); Note. "wasm" is added via JDK-8297609 (Java 20) which not exist in current java version yet + + // extensions with content type that differs on Windows 11+ + if (Platform.isWindows() && + (System.getProperty("os.name").endsWith("11") || + new OSVersion(10, 0).compareTo(OSVersion.current()) > 0)) { + System.out.println("Windows 11+ detected: using different types"); + exTypes.add(new ExType("bz2", List.of("application/bz2", "application/x-bzip2", "application/x-bzip", "application/x-compressed"))); + exTypes.add(new ExType("csv", List.of("text/csv", "application/vnd.ms-excel"))); + exTypes.add(new ExType("rar", List.of("application/rar", "application/vnd.rar", "application/x-rar", "application/x-rar-compressed", "application/x-compressed"))); + exTypes.add(new ExType("rtf", List.of("application/rtf", "text/rtf", "application/msword"))); + exTypes.add(new ExType("7z", List.of("application/x-7z-compressed", "application/x-compressed"))); + } else { + exTypes.add(new ExType("bz2", List.of("application/bz2", "application/x-bzip2", "application/x-bzip"))); + exTypes.add(new ExType("csv", List.of("text/csv"))); + exTypes.add(new ExType("rar", List.of("application/rar", "application/vnd.rar", "application/x-rar", "application/x-rar-compressed"))); + exTypes.add(new ExType("rtf", List.of("application/rtf", "text/rtf"))); + exTypes.add(new ExType("7z", List.of("application/x-7z-compressed"))); + } + failures += checkContentTypes(exTypes); if (failures > 0) { diff --git a/test/jdk/java/nio/file/spi/SetDefaultProvider.java b/test/jdk/java/nio/file/spi/SetDefaultProvider.java index 29953c33e8e..0c012b24bf8 100644 --- a/test/jdk/java/nio/file/spi/SetDefaultProvider.java +++ b/test/jdk/java/nio/file/spi/SetDefaultProvider.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8266345 + * @bug 4313887 7006126 8142968 8178380 8183320 8210112 8266345 8263940 * @modules jdk.jartool * @library /test/lib * @build SetDefaultProvider TestProvider m/* jdk.test.lib.process.ProcessTools @@ -37,11 +37,14 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; import java.util.spi.ToolProvider; +import java.util.stream.Collectors; +import java.util.stream.Stream; import jdk.test.lib.process.ProcessTools; -import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import static org.testng.Assert.*; @@ -73,6 +76,45 @@ public void testClassPath() throws Exception { assertTrue(exitValue == 0); } + /** + * Test override of default FileSystemProvider with a + * FileSystemProvider jar and the main application on the class path. + */ + public void testClassPathWithFileSystemProviderJar() throws Exception { + String testClasses = System.getProperty("test.classes"); + Path jar = Path.of("testFileSystemProvider.jar"); + Files.deleteIfExists(jar); + createFileSystemProviderJar(jar, Path.of(testClasses)); + String classpath = jar + File.pathSeparator + testClasses + + File.separator + "modules" + File.separator + "m"; + int exitValue = exec(SET_DEFAULT_FSP, "-cp", classpath, "p.Main"); + assertTrue(exitValue == 0); + } + + /** + * Creates a JAR containing the FileSystemProvider used to override the + * default FileSystemProvider + */ + private void createFileSystemProviderJar(Path jar, Path dir) throws IOException { + + List args = new ArrayList<>(); + args.add("--create"); + args.add("--file=" + jar); + try (Stream stream = Files.list(dir)) { + List paths = stream + .map(path -> path.getFileName().toString()) + .filter(f -> f.startsWith("TestProvider")) + .toList(); + for(var p : paths) { + args.add("-C"); + args.add(dir.toString()); + args.add(p); + } + } + int ret = JAR_TOOL.run(System.out, System.out, args.toArray(new String[0])); + assertTrue(ret == 0); + } + /** * Test override of default FileSystemProvider with the main application * on the class path and a SecurityManager enabled. diff --git a/test/jdk/java/security/Security/ConfigFileTest.java b/test/jdk/java/security/Security/ConfigFileTest.java index e6f54a7491e..fe022fc45ce 100644 --- a/test/jdk/java/security/Security/ConfigFileTest.java +++ b/test/jdk/java/security/Security/ConfigFileTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, 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 @@ -36,7 +36,7 @@ /* * @test * @summary Throw error if default java.security file is missing - * @bug 8155246 8292297 8292177 + * @bug 8155246 8292297 8292177 8281658 * @library /test/lib * @run main ConfigFileTest */ @@ -71,6 +71,10 @@ public static void main(String[] args) throws Exception { copyJDK(jdkTestDir, copyJdkDir); String extraPropsFile = Path.of(System.getProperty("test.src"), "override.props").toString(); + // sanity test -XshowSettings:security option + exerciseShowSettingsSecurity(copiedJava.toString(), "-cp", System.getProperty("test.classes"), + "-Djava.security.debug=all", "-XshowSettings:security", "ConfigFileTest", "runner"); + // exercise some debug flags while we're here // regular JDK install - should expect success exerciseSecurity(0, "java", @@ -136,6 +140,16 @@ private static void exerciseSecurity(int exitCode, String output, String... args } } + // exercise the -XshowSettings:security launcher + private static void exerciseShowSettingsSecurity(String... args) throws Exception { + ProcessBuilder process = new ProcessBuilder(args); + OutputAnalyzer oa = ProcessTools.executeProcess(process); + oa.shouldHaveExitValue(0) + .shouldContain("Security properties:") + .shouldContain("Security provider static configuration:") + .shouldContain("Security TLS configuration"); + } + private static void copyJDK(Path src, Path dst) throws Exception { Files.walk(src) .skip(1) diff --git a/test/jdk/java/security/cert/CertPathBuilder/akiExt/AKISerialNumber.java b/test/jdk/java/security/cert/CertPathBuilder/akiExt/AKISerialNumber.java index e8ab65d78dd..53db87cfe63 100644 --- a/test/jdk/java/security/cert/CertPathBuilder/akiExt/AKISerialNumber.java +++ b/test/jdk/java/security/cert/CertPathBuilder/akiExt/AKISerialNumber.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, 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 @@ -118,6 +118,8 @@ public static void main(String[] args) throws Exception { PKIXBuilderParameters params = new PKIXBuilderParameters (Collections.singleton(anchor), sel); params.setRevocationEnabled(false); + // Set date to 2024-01-01 to satisfy cert constraints + params.setDate(new java.util.Date(1704067200000l)); ArrayList certs = new ArrayList<>(); certs.add(intCert); diff --git a/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java b/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java index 1dc8cba5cc5..478e94572bc 100644 --- a/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java +++ b/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, 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 @@ -23,7 +23,7 @@ /** * @test - * @bug 8179503 + * @bug 8179503 8328638 * @summary Java should support GET OCSP calls * @library /javax/net/ssl/templates /java/security/testlibrary * @build SimpleOCSPServer @@ -31,6 +31,8 @@ * java.base/sun.security.provider.certpath * java.base/sun.security.x509 * @run main/othervm GetAndPostTests + * @run main/othervm -Dcom.sun.security.ocsp.useget=false GetAndPostTests + * @run main/othervm -Dcom.sun.security.ocsp.useget=foo GetAndPostTests */ import java.io.ByteArrayInputStream; @@ -62,16 +64,14 @@ import java.util.Set; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; -import sun.security.testlibrary.SimpleOCSPServer; import sun.security.testlibrary.SimpleOCSPServer; import sun.security.util.DerOutputStream; import sun.security.util.DerValue; import sun.security.util.ObjectIdentifier; -import sun.security.testlibrary.SimpleOCSPServer; public class GetAndPostTests { private static final String PASS = "passphrase"; + private static final int SERVER_WAIT_SECS = 60; private static CertificateFactory certFac; public static void main(String args[]) throws Exception { @@ -114,13 +114,8 @@ public static void main(String args[]) throws Exception { endEntCert.getSerialNumber(), new SimpleOCSPServer.CertStatusInfo( SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD))); - ocspResponder.start(); - // Wait 5 seconds for server ready - boolean readyStatus = - ocspResponder.awaitServerReady(5, TimeUnit.SECONDS); - if (!readyStatus) { - throw new RuntimeException("Server not ready"); - } + + startOcspServer(ocspResponder); int ocspPort = ocspResponder.getPort(); URI ocspURI = new URI("http://localhost:" + ocspPort); @@ -169,6 +164,14 @@ public static void main(String args[]) throws Exception { } } + private static void startOcspServer(SimpleOCSPServer ocspResponder) throws InterruptedException, IOException { + ocspResponder.start(); + if (!ocspResponder.awaitServerReady(SERVER_WAIT_SECS, TimeUnit.SECONDS)) { + throw new RuntimeException("Server not ready after " + SERVER_WAIT_SECS + + " seconds."); + } + } + /** * Create an X509Certificate object from its PEM encoding * diff --git a/test/jdk/java/security/testlibrary/SimpleOCSPServer.java b/test/jdk/java/security/testlibrary/SimpleOCSPServer.java index ba3cdeb581a..37e43bac9b1 100644 --- a/test/jdk/java/security/testlibrary/SimpleOCSPServer.java +++ b/test/jdk/java/security/testlibrary/SimpleOCSPServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, 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 @@ -288,10 +288,18 @@ public synchronized void acceptConnections() { public synchronized void stop() { if (started) { receivedShutdown = true; + started = false; log("Received shutdown notification"); } } + public synchronized void shutdownNow() { + stop(); + if (threadPool != null) { + threadPool.shutdownNow(); + } + } + /** * Print {@code SimpleOCSPServer} operating parameters. * @@ -577,7 +585,7 @@ private synchronized void log(String message) { * @param message the message to log */ private static synchronized void err(String message) { - System.out.println("[" + Thread.currentThread().getName() + "]: " + + System.err.println("[" + Thread.currentThread().getName() + "]: " + message); } @@ -696,6 +704,9 @@ public CRLReason getRevocationReason() { * responses. */ private class OcspHandler implements Runnable { + private final boolean USE_GET = + !System.getProperty("com.sun.security.ocsp.useget", "").equals("false"); + private final Socket sock; InetSocketAddress peerSockAddr; @@ -868,6 +879,12 @@ private LocalOcspRequest parseHttpOcspPost(InputStream inStream) // Okay, make sure we got what we needed from the header, then // read the remaining OCSP Request bytes if (properContentType && length >= 0) { + if (USE_GET && length <= 255) { + // Received a small POST request. Check that our client code properly + // handled the relevant flag. We expect small GET requests, unless + // explicitly disabled. + throw new IOException("Should have received small GET, not POST."); + } byte[] ocspBytes = new byte[length]; inStream.read(ocspBytes); return new LocalOcspRequest(ocspBytes); diff --git a/test/jdk/java/util/Currency/ValidateISO4217.java b/test/jdk/java/util/Currency/ValidateISO4217.java index 9c0786816e0..3d2bae0e5e7 100644 --- a/test/jdk/java/util/Currency/ValidateISO4217.java +++ b/test/jdk/java/util/Currency/ValidateISO4217.java @@ -25,7 +25,7 @@ * @test * @bug 4691089 4819436 4942982 5104960 6544471 6627549 7066203 7195759 * 8039317 8074350 8074351 8145952 8187946 8193552 8202026 8204269 - * 8208746 8209775 8264792 8274658 8283277 8296239 + * 8208746 8209775 8264792 8274658 8283277 8296239 8321480 * @summary Validate ISO 4217 data for Currency class. * @modules java.base/java.util:open * jdk.localedata @@ -86,7 +86,7 @@ public class ValidateISO4217 { // Codes that are obsolete, do not have related country, extra currency private static final String otherCodes = "ADP-AFA-ATS-AYM-AZM-BEF-BGL-BOV-BYB-BYR-CHE-CHW-CLF-COU-CUC-CYP-" - + "DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-IEP-ITL-LTL-LUF-LVL-MGF-MRO-MTL-MXV-MZM-NLG-" + + "DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-HRK-IEP-ITL-LTL-LUF-LVL-MGF-MRO-MTL-MXV-MZM-NLG-" + "PTE-ROL-RUR-SDD-SIT-SLL-SKK-SRG-STD-TMM-TPE-TRL-VEF-UYI-USN-USS-VEB-VED-" + "XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-" + "YUM-ZMK-ZWD-ZWN-ZWR"; @@ -168,7 +168,7 @@ private static void processColumns(StringTokenizer tokens, String country) throw if (format == null) { createDateFormat(); } - // If the cut-over already passed, test the changed data too + // If the cut-over already passed, use the new curency for ISO4217Codes if (format.parse(tokens.nextToken()).getTime() < System.currentTimeMillis()) { currency = tokens.nextToken(); numeric = tokens.nextToken(); @@ -267,20 +267,21 @@ private static List additionalCodesProvider() { * throws an IllegalArgumentException or returns null. The test data * supplied is every possible combination of AA -> ZZ. */ - @ParameterizedTest - @MethodSource("codeCombos") - public void twoLetterCodesTest(String country) { - if (codes[toIndex(country)] == UNDEFINED) { - // if a code is undefined / 0, creating a Currency from it - // should throw an IllegalArgumentException - assertThrows(IllegalArgumentException.class, - ()-> Currency.getInstance(new Locale("", country)), - "Error: This should be an undefined code and throw IllegalArgumentException: " + country); - } else if (codes[toIndex(country)] == SKIPPED) { - // if a code is marked as skipped / 2, creating a Currency from it - // should return null - assertNull(Currency.getInstance(new Locale("", country)), - "Error: Currency.getInstance() for this locale should return null: " + country); + @Test + public void twoLetterCodesTest() { + for (String country : codeCombos()) { + if (codes[toIndex(country)] == UNDEFINED) { + // if a code is undefined / 0, creating a Currency from it + // should throw an IllegalArgumentException + assertThrows(IllegalArgumentException.class, + () -> Currency.getInstance(new Locale("", country)), + "Error: This should be an undefined code and throw IllegalArgumentException: " + country); + } else if (codes[toIndex(country)] == SKIPPED) { + // if a code is marked as skipped / 2, creating a Currency from it + // should return null + assertNull(Currency.getInstance(new Locale("", country)), + "Error: Currency.getInstance() for this locale should return null: " + country); + } } } diff --git a/test/jdk/java/util/Currency/tablea1.txt b/test/jdk/java/util/Currency/tablea1.txt index 4e33a62c05e..6e85de5e6d2 100644 --- a/test/jdk/java/util/Currency/tablea1.txt +++ b/test/jdk/java/util/Currency/tablea1.txt @@ -1,12 +1,12 @@ # # -# Amendments up until ISO 4217 AMENDMENT NUMBER 175 -# (As of 31 March 2023) +# Amendments up until ISO 4217 AMENDMENT NUMBER 176 +# (As of 06 December 2023) # # Version FILEVERSION=3 -DATAVERSION=175 +DATAVERSION=176 # ISO 4217 currency data AF AFN 971 2 @@ -67,9 +67,9 @@ CD CDF 976 2 CK NZD 554 2 CR CRC 188 2 CI XOF 952 0 -HR HRK 191 2 2022-12-31-23-00-00 EUR 978 2 +HR EUR 978 2 CU CUP 192 2 -CW ANG 532 2 +CW ANG 532 2 2025-04-01-04-00-00 XCG 532 2 CY EUR 978 2 CZ CZK 203 2 DK DKK 208 2 @@ -233,7 +233,7 @@ LK LKR 144 2 SD SDG 938 2 SR SRD 968 2 SJ NOK 578 2 -SX ANG 532 2 +SX ANG 532 2 2025-04-01-04-00-00 XCG 532 2 SZ SZL 748 2 SE SEK 752 2 CH CHF 756 2 diff --git a/test/jdk/java/util/Formatter/Padding.java b/test/jdk/java/util/Formatter/Padding.java index 982b6967928..5f0e7f0e201 100644 --- a/test/jdk/java/util/Formatter/Padding.java +++ b/test/jdk/java/util/Formatter/Padding.java @@ -29,6 +29,8 @@ * @run junit Padding */ +import java.util.Locale; + import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -307,7 +309,7 @@ static Arguments[] padding() { @ParameterizedTest @MethodSource void padding(String expected, String format, Object value) { - assertEquals(expected, String.format(format, value)); + assertEquals(expected, String.format(Locale.US, format, value)); } } diff --git a/test/jdk/java/util/HashMap/WhiteBoxResizeTest.java b/test/jdk/java/util/HashMap/WhiteBoxResizeTest.java index e7374dff5cd..fee39d229f8 100644 --- a/test/jdk/java/util/HashMap/WhiteBoxResizeTest.java +++ b/test/jdk/java/util/HashMap/WhiteBoxResizeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * Copyright (c) 2018, 2024, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,8 @@ * @modules java.base/java.util:open * @summary White box tests for HashMap internals around table resize * @run testng WhiteBoxResizeTest + * @comment skip running this test on 32 bit VM + * @requires vm.bits == "64" * @key randomness */ public class WhiteBoxResizeTest { diff --git a/test/jdk/java/util/Locale/Bug4175998Test.java b/test/jdk/java/util/Locale/Bug4175998Test.java deleted file mode 100644 index a5ad1dd3abd..00000000000 --- a/test/jdk/java/util/Locale/Bug4175998Test.java +++ /dev/null @@ -1,855 +0,0 @@ -/* - * Copyright (c) 2007, 2016, 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 test ISO639-2 language codes - * @library /java/text/testlib - * @compile -encoding ascii Bug4175998Test.java - * @run main Bug4175998Test - * @bug 4175998 - */ - -/* - * - * - * (C) Copyright IBM Corp. 1998 - All Rights Reserved - * - * The original version of this source code and documentation is - * copyrighted and owned by IBM. These materials are provided - * under terms of a License Agreement between IBM and Sun. - * This technology is protected by multiple US and International - * patents. This notice and attribution to IBM may not be removed. - * - */ - -import java.util.*; - -/** - * Bug4175998Test verifies that the following bug has been fixed: - * Bug 4175998 - The java.util.Locale.getISO3Language() returns wrong result for a locale with - * language code 'ta'(Tamil). - */ -public class Bug4175998Test extends IntlTest { - public static void main(String[] args) throws Exception { - new Bug4175998Test().run(args); - //generateTables(); //uncomment this to regenerate data tables - } - - public void testIt() throws Exception { - boolean bad = false; - for (int i = 0; i < CODES.length; i++) { - final String[] localeCodes = CODES[i]; - final Locale l = new Locale(localeCodes[0], ""); - final String iso3 = l.getISO3Language(); - if (!iso3.equals(localeCodes[1]) /*&& !iso3.equals(localeCodes[2])*/) { - logln("Locale("+l+") returned bad ISO3 language code." - +" Got '"+iso3+"' instead of '"+localeCodes[1]+"'"/*+" or '"+localeCodes[2]+"'"*/); - bad = true; - } - } - if (bad) { - errln("Bad ISO3 language codes detected."); - } - } - - private static final String[][] CODES = { - {"pt","por","por"}, - {"eu","eus","baq"}, - {"ps","pus","pus"}, - {"et","est","est"}, - {"ka","kat","geo"}, - {"es","spa","spa"}, - {"eo","epo","epo"}, - {"en","eng","eng"}, - {"pl","pol","pol"}, - {"el","ell","gre"}, - {"uz","uzb","uzb"}, - {"jv","jav","jav"}, - {"ur","urd","urd"}, - {"uk","ukr","ukr"}, - {"ug","uig","uig"}, - {"zu","zul","zul"}, - {"ja","jpn","jpn"}, - {"or","ori","ori"}, - {"om","orm","orm"}, - {"zh","zho","chi"}, - {"tw","twi","twi"}, - {"de","deu","ger"}, - {"oc","oci","oci"}, - {"za","zha","zha"}, - {"tt","tat","tat"}, - {"iu","iku","iku"}, - {"ts","tso","tso"}, - {"it","ita","ita"}, - {"tr","tur","tur"}, - {"da","dan","dan"}, - {"is","isl","ice"}, - {"to","ton","ton"}, - {"tl","tgl","tgl"}, - {"tk","tuk","tuk"}, - {"ik","ipk","ipk"}, - {"ti","tir","tir"}, - {"th","tha","tha"}, - {"tg","tgk","tgk"}, - {"te","tel","tel"}, - {"cy","cym","wel"}, - {"ie","ile","ile"}, - {"id","ind","ind"}, - {"ta","tam","tam"}, - {"ia","ina","ina"}, - {"cs","ces","cze"}, - {"yo","yor","yor"}, - {"no","nor","nor"}, - {"co","cos","cos"}, - {"nl","nld","dut"}, - {"yi","yid","yid"}, - {"hy","hye","arm"}, - {"sw","swa","swa"}, - {"ne","nep","nep"}, - {"sv","swe","swe"}, - {"su","sun","sun"}, - {"hu","hun","hun"}, - {"na","nau","nau"}, - {"sr","srp","scc"}, - {"ca","cat","cat"}, - {"sq","sqi","alb"}, - {"hr","hrv","scr"}, - {"so","som","som"}, - {"sn","sna","sna"}, - {"sm","smo","smo"}, - {"sl","slv","slv"}, - {"sk","slk","slo"}, - {"si","sin","sin"}, - {"hi","hin","hin"}, - {"my","mya","bur"}, - {"sd","snd","snd"}, - {"he","heb","heb"}, - {"sa","san","san"}, - {"mt","mlt","mlt"}, - {"ms","msa","may"}, - {"ha","hau","hau"}, - {"mr","mar","mar"}, - {"br","bre","bre"}, - {"mo","mol","mol"}, - {"bo","bod","tib"}, - {"mn","mon","mon"}, - {"bn","ben","ben"}, - {"ml","mal","mal"}, - {"mk","mkd","mac"}, - {"xh","xho","xho"}, - {"mi","mri","mao"}, - {"bi","bis","bis"}, - {"bh","bih","bih"}, - {"mg","mlg","mlg"}, - {"bg","bul","bul"}, - {"rw","kin","kin"}, - {"be","bel","bel"}, - {"ru","rus","rus"}, - {"gu","guj","guj"}, - {"ba","bak","bak"}, - {"ro","ron","rum"}, - {"rm","roh","roh"}, - {"gn","grn","grn"}, - {"az","aze","aze"}, - {"ay","aym","aym"}, - {"gd","gla","gla"}, - {"lv","lav","lav"}, - {"lt","lit","lit"}, - {"ga","gle","gle"}, - {"as","asm","asm"}, - {"ar","ara","ara"}, - {"wo","wol","wol"}, - {"ln","lin","lin"}, - {"am","amh","amh"}, - {"fy","fry","fry"}, - {"af","afr","afr"}, - {"qu","que","que"}, - {"ab","abk","abk"}, - {"la","lat","lat"}, - {"aa","aar","aar"}, - {"fr","fra","fre"}, - {"fo","fao","fao"}, - {"fj","fij","fij"}, - {"fi","fin","fin"}, - {"ky","kir","kir"}, - {"ku","kur","kur"}, - {"fa","fas","per"}, - {"ks","kas","kas"}, - {"vo","vol","vol"}, - {"ko","kor","kor"}, - {"kn","kan","kan"}, - {"kk","kaz","kaz"}, - {"vi","vie","vie"}, - }; - -/* - The following code was used to generate the table above from the two ISO standards. - It matches the language names (not the codes) from both standards to associate - the two and three letter codes. - - private static final String ISO639 = "d:\\temp\\iso639.txt"; - private static final String ISO6392 = "d:\\temp\\iso-639-2.txt"; - private static void generateTables() { - try { - BufferedReader ISO639File = new BufferedReader(new FileReader(ISO639)); - Hashtable i639 = new Hashtable(); - for (String line = ISO639File.readLine(); line != null; line = ISO639File.readLine()) { - if (!line.startsWith("#")) { - final int ndx = line.indexOf(' '); - final String arg1 = line.substring(0, ndx); - final int ndx2 = line.indexOf(' ', ndx+1); - final String arg2 = line.substring(ndx+1, ndx2 < 0 ? line.length() : ndx2); - i639.put(arg1, arg2); - } - } - - BufferedReader ISO6392File = new BufferedReader(new FileReader(ISO6392)); - Hashtable i6392 = new Hashtable(); - for (String line = ISO6392File.readLine(); line != null; line = ISO6392File.readLine()) { - final int ndx = line.indexOf(' '); - final int ndx2 = line.indexOf(' ', ndx+1); - int ndx3 = line.indexOf(' ', ndx2+1); - if (ndx3 < 0) ndx3 = line.length(); - final String arg1 = line.substring(0, ndx); - final String arg2 = line.substring(ndx+1, ndx2); - final String arg3 = line.substring(ndx2+1, ndx3); - i6392.put(arg3, new ISO6392Entry(arg1, arg2)); - } - - Enumeration keys = i639.keys(); - while (keys.hasMoreElements()) { - final Object key = keys.nextElement(); - final Object name = i639.get(key); - final Object value = i6392.get(name); - - if (value != null) { - System.out.print("{"); - System.out.print("\""+key+"\","); - System.out.print(value); - System.out.println("},"); - } - } - } catch (Exception e) { - System.out.println(e); - } - } - - - private static final class ISO6392Entry { - public final String code; - public final String name; - public ISO6392Entry(String code, String name) { - this.code = code; - this.name = name; - } - public String toString() { - return "\""+code+"\",\""+name+"\""; - } - - } -*/ - -} - -/* - -data from ftp://dkuug.dk on March 4, 1999 -verified by http://www.triacom.com/archive/iso639-2.en.html - -iso 639 data -aa Afar -ab Abkhazian -af Afrikaans -am Amharic -ar Arabic -as Assamese -ay Aymara -az Azerbaijani -ba Bashkir -be Belarussian -bg Bulgarian -bh Bihari -bi Bislama -bn Bengali -bo Tibetan -br Breton -ca Catalan -co Corsican -cs Czech -cy Welsh -da Danish -de German -dz Bhutani -el Greek -en English -eo Esperanto -es Spanish -et Estonian -eu Basque -fa Persian -fi Finnish -fj Fijian -fo Faroese -fr French -fy Frisian -ga Irish -gd Gaelic -gl Galician -gn Guarani -gu Gujarati -ha Hausa -he Hebrew -hi Hindi -hr Croatian -hu Hungarian -hy Armenian -ia Interlingua -id Indonesian -ie Interlingue -ik Inupiak -is Icelandic -it Italian -iu Inuktitut -ja Japanese -jw Javanese -ka Georgian -kk Kazakh -kl Greenlandic -km Cambodian -kn Kannada -ko Korean -ks Kashmiri -ku Kurdish -ky Kirghiz -la Latin -ln Lingala -lo Laothian -lt Lithuanian -lv Latvian -mg Malagasy -mi Maori -mk Macedonian -ml Malayalam -mn Mongolian -mo Moldavian -mr Marathi -ms Malay -mt Maltese -my Burmese -na Nauru -ne Nepali -nl Dutch -no Norwegian -oc Occitan -om Oromo -or Oriya -pa Punjabi -pl Polish -ps Pushto -pt Portuguese -qu Quechua -rm Raeto-Romance -rn Kirundi -ro Romanian -ru Russian -rw Kinyarwanda -sa Sanskrit -sd Sindhi -sg Sangho -sh Croatian (Serbo) -si Sinhalese -sk Slovak -sl Slovenian -sm Samoan -sn Shona -so Somali -sq Albanian -sr Serbian -ss Siswati -st Sesotho -su Sundanese -sv Swedish -sw Swahili -ta Tamil -te Telugu -tg Tajik -th Thai -ti Tigrinya -tk Turkmen -tl Tagalog -tn Setswana -to Tonga -tr Turkish -ts Tsonga -tt Tatar -tw Twi -ug Uighur -uk Ukrainian -ur Urdu -uz Uzbek -vi Vietnamese -vo Volapuk -wo Wolof -xh Xhosa -yi Yiddish -yo Yoruba -za Zhuang -zh Chinese -zu Zulu - -ISO 639-2 data - -aar aar Afar -abk abk Abkhazian -ace ace Achinese -ach ach Acoli -ada ada Adangme -afa afa Afro-Asiatic (Other) -afh afh Afrihili -afr afr Afrikaans -aka aka Akan -akk akk Akkadian -ale ale Aleut -alg alg Algonquian languages -amh amh Amharic -ang ang English-Old (ca. 450-1100) -apa apa Apache languages -ara ara Arabic -arc arc Aramaic -arn arn Araucanian -arp arp Arapaho -art art Artificial (Other) -arw arw Arawak -asm asm Assamese -ath ath Athapascan languages -aus aus Australian languages -ava ava Avaric -ave ave Avestan -awa awa Awadhi -aym aym Aymara -aze aze Azerbaijani -bad bad Banda -bai bai Bamileke languages -bak bak Bashkir -bal bal Baluchi -bam bam Bambara -ban ban Balinese -bas bas Basa -bat bat Baltic (Other) -bej bej Beja -bel bel Belarussian -bem bem Bemba -ben ben Bengali -ber ber Berber (Other) -bho bho Bhojpuri -bih bih Bihari -bik bik Bikol -bin bin Bini -bis bis Bislama -bla bla Siksika -bnt bnt Bantu (Other) -bod tib Tibetan -bra bra Braj -bre bre Breton -btk btk Batak (Indonesia) -bua bua Buriat -bug bug Buginese -bul bul Bulgarian -cad cad Caddo -cai cai Central-American-Indian (Other) -car car Carib -cat cat Catalan -cau cau Caucasian (Other) -ceb ceb Cebuano -cel cel Celtic (Other) -ces cze Czech -cha cha Chamorro -chb chb Chibcha -che che Chechen -chg chg Chagatai -chk chk Chuukese -chm chm Mari -chn chn Chinook-jargon -cho cho Choctaw -chp chp Chipewyan -chr chr Cherokee -chu chu Church-Slavic -chv chv Chuvash -chy chy Cheyenne -cmc cmc Chamic languages -cop cop Coptic -cor cor Cornish -cos cos Corsican -cpe cpe Creoles-and-pidgins-English-based (Other) -cpf cpf Creoles-and-pidgins-French-based (Other) -cpp cpp Creoles-and-pidgins-Portuguese-based (Other) -cre cre Cree -crp crp Creoles-and-pidgins (Other) -cus cus Cushitic (Other) -cym wel Welsh -dak dak Dakota -dan dan Danish -day day Dayak -del del Delaware -den den Slave (Athapascan) -deu ger German -dgr dgr Dogrib -din din Dinka -div div Divehi -doi doi Dogri -dra dra Dravidian (Other) -dua dua Duala -dum dum Dutch-Middle (ca. 1050-1350) -dyu dyu Dyula -dzo dzo Dzongkha -efi efi Efik -egy egy Egyptian (Ancient) -eka eka Ekajuk -ell gre Greek Modern (post 1453) -elx elx Elamite -eng eng English -enm enm English-Middle (1100-1500) -epo epo Esperanto -est est Estonian -eus baq Basque -ewe ewe Ewe -ewo ewo Ewondo -fan fan Fang -fao fao Faroese -fas per Persian -fat fat Fanti -fij fij Fijian -fin fin Finnish -fiu fiu Finno-Ugrian (Other) -fon fon Fon -fra fre French -frm frm French-Middle (ca. 1400-1600) -fro fro French-Old (842-ca. 1400) -fry fry Frisian -ful ful Fulah -fur fur Friulian -gaa gaa Ga -gay gay Gayo -gba gba Gbaya -gem gem Germanic (Other) -gez gez Geez -gil gil Gilbertese -gdh gae Gaelic -gai iri Irish -glg glg Gallegan -glv glv Manx -gmh gmh German-Middle High (ca. 1050-1500) -goh goh German-Old High (ca. 750-1050) -gon gon Gondi -gor gor Gorontalo -got got Gothic -grb grb Grebo -grc grc Greek-Ancient (to 1453) -grn grn Guarani -guj guj Gujarati -gwi gwi Gwich'in -hai hai Haida -hau hau Hausa -haw haw Hawaiian -heb heb Hebrew -her her Herero -hil hil Hiligaynon -him him Himachali -hin hin Hindi -hit hit Hittite -hmn hmn Hmong -hmo hmo Hiri Motu -hrv scr Croatian -hun hun Hungarian -hup hup Hupa -hye arm Armenian -iba iba Iban -ibo ibo Igbo -ijo ijo Ijo -iku iku Inuktitut -ile ile Interlingue -ilo ilo Iloko -ina ina Interlingua (International Auxilary Language Association) -inc inc Indic (Other) -ind ind Indonesian -ine ine Indo-European (Other) -ipk ipk Inupiak -ira ira Iranian (Other) -iro iro Iroquoian languages -isl ice Icelandic -ita ita Italian -jaw jav Javanese -jpn jpn Japanese -jpr jpr Judeo-Persian -jrb jrb Judeo-Arabic -kaa kaa Kara-Kalpak -kab kab Kabyle -kac kac Kachin -kal kal Kalaallisut -kam kam Kamba -kan kan Kannada -kar kar Karen -kas kas Kashmiri -kat geo Georgian -kau kau Kanuri -kaw kaw Kawi -kaz kaz Kazakh -kha kha Khasi -khi khi Khoisan (Other) -khm khm Khmer -kho kho Khotanese -kik kik Kikuyu -kin kin Kinyarwanda -kir kir Kirghiz -kmb kmb Kimbundu -kok kok Konkani -kom kom Komi -kon kon Kongo -kor kor Korean -kos kos Kosraean -kpe kpe Kpelle -kro kro Kru -kru kru Kurukh -kua kua Kuanyama -kum kum Kumyk -kur kur Kurdish -kut kut Kutenai -lad lad Ladino -lah lah Lahnda -lam lam Lamba -lao lao Lao -lat lat Latin -lav lav Latvian -lez lez Lezghian -lin lin Lingala -lit lit Lithuanian -lol lol Mongo -loz loz Lozi -ltz ltz Letzeburgesch -lua lua Luba-Lulua -lub lub Luba-Katanga -lug lug Ganda -lui lui Luiseno -lun lun Lunda -luo luo Luo (Kenya and Tanzania) -lus lus Lushai -mad mad Madurese -mag mag Magahi -mah mah Marshall -mai mai Maithili -mak mak Makasar -mal mal Malayalam -man man Mandingo -map map Austronesian (Other) -mar mar Marathi -mas mas Masai -mdr mdr Mandar -men men Mende -mga mga Irish-Middle (900-1200) -mic mic Micmac -min min Minangkabau -mis mis Miscellaneous languages -mkd mac Macedonian -mkh mkh Mon-Khmer (Other) -mlg mlg Malagasy -mlt mlt Maltese -mni mni Manipuri -mno mno Manobo languages -moh moh Mohawk -mol mol Moldavian -mon mon Mongolian -mos mos Mossi -mri mao Maori -msa may Malay -mul mul Multiple languages -mun mun Munda languages -mus mus Creek -mwr mwr Marwari -mya bur Burmese -myn myn Mayan languages -nah nah Nahuatl -nai nai North American Indian (Other) -nau nau Nauru -nav nav Navajo -nbl nbl Ndebele, South -nde nde Ndebele, North -ndo ndo Ndonga -nep nep Nepali -new new Newari -nia nia Nias -nic nic Niger-Kordofanian (Other) -niu niu Niuean -nld dut Dutch -non non Norse, Old -nor nor Norwegian -nso nso Sohto, Northern -nub nub Nubian languages -nya nya Nyanja -nym nym Nyamwezi -nyn nyn Nyankole -nyo nyo Nyoro -nzi nzi Nzima -oci oci Occitan (post 1500) -oji oji Ojibwa -ori ori Oriya -orm orm Oromo -osa osa Osage -oss oss Ossetic -ota ota Turkish, Ottoman (1500-1928) -oto oto Otomian languages -paa paa Papuan (Other) -pag pag Pangasinan -pal pal Pahlavi -pam pam Pampanga -pan pan Panjabi -pap pap Papiamento -pau pau Palauan -peo peo Persian, Old (ca. 600-400 B.C.) -phi phi Philippine (Other) -phn phn Phoenician -pli pli Pali -pol pol Polish -pon pon Pohnpeian -por por Portuguese -pra pra Prakrit languages -pro pro Proven\u00E7al, Old (to 1500) -pus pus Pushto -qaa-qtz qaa-qtz Reserved for local use -que que Quechua -raj raj Rajasthani -rap rap Rapanui -rar rar Rarotongan -roa roa Romance (Other) -roh roh Raeto-Romance -rom rom Romany -ron rum Romanian -run run Rundi -rus rus Russian -sad sad Sandawe -sag sag Sango -sah sah Yakut -sai sai South American Indian (Other) -sal sal Salishan languages -sam sam Samaritan Aramaic -san san Sanskrit -sas sas Sasak -sat sat Santali -sco sco Scots -sel sel Selkup -sem sem Semitic (Other) -sga sga Irish-Old (to 900) -shn shn Shan -sid sid Sidamo -sin sin Sinhalese -sio sio Siouan languages -sit sit Sino-Tibetan (Other) -sla sla Slavic (Other) -slk slo Slovak -slv slv Slovenian -smi smi Sami languages -smo smo Samoan -sna sna Shona -snd snd Sindhi -snk snk Soninke -sog sog Sogdian -som som Somali -son son Songhai -sot sot Sotho Southern -spa spa Spanish -sqi alb Albanian -srd srd Sardinian -srp scc Serbian -srr srr Serer -ssa ssa Nilo-Saharan (Other) -ssw ssw Swati -suk suk Sukuma -sun sun Sundanese -sus sus Susu -sux sux Sumerian -swa swa Swahili -swe swe Swedish -syr syr Syriac -tah tah Tahitian -tai tai Tai (Other) -tam tam Tamil -tat tat Tatar -tel tel Telugu -tem tem Timne -ter ter Tereno -tet tet Tetum -tgk tgk Tajik -tgl tgl Tagalog -tha tha Thai -tig tig Tigre -tir tir Tigrinya -tiv tiv Tiv -tkl tkl Tokelau -tli tli Tlingit -tmh tmh Tamashek -tog tog Tonga (Nyasa) -ton ton Tonga (Tonga Islands) -tpi tpi Tok Pisin -tsi tsi Tsimshian -tsn tsn Tswana -tso tso Tsonga -tuk tuk Turkmen -tum tum Tumbuka -tur tur Turkish -tut tut Altaic -tvl tvl Tuvalu -twi twi Twi -tyv tyv Tuvinian -uga uga Ugaritic -uig uig Uighur -ukr ukr Ukrainian -umb umb Umbundu -und und Undetermined -urd urd Urdu -uzb uzb Uzbek -vai vai Vai -ven ven Venda -vie vie Vietnamese -vol vol Volapuk -vot vot Votic -wak wak Wakashan -wal wal Walamo -war war Waray -was was Washo -wen wen Sorbian -wol wol Wolof -xho xho Xhosa -yao yao Yao -yap yap Yapese -yid yid Yiddish -yor yor Yoruba -ypk ypk Yupik -zap zap Zapotec -zen zen Zenaga -zha zha Zhuang -zho chi Chinese -znd znd Zande -zul zul Zulu -zun zun Zuni - -*/ diff --git a/test/jdk/java/util/Locale/Bug8025703.java b/test/jdk/java/util/Locale/Bug8025703.java deleted file mode 100644 index 8a694aecb7b..00000000000 --- a/test/jdk/java/util/Locale/Bug8025703.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2013, 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 8025703 - * @summary Verify implementation for Locale matching. - * @run main Bug8025703 - */ - -import java.util.*; -import java.util.Locale.LanguageRange; - -public class Bug8025703 { - - public static void main(String[] args) { - boolean err = false; - - String[][] mappings = {{"ilw", "gal"}, - {"meg", "cir"}, - {"pcr", "adx"}, - {"xia", "acn"}, - {"yos", "zom"}}; - - for (int i = 0; i < mappings.length; i++) { - List got = LanguageRange.parse(mappings[i][0]); - ArrayList expected = new ArrayList<>(); - expected.add(new LanguageRange(mappings[i][0], 1.0)); - expected.add(new LanguageRange(mappings[i][1], 1.0)); - - if (!expected.equals(got)) { - err = true; - System.err.println("Incorrect language ranges. "); - for (LanguageRange lr : expected) { - System.err.println(" Expected: range=" - + lr.getRange() + ", weight=" + lr.getWeight()); - } - for (LanguageRange lr : got) { - System.err.println(" Got: range=" - + lr.getRange() + ", weight=" + lr.getWeight()); - } - } - } - - if (err) { - throw new RuntimeException("Failed."); - } - } - -} - diff --git a/test/jdk/java/util/Locale/Bug8032842.java b/test/jdk/java/util/Locale/Bug8032842.java deleted file mode 100644 index 92f36a6dcfd..00000000000 --- a/test/jdk/java/util/Locale/Bug8032842.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 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. - */ -/* - * @test - * @bug 8032842 8175539 - * @summary Checks that the filterTags() and lookup() methods - * preserve the case of matching language tag(s). - * Before 8032842 fix these methods return the matching - * language tag(s) in lowercase. - * Also, checks the filterTags() to return only unique - * (ignoring case considerations) matching tags. - * - */ - -import java.util.List; -import java.util.Locale; -import java.util.Locale.FilteringMode; -import java.util.Locale.LanguageRange; - -public class Bug8032842 { - - public static void main(String[] args) { - - // test filterBasic() for preserving the case of matching tags for - // the language range '*', with no duplicates in the matching tags - testFilter("*", List.of("de-CH", "hi-in", "En-GB", "ja-Latn-JP", - "JA-JP", "en-GB"), - List.of("de-CH", "hi-in", "En-GB", "ja-Latn-JP", "JA-JP"), - FilteringMode.AUTOSELECT_FILTERING); - - // test filterBasic() for preserving the case of matching tags for - // basic ranges other than *, with no duplicates in the matching tags - testFilter("mtm-RU, en-GB", List.of("En-Gb", "mTm-RU", "en-US", - "en-latn", "en-GB"), - List.of("mTm-RU", "En-Gb"), FilteringMode.AUTOSELECT_FILTERING); - - // test filterExtended() for preserving the case of matching tags for - // the language range '*', with no duplicates in the matching tags - testFilter("*", List.of("de-CH", "hi-in", "En-GB", "hi-IN", - "ja-Latn-JP", "JA-JP"), - List.of("de-CH", "hi-in", "En-GB", "ja-Latn-JP", "JA-JP"), - FilteringMode.EXTENDED_FILTERING); - - // test filterExtended() for preserving the case of matching tags for - // extended ranges other than *, with no duplicates in the matching tags - testFilter("*-ch;q=0.5, *-Latn;q=0.4", List.of("fr-CH", "de-Ch", - "en-latn", "en-US", "en-Latn"), - List.of("fr-CH", "de-Ch", "en-latn"), - FilteringMode.EXTENDED_FILTERING); - - // test lookupTag() for preserving the case of matching tag - testLookup("*-ch;q=0.5", List.of("en", "fR-cH"), "fR-cH"); - - } - - public static void testFilter(String ranges, List tags, - List expected, FilteringMode mode) { - List priorityList = LanguageRange.parse(ranges); - List actual = Locale.filterTags(priorityList, tags, mode); - if (!actual.equals(expected)) { - throw new RuntimeException("[filterTags() failed for the language" - + " range: " + ranges + ", Expected: " + expected - + ", Found: " + actual + "]"); - } - } - - public static void testLookup(String ranges, List tags, - String expected) { - List priorityList = LanguageRange.parse(ranges); - String actual = Locale.lookupTag(priorityList, tags); - if (!actual.equals(expected)) { - throw new RuntimeException("[lookupTag() failed for the language" - + " range: " + ranges + ", Expected: " + expected - + ", Found: " + actual + "]"); - } - } - -} - diff --git a/test/jdk/java/util/Locale/Bug8008577.java b/test/jdk/java/util/Locale/ExpectedAdapterTypes.java similarity index 59% rename from test/jdk/java/util/Locale/Bug8008577.java rename to test/jdk/java/util/Locale/ExpectedAdapterTypes.java index ee267ecfa06..60c24b01fb5 100644 --- a/test/jdk/java/util/Locale/Bug8008577.java +++ b/test/jdk/java/util/Locale/ExpectedAdapterTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, 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,27 +25,36 @@ * @test * @bug 8008577 8138613 * @summary Check whether CLDR locale provider adapter is enabled by default - * @compile -XDignore.symbol.file Bug8008577.java + * @compile -XDignore.symbol.file ExpectedAdapterTypes.java * @modules java.base/sun.util.locale.provider - * @run main Bug8008577 + * @run junit ExpectedAdapterTypes */ import java.util.Arrays; import java.util.List; import sun.util.locale.provider.LocaleProviderAdapter; -public class Bug8008577 { +import org.junit.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ExpectedAdapterTypes { static final LocaleProviderAdapter.Type[] expected = { LocaleProviderAdapter.Type.CLDR, LocaleProviderAdapter.Type.JRE, }; - public static void main(String[] args) { - List types = LocaleProviderAdapter.getAdapterPreference(); - List expectedList = Arrays.asList(expected); - if (!types.equals(expectedList)) { - throw new RuntimeException("Default locale provider adapter list is incorrect"); - } + /** + * This test ensures LocaleProviderAdapter.getAdapterPreference() returns + * the correct preferred adapter types. This test should fail whenever a change is made + * to the implementation and the expected list is not updated accordingly. + */ + @Test + public void correctAdapterListTest() { + List actualTypes = LocaleProviderAdapter.getAdapterPreference(); + List expectedTypes = Arrays.asList(expected); + assertEquals(actualTypes, expectedTypes, String.format("getAdapterPreference() " + + "returns: %s, but the expected adapter list returns: %s", actualTypes, expectedTypes)); } } diff --git a/test/jdk/java/util/Locale/Bug8071929.java b/test/jdk/java/util/Locale/ISO3166.java similarity index 93% rename from test/jdk/java/util/Locale/Bug8071929.java rename to test/jdk/java/util/Locale/ISO3166.java index 19a316ac217..7472ea1a4a4 100644 --- a/test/jdk/java/util/Locale/Bug8071929.java +++ b/test/jdk/java/util/Locale/ISO3166.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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,7 +27,9 @@ * @summary Test obsolete ISO3166-1 alpha-2 country codes should not be retrieved. * ISO3166-1 alpha-2, ISO3166-1 alpha-3, ISO3166-3 country codes * from overloaded getISOCountries(Iso3166 type) are retrieved correctly. + * @run junit ISO3166 */ + import java.util.HashSet; import java.util.List; import java.util.Locale; @@ -35,7 +37,9 @@ import java.util.Set; import java.util.stream.Collectors; -public class Bug8071929 { +import org.junit.jupiter.api.Test; + +public class ISO3166 { private static final List ISO3166_1_ALPHA2_OBSOLETE_CODES = List.of("AN", "BU", "CS", "NT", "SF", "TP", "YU", "ZR"); @@ -78,7 +82,8 @@ public class Bug8071929 { * This method checks that obsolete ISO3166-1 alpha-2 country codes are not * retrieved in output of getISOCountries() method. */ - private static void checkISO3166_1_Alpha2ObsoleteCodes() { + @Test + public void checkISO3166_1_Alpha2ObsoleteCodes() { Set unexpectedCodes = ISO3166_1_ALPHA2_OBSOLETE_CODES.stream(). filter(Set.of(Locale.getISOCountries())::contains).collect(Collectors.toSet()); if (!unexpectedCodes.isEmpty()) { @@ -91,7 +96,8 @@ private static void checkISO3166_1_Alpha2ObsoleteCodes() { * This method checks that ISO3166-3 country codes which are PART3 of * IsoCountryCode enum, are retrieved correctly. */ - private static void checkISO3166_3Codes() { + @Test + public void checkISO3166_3Codes() { Set iso3166_3Codes = Locale.getISOCountries(IsoCountryCode.PART3); if (!iso3166_3Codes.equals(ISO3166_3EXPECTED)) { reportDifference(iso3166_3Codes, ISO3166_3EXPECTED); @@ -102,7 +108,8 @@ private static void checkISO3166_3Codes() { * This method checks that ISO3166-1 alpha-3 country codes which are * PART1_ALPHA3 of IsoCountryCode enum, are retrieved correctly. */ - private static void checkISO3166_1_Alpha3Codes() { + @Test + public void checkISO3166_1_Alpha3Codes() { Set iso3166_1_Alpha3Codes = Locale.getISOCountries(IsoCountryCode.PART1_ALPHA3); if (!iso3166_1_Alpha3Codes.equals(ISO3166_1_ALPHA3_EXPECTED)) { reportDifference(iso3166_1_Alpha3Codes, ISO3166_1_ALPHA3_EXPECTED); @@ -113,7 +120,8 @@ private static void checkISO3166_1_Alpha3Codes() { * This method checks that ISO3166-1 alpha-2 country codes, which are * PART1_ALPHA2 of IsoCountryCode enum, are retrieved correctly. */ - private static void checkISO3166_1_Alpha2Codes() { + @Test + public void checkISO3166_1_Alpha2Codes() { Set iso3166_1_Alpha2Codes = Locale.getISOCountries(IsoCountryCode.PART1_ALPHA2); Set ISO3166_1_ALPHA2_EXPECTED = Set.of(Locale.getISOCountries()); if (!iso3166_1_Alpha2Codes.equals(ISO3166_1_ALPHA2_EXPECTED)) { @@ -139,11 +147,4 @@ private static void reportDifference(Set retrievedCountrySet, Set expectedISO639Codes() { + return Stream.of( + Arguments.of("aa","aar","aar"), + Arguments.of("ab","abk","abk"), + Arguments.of("af","afr","afr"), + Arguments.of("ak","aka","aka"), + Arguments.of("sq","sqi","alb"), + Arguments.of("am","amh","amh"), + Arguments.of("ar","ara","ara"), + Arguments.of("an","arg","arg"), + Arguments.of("hy","hye","arm"), + Arguments.of("as","asm","asm"), + Arguments.of("av","ava","ava"), + Arguments.of("ae","ave","ave"), + Arguments.of("ay","aym","aym"), + Arguments.of("az","aze","aze"), + Arguments.of("ba","bak","bak"), + Arguments.of("bm","bam","bam"), + Arguments.of("eu","eus","baq"), + Arguments.of("be","bel","bel"), + Arguments.of("bn","ben","ben"), + Arguments.of("bh","bih","bih"), + Arguments.of("bi","bis","bis"), + Arguments.of("bs","bos","bos"), + Arguments.of("br","bre","bre"), + Arguments.of("bg","bul","bul"), + Arguments.of("my","mya","bur"), + Arguments.of("ca","cat","cat"), + Arguments.of("ch","cha","cha"), + Arguments.of("ce","che","che"), + Arguments.of("zh","zho","chi"), + Arguments.of("cu","chu","chu"), + Arguments.of("cv","chv","chv"), + Arguments.of("kw","cor","cor"), + Arguments.of("co","cos","cos"), + Arguments.of("cr","cre","cre"), + Arguments.of("cs","ces","cze"), + Arguments.of("da","dan","dan"), + Arguments.of("dv","div","div"), + Arguments.of("nl","nld","dut"), + Arguments.of("dz","dzo","dzo"), + Arguments.of("en","eng","eng"), + Arguments.of("eo","epo","epo"), + Arguments.of("et","est","est"), + Arguments.of("ee","ewe","ewe"), + Arguments.of("fo","fao","fao"), + Arguments.of("fj","fij","fij"), + Arguments.of("fi","fin","fin"), + Arguments.of("fr","fra","fre"), + Arguments.of("fy","fry","fry"), + Arguments.of("ff","ful","ful"), + Arguments.of("ka","kat","geo"), + Arguments.of("de","deu","ger"), + Arguments.of("gd","gla","gla"), + Arguments.of("ga","gle","gle"), + Arguments.of("gl","glg","glg"), + Arguments.of("gv","glv","glv"), + Arguments.of("el","ell","gre"), + Arguments.of("gn","grn","grn"), + Arguments.of("gu","guj","guj"), + Arguments.of("ht","hat","hat"), + Arguments.of("ha","hau","hau"), + Arguments.of("he","heb","heb"), + Arguments.of("hz","her","her"), + Arguments.of("hi","hin","hin"), + Arguments.of("ho","hmo","hmo"), + Arguments.of("hr","hrv","hrv"), + Arguments.of("hu","hun","hun"), + Arguments.of("ig","ibo","ibo"), + Arguments.of("is","isl","ice"), + Arguments.of("io","ido","ido"), + Arguments.of("ii","iii","iii"), + Arguments.of("iu","iku","iku"), + Arguments.of("ie","ile","ile"), + Arguments.of("ia","ina","ina"), + Arguments.of("id","ind","ind"), + Arguments.of("ik","ipk","ipk"), + Arguments.of("it","ita","ita"), + Arguments.of("jv","jav","jav"), + Arguments.of("ja","jpn","jpn"), + Arguments.of("kl","kal","kal"), + Arguments.of("kn","kan","kan"), + Arguments.of("ks","kas","kas"), + Arguments.of("kr","kau","kau"), + Arguments.of("kk","kaz","kaz"), + Arguments.of("km","khm","khm"), + Arguments.of("ki","kik","kik"), + Arguments.of("rw","kin","kin"), + Arguments.of("ky","kir","kir"), + Arguments.of("kv","kom","kom"), + Arguments.of("kg","kon","kon"), + Arguments.of("ko","kor","kor"), + Arguments.of("kj","kua","kua"), + Arguments.of("ku","kur","kur"), + Arguments.of("lo","lao","lao"), + Arguments.of("la","lat","lat"), + Arguments.of("lv","lav","lav"), + Arguments.of("li","lim","lim"), + Arguments.of("ln","lin","lin"), + Arguments.of("lt","lit","lit"), + Arguments.of("lb","ltz","ltz"), + Arguments.of("lu","lub","lub"), + Arguments.of("lg","lug","lug"), + Arguments.of("mk","mkd","mac"), + Arguments.of("mh","mah","mah"), + Arguments.of("ml","mal","mal"), + Arguments.of("mi","mri","mao"), + Arguments.of("mr","mar","mar"), + Arguments.of("ms","msa","may"), + Arguments.of("mg","mlg","mlg"), + Arguments.of("mt","mlt","mlt"), + Arguments.of("mn","mon","mon"), + Arguments.of("na","nau","nau"), + Arguments.of("nv","nav","nav"), + Arguments.of("nr","nbl","nbl"), + Arguments.of("nd","nde","nde"), + Arguments.of("ng","ndo","ndo"), + Arguments.of("ne","nep","nep"), + Arguments.of("nn","nno","nno"), + Arguments.of("nb","nob","nob"), + Arguments.of("no","nor","nor"), + Arguments.of("ny","nya","nya"), + Arguments.of("oc","oci","oci"), + Arguments.of("oj","oji","oji"), + Arguments.of("or","ori","ori"), + Arguments.of("om","orm","orm"), + Arguments.of("os","oss","oss"), + Arguments.of("pa","pan","pan"), + Arguments.of("fa","fas","per"), + Arguments.of("pi","pli","pli"), + Arguments.of("pl","pol","pol"), + Arguments.of("pt","por","por"), + Arguments.of("ps","pus","pus"), + Arguments.of("qu","que","que"), + Arguments.of("rm","roh","roh"), + Arguments.of("ro","ron","rum"), + Arguments.of("rn","run","run"), + Arguments.of("ru","rus","rus"), + Arguments.of("sg","sag","sag"), + Arguments.of("sa","san","san"), + Arguments.of("si","sin","sin"), + Arguments.of("sk","slk","slo"), + Arguments.of("sl","slv","slv"), + Arguments.of("se","sme","sme"), + Arguments.of("sm","smo","smo"), + Arguments.of("sn","sna","sna"), + Arguments.of("sd","snd","snd"), + Arguments.of("so","som","som"), + Arguments.of("st","sot","sot"), + Arguments.of("es","spa","spa"), + Arguments.of("sc","srd","srd"), + Arguments.of("sr","srp","srp"), + Arguments.of("ss","ssw","ssw"), + Arguments.of("su","sun","sun"), + Arguments.of("sw","swa","swa"), + Arguments.of("sv","swe","swe"), + Arguments.of("ty","tah","tah"), + Arguments.of("ta","tam","tam"), + Arguments.of("tt","tat","tat"), + Arguments.of("te","tel","tel"), + Arguments.of("tg","tgk","tgk"), + Arguments.of("tl","tgl","tgl"), + Arguments.of("th","tha","tha"), + Arguments.of("bo","bod","tib"), + Arguments.of("ti","tir","tir"), + Arguments.of("to","ton","ton"), + Arguments.of("tn","tsn","tsn"), + Arguments.of("ts","tso","tso"), + Arguments.of("tk","tuk","tuk"), + Arguments.of("tr","tur","tur"), + Arguments.of("tw","twi","twi"), + Arguments.of("ug","uig","uig"), + Arguments.of("uk","ukr","ukr"), + Arguments.of("ur","urd","urd"), + Arguments.of("uz","uzb","uzb"), + Arguments.of("ve","ven","ven"), + Arguments.of("vi","vie","vie"), + Arguments.of("vo","vol","vol"), + Arguments.of("cy","cym","wel"), + Arguments.of("wa","wln","wln"), + Arguments.of("wo","wol","wol"), + Arguments.of("xh","xho","xho"), + Arguments.of("yi","yid","yid"), + Arguments.of("yo","yor","yor"), + Arguments.of("za","zha","zha"), + Arguments.of("zu","zul","zul") + ); + } + + @Test + @Disabled("For updating expected ISO data, NOT an actual test") + public void getISOData() { + // Remove @Disabled to generate new ISO Data + generateTables(); + } + + private static final String ISO639 = "ISO-639-2_utf-8.txt"; + private static void generateTables() { + try { + BufferedReader ISO639File = new BufferedReader(new FileReader(ISO639)); + for (String line = ISO639File.readLine(); line != null; line = ISO639File.readLine()) { + String[] tokens= line.split("\\|"); + String iso639_1 = tokens[2]; + String iso639_2B = tokens[1]; + String iso639_2T = tokens[0]; + if (iso639_1.isEmpty()){ + continue; // Skip if not both a 639-1 and 639-2 code + } + if (iso639_2B.isEmpty()){ + iso639_2B = iso639_2T; // Default 639/B to 639/T if empty + } + System.out.printf(""" + Arguments.of("%s","%s","%s"), + """, iso639_1, iso639_2B, iso639_2T); + } + } catch (Exception e) { + System.out.println(e); + } + } +} diff --git a/test/jdk/java/util/Locale/Bug8001562.java b/test/jdk/java/util/Locale/JDK7LocaleServiceDiffs.java similarity index 71% rename from test/jdk/java/util/Locale/Bug8001562.java rename to test/jdk/java/util/Locale/JDK7LocaleServiceDiffs.java index be53600a84d..a9acb23d10f 100644 --- a/test/jdk/java/util/Locale/Bug8001562.java +++ b/test/jdk/java/util/Locale/JDK7LocaleServiceDiffs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, 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,9 +25,9 @@ * @test * @bug 8001562 * @summary Verify that getAvailableLocales() in locale sensitive services - * classes return compatible set of locales as in JDK7. + * classes return compatible set of locales as in JDK7. * @modules jdk.localedata - * @run main Bug8001562 + * @run junit JDK7LocaleServiceDiffs */ import java.text.BreakIterator; @@ -40,8 +40,13 @@ import java.util.List; import java.util.Locale; import java.util.stream.Collectors; +import java.util.stream.Stream; -public class Bug8001562 { +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class JDK7LocaleServiceDiffs { static final List jdk7availTags = List.of( "ar", "ar-AE", "ar-BH", "ar-DZ", "ar-EG", "ar-IQ", "ar-JO", "ar-KW", @@ -72,27 +77,16 @@ public class Bug8001562 { .collect(Collectors.toList()); } - public static void main(String[] args) { - List avail = Arrays.asList(BreakIterator.getAvailableLocales()); - diffLocale(BreakIterator.class, avail); - - avail = Arrays.asList(Collator.getAvailableLocales()); - diffLocale(Collator.class, avail); - - avail = Arrays.asList(DateFormat.getAvailableLocales()); - diffLocale(DateFormat.class, avail); - - avail = Arrays.asList(DateFormatSymbols.getAvailableLocales()); - diffLocale(DateFormatSymbols.class, avail); - - avail = Arrays.asList(DecimalFormatSymbols.getAvailableLocales()); - diffLocale(DecimalFormatSymbols.class, avail); - - avail = Arrays.asList(NumberFormat.getAvailableLocales()); - diffLocale(NumberFormat.class, avail); - - avail = Arrays.asList(Locale.getAvailableLocales()); - diffLocale(Locale.class, avail); + /** + * This test compares the locales returned by getAvailableLocales() from a + * locale sensitive service to the available JDK7 locales. If the locales from + * a locale sensitive service are found to not contain a JDK7 available tag, + * the test will fail. + */ + @ParameterizedTest + @MethodSource("serviceProvider") + public void compatibleLocalesTest(Class c, List locs) { + diffLocale(c, locs); } static void diffLocale(Class c, List locs) { @@ -119,4 +113,16 @@ static void diffLocale(Class c, List locs) { throw new RuntimeException("Above locale(s) were not included in the target available locales"); } } + + private static Stream serviceProvider() { + return Stream.of( + Arguments.of(BreakIterator.class, Arrays.asList(BreakIterator.getAvailableLocales())), + Arguments.of(Collator.class, Arrays.asList(Collator.getAvailableLocales())), + Arguments.of(DateFormat.class, Arrays.asList(DateFormat.getAvailableLocales())), + Arguments.of(DateFormatSymbols.class, Arrays.asList(DateFormatSymbols.getAvailableLocales())), + Arguments.of(DecimalFormatSymbols.class, Arrays.asList(DecimalFormatSymbols.getAvailableLocales())), + Arguments.of(NumberFormat.class, Arrays.asList(NumberFormat.getAvailableLocales())), + Arguments.of(Locale.class, Arrays.asList(Locale.getAvailableLocales())) + ); + } } diff --git a/test/jdk/java/util/Locale/LRToString.java b/test/jdk/java/util/Locale/LRToString.java new file mode 100644 index 00000000000..229507b71b3 --- /dev/null +++ b/test/jdk/java/util/Locale/LRToString.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016, 2023, 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 8026766 + * @summary Confirm that LanguageRange.toString() returns an expected result. + * @run junit LRToString + */ + +import java.util.Locale.LanguageRange; +import java.util.stream.Stream; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class LRToString { + + /** + * This test ensures that the output of LanguageRange.toString() + * returns an expected result, that is, the weight is hidden if it is + * equal to 1.0. + */ + @ParameterizedTest + @MethodSource("ranges") + public void toStringTest(String range, double weight) { + LanguageRange lr = new LanguageRange(range, weight); + String expected = weight == 1.0 + ? range + : range+";q="+weight; + assertEquals(lr.toString(), expected); + } + + private static Stream ranges() { + return Stream.of( + Arguments.of("ja", 1.0), + Arguments.of("de", 0.5), + Arguments.of("fr", 0.0) + ); + } +} diff --git a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java index a617aeb02cd..04a6e89db7b 100644 --- a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java +++ b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, 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 @@ -23,10 +23,11 @@ /* * @test - * @bug 8040211 8191404 8203872 8222980 8225435 8241082 8242010 8247432 - * 8258795 8267038 + * @bug 8025703 8040211 8191404 8203872 8222980 8225435 8241082 8242010 8247432 + * 8258795 8267038 8287180 8302512 8304761 8306031 8308021 8313702 8318322 + * 8327631 * @summary Checks the IANA language subtag registry data update - * (LSR Revision: 2022-08-08) with Locale and Locale.LanguageRange + * (LSR Revision: 2024-03-07) with Locale and Locale.LanguageRange * class methods. * @run main LanguageSubtagRegistryTest */ @@ -44,10 +45,10 @@ public class LanguageSubtagRegistryTest { static boolean err = false; private static final String ACCEPT_LANGUAGE = - "Accept-Language: aam, adp, aeb, ajs, aog, aue, bcg, bic, bpp, cey, cnp, cqu, csp, csx, dif, dmw, dsz, ehs, ema," - + " en-gb-oed, gti, iba, jks, kdz, kmb, koj, kru, ksp, kwq, kxe, kzk, lii, lmm, lsb, lsc, lsn, lsv, lsw, lvi, mtm," - + " ngv, nns, ola, oyb, pat, phr, pnd, pub, rib, rnb, rsn, scv, snz, sqx, suj, szy, taj, tjj, tjp, tvx," - + " uss, uth, ysm, wkr;q=0.9, ar-hyw;q=0.8, yug;q=0.5, gfx;q=0.4"; + "Accept-Language: aam, adp, aeb, ajs, aog, apc, ajp, aue, bcg, bic, bpp, cey, cbr, cnp, cqu, crr, csp, csx, dif, dmw, dsz, ehs, ema," + + " en-gb-oed, gti, iba, ilw, jks, kdz, kjh, kmb, koj, kru, ksp, kwq, kxe, kzk, lgs, lii, lmm, lsb, lsc, lsn, lsv, lsw, lvi, meg, mtm," + + " ngv, nns, ola, oyb, pat, pcr, phr, plu, pnd, pub, rib, rnb, rsn, scv, snz, sqx, suj, szy, taj, tdg, tjj, tjp, tpn, tvx," + + " umi, uss, uth, xia, yos, ysm, zko, wkr;q=0.9, ar-hyw;q=0.8, yug;q=0.5, gfx;q=0.4"; private static final List EXPECTED_RANGE_LIST = List.of( new LanguageRange("aam", 1.0), new LanguageRange("aas", 1.0), @@ -60,6 +61,10 @@ public class LanguageSubtagRegistryTest { new LanguageRange("sgn-ajs", 1.0), new LanguageRange("aog", 1.0), new LanguageRange("myd", 1.0), + new LanguageRange("apc", 1.0), + new LanguageRange("ar-apc", 1.0), + new LanguageRange("ar-ajp", 1.0), + new LanguageRange("ajp", 1.0), new LanguageRange("aue", 1.0), new LanguageRange("ktz", 1.0), new LanguageRange("bcg", 1.0), @@ -69,10 +74,14 @@ public class LanguageSubtagRegistryTest { new LanguageRange("bpp", 1.0), new LanguageRange("nxu", 1.0), new LanguageRange("cey", 1.0), + new LanguageRange("cbr", 1.0), + new LanguageRange("nom", 1.0), new LanguageRange("cnp", 1.0), new LanguageRange("zh-cnp", 1.0), new LanguageRange("cqu", 1.0), new LanguageRange("quh", 1.0), + new LanguageRange("crr", 1.0), + new LanguageRange("pmk", 1.0), new LanguageRange("csp", 1.0), new LanguageRange("zh-csp", 1.0), new LanguageRange("csx", 1.0), @@ -94,10 +103,14 @@ public class LanguageSubtagRegistryTest { new LanguageRange("iba", 1.0), new LanguageRange("snb", 1.0), new LanguageRange("blg", 1.0), + new LanguageRange("ilw", 1.0), + new LanguageRange("gal", 1.0), new LanguageRange("jks", 1.0), new LanguageRange("sgn-jks", 1.0), new LanguageRange("kdz", 1.0), new LanguageRange("ncp", 1.0), + new LanguageRange("kjh", 1.0), + new LanguageRange("zkb", 1.0), new LanguageRange("kmb", 1.0), new LanguageRange("smd", 1.0), new LanguageRange("koj", 1.0), @@ -113,6 +126,8 @@ public class LanguageSubtagRegistryTest { new LanguageRange("kzk", 1.0), new LanguageRange("gli", 1.0), new LanguageRange("drr", 1.0), + new LanguageRange("lgs", 1.0), + new LanguageRange("sgn-lgs", 1.0), new LanguageRange("lii", 1.0), new LanguageRange("raq", 1.0), new LanguageRange("lmm", 1.0), @@ -128,6 +143,8 @@ public class LanguageSubtagRegistryTest { new LanguageRange("lsw", 1.0), new LanguageRange("sgn-lsw", 1.0), new LanguageRange("lvi", 1.0), + new LanguageRange("meg", 1.0), + new LanguageRange("cir", 1.0), new LanguageRange("mtm", 1.0), new LanguageRange("ymt", 1.0), new LanguageRange("ngv", 1.0), @@ -142,8 +159,12 @@ public class LanguageSubtagRegistryTest { new LanguageRange("jeg", 1.0), new LanguageRange("pat", 1.0), new LanguageRange("kxr", 1.0), + new LanguageRange("pcr", 1.0), + new LanguageRange("adx", 1.0), new LanguageRange("phr", 1.0), new LanguageRange("pmu", 1.0), + new LanguageRange("plu", 1.0), + new LanguageRange("kgm", 1.0), new LanguageRange("pnd", 1.0), new LanguageRange("pub", 1.0), new LanguageRange("puz", 1.0), @@ -163,13 +184,25 @@ public class LanguageSubtagRegistryTest { new LanguageRange("szy", 1.0), new LanguageRange("taj", 1.0), new LanguageRange("tsf", 1.0), + new LanguageRange("tdg", 1.0), + new LanguageRange("tmk", 1.0), new LanguageRange("tjj", 1.0), new LanguageRange("tjp", 1.0), + new LanguageRange("tpn", 1.0), + new LanguageRange("tpw", 1.0), new LanguageRange("tvx", 1.0), + new LanguageRange("umi", 1.0), + new LanguageRange("szd", 1.0), new LanguageRange("uss", 1.0), new LanguageRange("uth", 1.0), + new LanguageRange("xia", 1.0), + new LanguageRange("acn", 1.0), + new LanguageRange("yos", 1.0), + new LanguageRange("zom", 1.0), new LanguageRange("ysm", 1.0), new LanguageRange("sgn-ysm", 1.0), + new LanguageRange("zko", 1.0), + new LanguageRange("xss", 1.0), new LanguageRange("wkr", 0.9), new LanguageRange("ar-hyw", 0.8), new LanguageRange("yug", 0.5), diff --git a/test/jdk/java/util/Locale/PreserveTagCase.java b/test/jdk/java/util/Locale/PreserveTagCase.java new file mode 100644 index 00000000000..c5535e3a89f --- /dev/null +++ b/test/jdk/java/util/Locale/PreserveTagCase.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2017, 2023, 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 8032842 8175539 + * @summary Checks that the filterTags() and lookup() methods + * preserve the case of matching language tag(s). + * Before 8032842 fix these methods return the matching + * language tag(s) in lowercase. + * Also, checks the filterTags() to return only unique + * (ignoring case considerations) matching tags. + * @run junit PreserveTagCase + */ + +import java.util.List; +import java.util.Locale; +import java.util.Locale.FilteringMode; +import java.util.Locale.LanguageRange; +import java.util.stream.Stream; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class PreserveTagCase { + + /** + * This test ensures that Locale.filterTags() preserves the case of matching + * language tag(s). + */ + @ParameterizedTest + @MethodSource("filterProvider") + public static void testFilterTags(String ranges, List tags, + List expected, FilteringMode mode) { + List priorityList = LanguageRange.parse(ranges); + List actual = Locale.filterTags(priorityList, tags, mode); + assertEquals(actual, expected, String.format("[filterTags() failed for " + + "the language range: %s, Expected: %s, Found: %s]", ranges, expected, actual)); + } + + /** + * This test ensures that Locale.lookupTag() preserves the case of matching + * language tag(s). + */ + @ParameterizedTest + @MethodSource("lookupProvider") + public static void testLookupTag(String ranges, List tags, + String expected) { + List priorityList = LanguageRange.parse(ranges); + String actual = Locale.lookupTag(priorityList, tags); + assertEquals(actual, expected, String.format("[lookupTags() failed for " + + "the language range: %s, Expected: %s, Found: %s]", ranges, expected, actual)); + } + + private static Stream filterProvider() { + return Stream.of( + // test filterBasic() for preserving the case of matching tags for + // the language range '*', with no duplicates in the matching tags + Arguments.of("*", + List.of("de-CH", "hi-in", "En-GB", "ja-Latn-JP", "JA-JP", "en-GB"), + List.of("de-CH", "hi-in", "En-GB", "ja-Latn-JP", "JA-JP"), + FilteringMode.AUTOSELECT_FILTERING), + // test filterBasic() for preserving the case of matching tags for + // basic ranges other than *, with no duplicates in the matching tags + Arguments.of("mtm-RU, en-GB", + List.of("En-Gb", "mTm-RU", "en-US", "en-latn", "en-GB"), + List.of("mTm-RU", "En-Gb"), + FilteringMode.AUTOSELECT_FILTERING), + // test filterExtended() for preserving the case of matching tags for + // the language range '*', with no duplicates in the matching tags + Arguments.of("*", + List.of("de-CH", "hi-in", "En-GB", "hi-IN", "ja-Latn-JP", "JA-JP"), + List.of("de-CH", "hi-in", "En-GB", "ja-Latn-JP", "JA-JP"), + FilteringMode.EXTENDED_FILTERING), + // test filterExtended() for preserving the case of matching tags for + // extended ranges other than *, with no duplicates in the matching tags + Arguments.of("*-ch;q=0.5, *-Latn;q=0.4", + List.of("fr-CH", "de-Ch", "en-latn", "en-US", "en-Latn"), + List.of("fr-CH", "de-Ch", "en-latn"), + FilteringMode.EXTENDED_FILTERING) + ); + } + + private static Stream lookupProvider() { + return Stream.of( + // test lookupTag() for preserving the case of matching tag + Arguments.of("*-ch;q=0.5", List.of("en", "fR-cH"), "fR-cH"), + Arguments.of("*-Latn;q=0.4", List.of("en", "fR-LATn"), "fR-LATn") + ); + } +} diff --git a/test/jdk/java/util/TimeZone/TimeZoneData/VERSION b/test/jdk/java/util/TimeZone/TimeZoneData/VERSION index f92096d49aa..bf027918ce7 100644 --- a/test/jdk/java/util/TimeZone/TimeZoneData/VERSION +++ b/test/jdk/java/util/TimeZone/TimeZoneData/VERSION @@ -1 +1 @@ -tzdata2023d +tzdata2024a diff --git a/test/jdk/java/util/concurrent/ConcurrentLinkedQueue/WhiteBox.java b/test/jdk/java/util/concurrent/ConcurrentLinkedQueue/WhiteBox.java index 63fd29a8a9a..2ea188aed46 100644 --- a/test/jdk/java/util/concurrent/ConcurrentLinkedQueue/WhiteBox.java +++ b/test/jdk/java/util/concurrent/ConcurrentLinkedQueue/WhiteBox.java @@ -281,36 +281,6 @@ public void pollActionsOneNodeSlack( assertInvariants(q); } - /** - * Actions that append an element, and are expected to - * leave at most one slack node at tail. - */ - @DataProvider - public Object[][] addActions() { - return List.>of( - q -> q.add(1), - q -> q.offer(1)) - .stream().map(x -> new Object[]{ x }).toArray(Object[][]::new); - } - - @Test(dataProvider = "addActions") - public void addActionsOneNodeSlack( - Consumer addAction) { - ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); - int n = 1 + rnd.nextInt(5); - for (int i = 0; i < n; i++) { - boolean slack = next(tail(q)) != null; - addAction.accept(q); - if (slack) - assertNull(next(tail(q))); - else { - assertNotNull(next(tail(q))); - assertNull(next(next(tail(q)))); - } - assertInvariants(q); - } - } - byte[] serialBytes(Object o) { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); diff --git a/test/jdk/java/util/prefs/AddNodeChangeListener.java b/test/jdk/java/util/prefs/AddNodeChangeListener.java index d63ffed36b7..11a771f93e3 100644 --- a/test/jdk/java/util/prefs/AddNodeChangeListener.java +++ b/test/jdk/java/util/prefs/AddNodeChangeListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, 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 @@ -34,75 +34,88 @@ public class AddNodeChangeListener { private static final int SLEEP_ITRS = 10; + private static final String N2_STR = "N2"; private static boolean failed = false; private static Preferences userRoot, N2; private static NodeChangeListenerAdd ncla; public static void main(String[] args) throws BackingStoreException, InterruptedException { - userRoot = Preferences.userRoot(); - ncla = new NodeChangeListenerAdd(); - userRoot.addNodeChangeListener(ncla); - //Should initiate a node added event - addNode(); - // Should not initiate a node added event - addNode(); - //Should initate a child removed event - removeNode(); - - if (failed) { - throw new RuntimeException("Failed"); + try { + userRoot = Preferences.userRoot(); + // Make sure test node is not present before test + clearPrefs(); + + ncla = new NodeChangeListenerAdd(); + userRoot.addNodeChangeListener(ncla); + //Should initiate a node added event + addNode(); + // Should not initiate a node added event + addNode(); + //Should initate a child removed event + removeNode(); + + if (failed) { + throw new RuntimeException("Failed"); + } + } finally { + // Make sure test node is not present after the test + clearPrefs(); } } private static void addNode() throws BackingStoreException, InterruptedException { - N2 = userRoot.node("N2"); + N2 = userRoot.node(N2_STR); userRoot.flush(); - int passItr = -1; - - for (int i = 0; i < SLEEP_ITRS; i++) { - System.out.print("addNode sleep iteration " + i + "..."); - Thread.sleep(3000); - System.out.println("done."); - if (ncla.getAddNumber() == 1) { - passItr = i; - break; - } - } - checkPassItr(passItr, "addNode()"); + checkAndSleep(1, "addNode"); } private static void removeNode() throws BackingStoreException, InterruptedException { N2.removeNode(); userRoot.flush(); - int passItr = -1; + checkAndSleep(0, "removeNode"); + } + /* Check for the expected value in the listener (1 after addNode(), 0 after removeNode()). + * Sleep a few extra times in a loop, if needed, for debugging purposes, to + * see if the event gets delivered late. + */ + private static void checkAndSleep(int expectedListenerVal, String methodName) throws InterruptedException { + int expectedItr = -1; // iteration in which the expected value was retrieved from the listener, or -1 if never for (int i = 0; i < SLEEP_ITRS; i++) { - System.out.print("removeNode sleep iteration " + i + "..."); + System.out.print(methodName + " sleep iteration " + i + "..."); Thread.sleep(3000); System.out.println("done."); - if (ncla.getAddNumber() == 0) { - passItr = i; + if (ncla.getAddNumber() == expectedListenerVal) { + expectedItr = i; break; } } - checkPassItr(passItr, "removeNode()"); - } - /* If the listener wasn't notified on iteration 0, throw a RuntimeException - * with some contextual information - */ - private static void checkPassItr(int itr, String methodName) { - if (itr == 0) { + if (expectedItr == 0) { System.out.println(methodName + " test passed"); } else { failed = true; - if (itr == -1) { - throw new RuntimeException("Failed in " + methodName + " - change listener never notified"); + if (expectedItr == -1) { + System.out.println("Failed in " + methodName + " - change listener never notified"); } else { - throw new RuntimeException("Failed in " + methodName + " - listener notified on iteration " + itr); + System.out.println("Failed in " + methodName + " - listener notified on iteration " + expectedItr); + } + } + } + + /* Check if the node already exists in userRoot, and remove it if so. */ + private static void clearPrefs() throws BackingStoreException { + if (userRoot.nodeExists(N2_STR)) { + System.out.println("Node " + N2_STR + " already/still exists; clearing"); + Preferences clearNode = userRoot.node(N2_STR); + userRoot.flush(); + clearNode.removeNode(); + userRoot.flush(); + if (userRoot.nodeExists(N2_STR)) { + throw new RuntimeException("Unable to clear pre-existing node." + (failed ? " Also, the test failed" : "")); } } } diff --git a/test/jdk/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java b/test/jdk/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java index 72319d72cb9..72ae5766307 100644 --- a/test/jdk/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java +++ b/test/jdk/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2023, 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 @@ -87,7 +87,10 @@ public static void main(String[] args) throws Exception { JMXServiceURL addr = server.getAddress(); JMXConnector client = JMXConnectorFactory.connect(addr, env); - Thread.sleep(100); // let pass the first client open notif if there is + // Sleeping here was an attempt to avoid seeing an initial notification. + // This does not work, but does not matter. + // Thread.sleep(100); + client.getMBeanServerConnection().addNotificationListener(oname, listener, null, @@ -100,12 +103,13 @@ public static void main(String[] args) throws Exception { synchronized(lock) { while(clientState == null && System.currentTimeMillis() < end) { + System.out.println("Calling sendNotifications"); mbs.invoke(oname, "sendNotifications", new Object[] {new Notification("MyType", "", 0)}, new String[] {"javax.management.Notification"}); try { - lock.wait(10); + lock.wait(1000); // sleep as no point in constant notifications } catch (Exception e) {} } } @@ -143,10 +147,10 @@ public interface NotificationEmitterMBean { private final static NotificationListener listener = new NotificationListener() { public void handleNotification(Notification n, Object hb) { - // treat the client notif to know the end + System.out.println("handleNotification: " + n); if (n instanceof JMXConnectionNotification) { if (!JMXConnectionNotification.NOTIFS_LOST.equals(n.getType())) { - + // Expected: [type=jmx.remote.connection.opened][message=Reconnected to server] clientState = n.getType(); System.out.println( ">>> The client state has been changed to: "+clientState); @@ -159,7 +163,7 @@ public void handleNotification(Notification n, Object hb) { return; } - System.out.println(">>> Do sleep to make reconnection."); + System.out.println(">>> sleeping in NotificationListener to force reconnection."); synchronized(lock) { try { lock.wait(listenerSleep); @@ -170,9 +174,11 @@ public void handleNotification(Notification n, Object hb) { } }; - private static final long serverTimeout = 1000; + // serverTimeout increased to avoid occasional problems with initial connect. + // Not using Utils.adjustTimeout to avoid accidentally making it too long. + private static final long serverTimeout = 3000; private static final long listenerSleep = serverTimeout*6; - private static String clientState = null; + private volatile static String clientState = null; private static final int[] lock = new int[0]; } diff --git a/test/jdk/javax/net/ssl/DTLS/DTLSWontNegotiateV10.java b/test/jdk/javax/net/ssl/DTLS/DTLSWontNegotiateV10.java new file mode 100644 index 00000000000..2532f524371 --- /dev/null +++ b/test/jdk/javax/net/ssl/DTLS/DTLSWontNegotiateV10.java @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2023, 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 jdk.test.lib.security.SecurityUtils; + +import javax.net.ssl.*; +import java.io.IOException; +import java.net.*; +import java.nio.ByteBuffer; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +/* + * @test + * @bug 8301381 + * @library /test/lib /javax/net/ssl/templates + * @summary DTLSv10 is now disabled. This test verifies that the server will + * not negotiate a connection if the client asks for it. + * @run main/othervm DTLSWontNegotiateV10 DTLS + * @run main/othervm DTLSWontNegotiateV10 DTLSv1.0 + */ +public class DTLSWontNegotiateV10 { + + private static final int MTU = 1024; + private static final String DTLSV_1_0 = "DTLSv1.0"; + private static final String DTLS = "DTLS"; + private static final String DTLSV_1_2 = "DTLSv1.2"; + + public static void main(String[] args) throws Exception { + if (args[0].equals(DTLSV_1_0)) { + SecurityUtils.removeFromDisabledTlsAlgs(DTLSV_1_0); + } + + if (args.length > 1) { + // running in client child process + // args: protocol server-port + try (DTLSClient client = new DTLSClient(args[0], Integer.parseInt(args[1]))) { + client.run(); + } + + } else { + // server process + // args: protocol + try (DTLSServer server = new DTLSServer(args[0])) { + List command = List.of( + Path.of(System.getProperty("java.home"), "bin", "java").toString(), + "DTLSWontNegotiateV10", + // if server is "DTLS" then the client should be v1.0 and vice versa + args[0].equals(DTLS) ? DTLSV_1_0 : DTLS, + Integer.toString(server.getListeningPortNumber()) + ); + + ProcessBuilder builder = new ProcessBuilder(command); + Process p = builder.inheritIO().start(); + server.run(); + p.destroy(); + System.out.println("Success: DTLSv1.0 connection was not established."); + } + } + } + + private static class DTLSClient extends DTLSEndpoint { + private final int remotePort; + + private final DatagramSocket socket = new DatagramSocket(); + + public DTLSClient(String protocol, int portNumber) throws Exception { + super(true, protocol); + remotePort = portNumber; + log("Enabled protocols: " + String.join(" ", engine.getEnabledProtocols())); + } + + @Override + public void run() throws Exception { + doHandshake(socket); + log("Client done handshaking. Protocol: " + engine.getSession().getProtocol()); + } + + @Override + void setRemotePortNumber(int portNumber) { + // don't do anything; we're using the one we already know + } + + @Override + int getRemotePortNumber() { + return remotePort; + } + + @Override + public void close () { + socket.close(); + } + } + + private abstract static class DTLSEndpoint extends SSLContextTemplate implements AutoCloseable { + protected final SSLEngine engine; + protected final SSLContext context; + private final String protocol; + protected final InetAddress LOCALHOST; + + private final String tag; + + public DTLSEndpoint(boolean useClientMode, String protocol) throws Exception { + this.protocol = protocol; + if (useClientMode) { + tag = "client"; + context = createClientSSLContext(); + } else { + tag = "server"; + context = createServerSSLContext(); + } + engine = context.createSSLEngine(); + engine.setUseClientMode(useClientMode); + SSLParameters params = engine.getSSLParameters(); + params.setMaximumPacketSize(MTU); + engine.setSSLParameters(params); + if (protocol.equals(DTLS)) { + // make sure both versions are "enabled"; 1.0 should be + // disabled by policy now and won't be negotiated. + engine.setEnabledProtocols(new String[]{DTLSV_1_0, DTLSV_1_2}); + } else { + engine.setEnabledProtocols(new String[]{DTLSV_1_0}); + } + + LOCALHOST = InetAddress.getByName("localhost"); + } + + @Override + protected ContextParameters getServerContextParameters() { + return new ContextParameters(protocol, "PKIX", "NewSunX509"); + } + + @Override + protected ContextParameters getClientContextParameters() { + return new ContextParameters(protocol, "PKIX", "NewSunX509"); + } + + + abstract void setRemotePortNumber(int portNumber); + + abstract int getRemotePortNumber(); + + abstract void run() throws Exception; + + private boolean runDelegatedTasks() { + log("Running delegated tasks."); + Runnable runnable; + while ((runnable = engine.getDelegatedTask()) != null) { + runnable.run(); + } + + SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus(); + if (hs == SSLEngineResult.HandshakeStatus.NEED_TASK) { + throw new RuntimeException( + "Handshake shouldn't need additional tasks"); + } + + return true; + } + + protected void doHandshake(DatagramSocket socket) throws Exception { + boolean handshaking = true; + engine.beginHandshake(); + while (handshaking) { + log("Handshake status = " + engine.getHandshakeStatus()); + handshaking = switch (engine.getHandshakeStatus()) { + case NEED_UNWRAP, NEED_UNWRAP_AGAIN -> readFromServer(socket); + case NEED_WRAP -> sendHandshakePackets(socket); + case NEED_TASK -> runDelegatedTasks(); + case NOT_HANDSHAKING, FINISHED -> false; + }; + } + } + + private boolean readFromServer(DatagramSocket socket) throws IOException { + log("Reading data from remote endpoint."); + ByteBuffer iNet, iApp; + if (engine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) { + byte[] buffer = new byte[MTU]; + DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + socket.receive(packet); + setRemotePortNumber(packet.getPort()); + iNet = ByteBuffer.wrap(buffer, 0, packet.getLength()); + iApp = ByteBuffer.allocate(MTU); + } else { + iNet = ByteBuffer.allocate(0); + iApp = ByteBuffer.allocate(MTU); + } + + SSLEngineResult engineResult; + do { + engineResult = engine.unwrap(iNet, iApp); + } while (iNet.hasRemaining()); + + return switch (engineResult.getStatus()) { + case CLOSED -> false; + case OK -> true; + case BUFFER_OVERFLOW -> throw new RuntimeException("Buffer overflow: " + + "incorrect server maximum fragment size"); + case BUFFER_UNDERFLOW -> throw new RuntimeException("Buffer underflow: " + + "incorrect server maximum fragment size"); + }; + } + + private boolean sendHandshakePackets(DatagramSocket socket) throws Exception { + List packets = generateHandshakePackets(); + log("Sending handshake packets."); + packets.forEach((p) -> { + try { + socket.send(p); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + + return true; + } + + private List generateHandshakePackets() throws SSLException { + log("Generating handshake packets."); + List packets = new ArrayList<>(); + ByteBuffer oNet = ByteBuffer.allocate(engine.getSession().getPacketBufferSize()); + ByteBuffer oApp = ByteBuffer.allocate(0); + + while (engine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_WRAP) { + SSLEngineResult result = engine.wrap(oApp, oNet); + oNet.flip(); + + switch (result.getStatus()) { + case BUFFER_UNDERFLOW -> { + if (engine.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) { + throw new RuntimeException("Buffer underflow: " + + "incorrect server maximum fragment size"); + } + } + case BUFFER_OVERFLOW -> throw new RuntimeException("Buffer overflow: " + + "incorrect server maximum fragment size"); + case CLOSED -> throw new RuntimeException("SSLEngine has closed"); + } + + if (oNet.hasRemaining()) { + byte[] packetBuffer = new byte[oNet.remaining()]; + oNet.get(packetBuffer); + packets.add(new DatagramPacket(packetBuffer, packetBuffer.length, + LOCALHOST, getRemotePortNumber())); + } + + runDelegatedTasks(); + oNet.clear(); + } + + log("Generated " + packets.size() + " packets."); + return packets; + } + + protected void log(String msg) { + System.out.println(tag + ": " + msg); + } + } + + private static class DTLSServer extends DTLSEndpoint implements AutoCloseable { + + private final AtomicInteger portNumber = new AtomicInteger(0); + private final DatagramSocket socket = new DatagramSocket(0); + + public DTLSServer(String protocol) throws Exception { + super(false, protocol); + log("Enabled protocols: " + String.join(" ", engine.getEnabledProtocols())); + } + + @Override + public void run() throws Exception { + doHandshake(socket); + if (!engine.getSession().getProtocol().equals("NONE")) { + throw new RuntimeException("Negotiated protocol: " + + engine.getSession().getProtocol() + + ". No protocol should be negotated."); + } + } + + public int getListeningPortNumber() { + return socket.getLocalPort(); + } + + void setRemotePortNumber(int portNumber) { + this.portNumber.compareAndSet(0, portNumber); + } + + int getRemotePortNumber() { + return portNumber.get(); + } + + @Override + public void close() throws Exception { + socket.close(); + } + } +} \ No newline at end of file diff --git a/test/jdk/javax/net/ssl/TLS/TestJSSE.java b/test/jdk/javax/net/ssl/TLS/TestJSSE.java index 2c5a2c6274d..29631064011 100644 --- a/test/jdk/javax/net/ssl/TLS/TestJSSE.java +++ b/test/jdk/javax/net/ssl/TLS/TestJSSE.java @@ -21,12 +21,13 @@ * questions. */ +import java.net.InetAddress; import java.security.Provider; import java.security.Security; public class TestJSSE { - private static final String LOCAL_IP = "127.0.0.1"; + private static final String LOCAL_IP = InetAddress.getLoopbackAddress().getHostAddress(); public static void main(String... args) throws Exception { // reset the security property to make sure that the algorithms diff --git a/test/jdk/javax/net/ssl/TLSv13/EngineOutOfSeqCCS.java b/test/jdk/javax/net/ssl/TLSv13/EngineOutOfSeqCCS.java new file mode 100644 index 00000000000..94a2c0fe311 --- /dev/null +++ b/test/jdk/javax/net/ssl/TLSv13/EngineOutOfSeqCCS.java @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2024, 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 8326643 + * @summary Test for out-of-sequence change_cipher_spec in TLSv1.3 + * @library /javax/net/ssl/templates + * @run main/othervm EngineOutOfSeqCCS + */ + +import java.nio.ByteBuffer; +import javax.net.ssl.SSLEngineResult; +import javax.net.ssl.SSLEngineResult.HandshakeStatus; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLParameters; + +public class EngineOutOfSeqCCS extends SSLEngineTemplate { + + /* + * Enables logging of the SSLEngine operations. + */ + private static final boolean logging = true; + private static final boolean dumpBufs = true; + + // Define a few basic TLS records we might need + private static final int TLS_RECTYPE_CCS = 0x14; + private static final int TLS_RECTYPE_ALERT = 0x15; + private static final int TLS_RECTYPE_HANDSHAKE = 0x16; + private static final int TLS_RECTYPE_APPDATA = 0x17; + + SSLEngineResult clientResult, serverResult; + + public EngineOutOfSeqCCS() throws Exception { + super(); + } + + public static void main(String[] args) throws Exception{ + new EngineOutOfSeqCCS().runDemo(); + } + + private void runDemo() throws Exception { + + // Client generates Client Hello + clientResult = clientEngine.wrap(clientOut, cTOs); + log("client wrap: ", clientResult); + runDelegatedTasks(clientEngine); + cTOs.flip(); + dumpByteBuffer("CLIENT-TO-SERVER", cTOs); + + // Server consumes Client Hello + serverResult = serverEngine.unwrap(cTOs, serverIn); + log("server unwrap: ", serverResult); + runDelegatedTasks(serverEngine); + cTOs.compact(); + + // Server generates ServerHello/HelloRetryRequest + serverResult = serverEngine.wrap(serverOut, sTOc); + log("server wrap: ", serverResult); + runDelegatedTasks(serverEngine); + sTOc.flip(); + + dumpByteBuffer("SERVER-TO-CLIENT", sTOc); + + // client consumes ServerHello/HelloRetryRequest + clientResult = clientEngine.unwrap(sTOc, clientIn); + log("client unwrap: ", clientResult); + runDelegatedTasks(clientEngine); + sTOc.compact(); + + // Server generates CCS + serverResult = serverEngine.wrap(serverOut, sTOc); + log("server wrap: ", serverResult); + runDelegatedTasks(serverEngine); + sTOc.flip(); + dumpByteBuffer("SERVER-TO-CLIENT", sTOc); + + if (isTlsMessage(sTOc, TLS_RECTYPE_CCS)) { + System.out.println("=========== CCS found ==========="); + } else { + // In TLS1.3 middlebox compatibility mode the server sends a + // dummy change_cipher_spec record immediately after its + // first handshake message. This may either be after + // a ServerHello or a HelloRetryRequest. + // (RFC 8446, Appendix D.4) + throw new SSLException( + "Server should generate change_cipher_spec record"); + } + clientEngine.closeOutbound(); + serverEngine.closeOutbound(); + } + + /** + * Look at an incoming TLS record and see if it is the desired + * record type, and where appropriate the correct subtype. + * + * @param srcRecord The input TLS record to be evaluated. This + * method will only look at the leading message if multiple + * TLS handshake messages are coalesced into a single record. + * @param reqRecType The requested TLS record type + * @param recParams Zero or more integer sub type fields. For CCS + * and ApplicationData, no params are used. For handshake records, + * one value corresponding to the HandshakeType is required. + * For Alerts, two values corresponding to AlertLevel and + * AlertDescription are necessary. + * + * @return true if the proper handshake message is the first one + * in the input record, false otherwise. + */ + private boolean isTlsMessage(ByteBuffer srcRecord, int reqRecType, + int... recParams) { + boolean foundMsg = false; + + if (srcRecord.hasRemaining()) { + srcRecord.mark(); + + // Grab the fields from the TLS Record + int recordType = Byte.toUnsignedInt(srcRecord.get()); + byte ver_major = srcRecord.get(); + byte ver_minor = srcRecord.get(); + + if (recordType == reqRecType) { + // For any zero-length recParams, making sure the requested + // type is sufficient. + if (recParams.length == 0) { + foundMsg = true; + } else { + switch (recordType) { + case TLS_RECTYPE_CCS: + case TLS_RECTYPE_APPDATA: + // We really shouldn't find ourselves here, but + // if someone asked for these types and had more + // recParams we can ignore them. + foundMsg = true; + break; + case TLS_RECTYPE_ALERT: + // Needs two params, AlertLevel and + //AlertDescription + if (recParams.length != 2) { + throw new RuntimeException( + "Test for Alert requires level and desc."); + } else { + int level = Byte.toUnsignedInt( + srcRecord.get()); + int desc = Byte.toUnsignedInt(srcRecord.get()); + if (level == recParams[0] && + desc == recParams[1]) { + foundMsg = true; + } + } + break; + case TLS_RECTYPE_HANDSHAKE: + // Needs one parameter, HandshakeType + if (recParams.length != 1) { + throw new RuntimeException( + "Test for Handshake requires only HS type"); + } else { + // Go into the first handshake message in the + // record and grab the handshake message header. + // All we need to do is parse out the leading + // byte. + int msgHdr = srcRecord.getInt(); + int msgType = (msgHdr >> 24) & 0x000000FF; + if (msgType == recParams[0]) { + foundMsg = true; + } + } + break; + } + } + } + + srcRecord.reset(); + } + + return foundMsg; + } + + private static String tlsRecType(int type) { + switch (type) { + case 20: + return "Change Cipher Spec"; + case 21: + return "Alert"; + case 22: + return "Handshake"; + case 23: + return "Application Data"; + default: + return ("Unknown (" + type + ")"); + } + } + + /* + * Logging code + */ + private static boolean resultOnce = true; + + private static void log(String str, SSLEngineResult result) { + if (!logging) { + return; + } + if (resultOnce) { + resultOnce = false; + System.out.println("The format of the SSLEngineResult is: \n" + + "\t\"getStatus() / getHandshakeStatus()\" +\n" + + "\t\"bytesConsumed() / bytesProduced()\"\n"); + } + HandshakeStatus hsStatus = result.getHandshakeStatus(); + log(str + + result.getStatus() + "/" + hsStatus + ", " + + result.bytesConsumed() + "/" + result.bytesProduced() + + " bytes"); + if (hsStatus == HandshakeStatus.FINISHED) { + log("\t...ready for application data"); + } + } + + private static void log(String str) { + if (logging) { + System.out.println(str); + } + } + + /** + * Hex-dumps a ByteBuffer to stdout. + */ + private static void dumpByteBuffer(String header, ByteBuffer bBuf) { + if (!dumpBufs) { + return; + } + + int bufLen = bBuf.remaining(); + if (bufLen > 0) { + bBuf.mark(); + + // We expect the position of the buffer to be at the + // beginning of a TLS record. Get the type, version and length. + int type = Byte.toUnsignedInt(bBuf.get()); + int ver_major = Byte.toUnsignedInt(bBuf.get()); + int ver_minor = Byte.toUnsignedInt(bBuf.get()); + + log("===== " + header + " (" + tlsRecType(type) + " / " + + ver_major + "." + ver_minor + " / " + + bufLen + " bytes) ====="); + bBuf.reset(); + for (int i = 0; i < bufLen; i++) { + if (i != 0 && i % 16 == 0) { + System.out.print("\n"); + } + System.out.format("%02X ", bBuf.get(i)); + } + log("\n==============================================="); + bBuf.reset(); + } + } +} diff --git a/test/jdk/javax/net/ssl/sanity/interop/JSSEClient.java b/test/jdk/javax/net/ssl/sanity/interop/JSSEClient.java index 2207749302d..21416f0aaef 100644 --- a/test/jdk/javax/net/ssl/sanity/interop/JSSEClient.java +++ b/test/jdk/javax/net/ssl/sanity/interop/JSSEClient.java @@ -23,6 +23,7 @@ import java.io.InputStream; import java.io.OutputStream; +import java.net.InetAddress; import java.security.cert.Certificate; import javax.net.ssl.KeyManager; @@ -52,7 +53,8 @@ void runTest(CipherTest.TestParameters params) throws Exception { new TrustManager[] { CipherTest.trustManager }, CipherTest.secureRandom); SSLSocketFactory factory = (SSLSocketFactory)sslContext.getSocketFactory(); - socket = (SSLSocket)factory.createSocket("127.0.0.1", CipherTest.serverPort); + socket = (SSLSocket)factory.createSocket( + InetAddress.getLoopbackAddress().getHostAddress(), CipherTest.serverPort); socket.setSoTimeout(CipherTest.TIMEOUT); socket.setEnabledCipherSuites(new String[] { params.cipherSuite.name() }); socket.setEnabledProtocols(new String[] { params.protocol.name }); diff --git a/test/jdk/javax/rmi/ssl/SSLSocketParametersTest.java b/test/jdk/javax/rmi/ssl/SSLSocketParametersTest.java index e853a32413a..63d9332f353 100644 --- a/test/jdk/javax/rmi/ssl/SSLSocketParametersTest.java +++ b/test/jdk/javax/rmi/ssl/SSLSocketParametersTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2023, 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 @@ -21,6 +21,18 @@ * questions. */ +/* + * @test + * @bug 5016500 + * @summary Test SslRmi[Client|Server]SocketFactory SSL socket parameters. + * @run main/othervm SSLSocketParametersTest 1 + * @run main/othervm SSLSocketParametersTest 2 + * @run main/othervm SSLSocketParametersTest 3 + * @run main/othervm SSLSocketParametersTest 4 + * @run main/othervm SSLSocketParametersTest 5 + * @run main/othervm SSLSocketParametersTest 6 + * @run main/othervm SSLSocketParametersTest 7 + */ import java.io.IOException; import java.io.File; import java.io.Serializable; @@ -77,7 +89,7 @@ public void runClient(Remote stub) throws IOException { } } - public class ClientFactory extends SslRMIClientSocketFactory { + public static class ClientFactory extends SslRMIClientSocketFactory { public ClientFactory() { super(); @@ -90,7 +102,7 @@ public Socket createSocket(String host, int port) throws IOException { } } - public class ServerFactory extends SslRMIServerSocketFactory { + public static class ServerFactory extends SslRMIServerSocketFactory { public ServerFactory() { super(); @@ -116,158 +128,90 @@ public ServerSocket createServerSocket(int port) throws IOException { } } - public void runTest(String[] args) { - - int test = Integer.parseInt(args[0]); - - String msg1 = "Running SSLSocketParametersTest [" + test + "]"; - String msg2 = "SSLSocketParametersTest [" + test + "] PASSED!"; - String msg3 = "SSLSocketParametersTest [" + test + "] FAILED!"; - - switch (test) { - case 1: /* default constructor - default config */ - System.out.println(msg1); - try { - HelloImpl server = new HelloImpl( - 0, - new ClientFactory(), - new ServerFactory()); - Remote stub = server.runServer(); - HelloClient client = new HelloClient(); - client.runClient(stub); - System.out.println(msg2); - } catch (Exception e) { - System.out.println(msg3 + " Exception: " + e.toString()); - e.printStackTrace(System.out); - System.exit(1); - } - break; - case 2: /* non-default constructor - default config */ - System.out.println(msg1); - try { - HelloImpl server = new HelloImpl( - 0, - new ClientFactory(), - new ServerFactory(null, - null, - false)); - Remote stub = server.runServer(); - HelloClient client = new HelloClient(); - client.runClient(stub); - System.out.println(msg2); - } catch (Exception e) { - System.out.println(msg3 + " Exception: " + e.toString()); - e.printStackTrace(System.out); - System.exit(1); + public void testRmiCommunication(RMIServerSocketFactory serverFactory, boolean expectException) { + + HelloImpl server = null; + try { + server = new HelloImpl(0, + new ClientFactory(), + serverFactory); + Remote stub = server.runServer(); + HelloClient client = new HelloClient(); + client.runClient(stub); + if (expectException) { + throw new RuntimeException("Test completed without throwing an expected exception."); } - break; - case 3: /* needClientAuth=true */ - System.out.println(msg1); - try { - HelloImpl server = new HelloImpl( - 0, - new ClientFactory(), - new ServerFactory(null, - null, - null, - true)); - Remote stub = server.runServer(); - HelloClient client = new HelloClient(); - client.runClient(stub); - System.out.println(msg2); - } catch (Exception e) { - System.out.println(msg3 + " Exception: " + e.toString()); - e.printStackTrace(System.out); - System.exit(1); - } - break; - case 4: /* server side dummy_ciphersuite */ - System.out.println(msg1); - try { - HelloImpl server = new HelloImpl( - 0, - new ClientFactory(), - new ServerFactory(SSLContext.getDefault(), - new String[] {"dummy_ciphersuite"}, - null, - false)); - Remote stub = server.runServer(); - HelloClient client = new HelloClient(); - client.runClient(stub); - System.out.println(msg3); - System.exit(1); - } catch (Exception e) { - System.out.println(msg2 + " Exception: " + e.toString()); - System.exit(0); + + } catch (IOException exc) { + if (!expectException) { + throw new RuntimeException("An error occurred during test execution", exc); + } else { + System.out.println("Caught expected exception: " + exc); } - break; - case 5: /* server side dummy_protocol */ - System.out.println(msg1); - try { - HelloImpl server = new HelloImpl( - 0, - new ClientFactory(), - new ServerFactory(null, - new String[] {"dummy_protocol"}, - false)); - Remote stub = server.runServer(); - HelloClient client = new HelloClient(); - client.runClient(stub); - System.out.println(msg3); - System.exit(1); - } catch (Exception e) { - System.out.println(msg2 + " Exception: " + e.toString()); - System.exit(0); + + } + } + + private static void testServerFactory(String[] cipherSuites, String[] protocol, String expectedMessage) throws Exception { + try { + new ServerFactory(SSLContext.getDefault(), + cipherSuites, protocol, false); + throw new RuntimeException( + "The expected exception for "+ expectedMessage + " was not thrown."); + } catch (IllegalArgumentException exc) { + // expecting an exception with a specific message + // anything else is an error + if (!exc.getMessage().toLowerCase().contains(expectedMessage)) { + throw exc; } - break; - case 6: /* client side dummy_ciphersuite */ - System.out.println(msg1); - try { + } + } + + public void runTest(int testNumber) throws Exception { + System.out.println("Running test " + testNumber); + + switch (testNumber) { + /* default constructor - default config */ + case 1 -> testRmiCommunication(new ServerFactory(), false); + + /* non-default constructor - default config */ + case 2 -> testRmiCommunication(new ServerFactory(null, null, false), false); + + /* needClientAuth=true */ + case 3 -> testRmiCommunication(new ServerFactory(null, null, null, true), false); + + /* server side dummy_ciphersuite */ + case 4 -> + testServerFactory(new String[]{"dummy_ciphersuite"}, null, "unsupported ciphersuite"); + + /* server side dummy_protocol */ + case 5 -> + testServerFactory(null, new String[]{"dummy_protocol"}, "unsupported protocol"); + + /* client side dummy_ciphersuite */ + case 6 -> { System.setProperty("javax.rmi.ssl.client.enabledCipherSuites", - "dummy_ciphersuite"); - HelloImpl server = new HelloImpl( - 0, - new ClientFactory(), - new ServerFactory()); - Remote stub = server.runServer(); - HelloClient client = new HelloClient(); - client.runClient(stub); - System.out.println(msg3); - System.exit(1); - } catch (Exception e) { - System.out.println(msg2 + " Exception: " + e.toString()); - System.exit(0); + "dummy_ciphersuite"); + testRmiCommunication(new ServerFactory(), true); } - break; - case 7: /* client side dummy_protocol */ - System.out.println(msg1); - try { + + /* client side dummy_protocol */ + case 7 -> { System.setProperty("javax.rmi.ssl.client.enabledProtocols", - "dummy_protocol"); - HelloImpl server = new HelloImpl( - 0, - new ClientFactory(), - new ServerFactory()); - Remote stub = server.runServer(); - HelloClient client = new HelloClient(); - client.runClient(stub); - System.out.println(msg3); - System.exit(1); - } catch (Exception e) { - System.out.println(msg2 + " Exception: " + e.toString()); - System.exit(0); + "dummy_protocol"); + testRmiCommunication(new ServerFactory(), true); } - break; - default: - throw new IllegalArgumentException("invalid test number"); + + default -> + throw new RuntimeException("Unknown test number: " + testNumber); } } - public static void main(String[] args) { + public static void main(String[] args) throws Exception { // Set keystore properties (server-side) // final String keystore = System.getProperty("test.src") + - File.separator + "keystore"; + File.separator + "keystore"; System.out.println("KeyStore = " + keystore); System.setProperty("javax.net.ssl.keyStore", keystore); System.setProperty("javax.net.ssl.keyStorePassword", "password"); @@ -275,15 +219,12 @@ public static void main(String[] args) { // Set truststore properties (client-side) // final String truststore = System.getProperty("test.src") + - File.separator + "truststore"; + File.separator + "truststore"; System.out.println("TrustStore = " + truststore); System.setProperty("javax.net.ssl.trustStore", truststore); System.setProperty("javax.net.ssl.trustStorePassword", "trustword"); - // Run test - // SSLSocketParametersTest test = new SSLSocketParametersTest(); - test.runTest(args); - System.exit(0); + test.runTest(Integer.parseInt(args[0])); } -} +} \ No newline at end of file diff --git a/test/jdk/javax/rmi/ssl/SSLSocketParametersTest.sh b/test/jdk/javax/rmi/ssl/SSLSocketParametersTest.sh deleted file mode 100644 index d411fa9517e..00000000000 --- a/test/jdk/javax/rmi/ssl/SSLSocketParametersTest.sh +++ /dev/null @@ -1,56 +0,0 @@ -# -# Copyright (c) 2004, 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 5016500 -# @summary Test SslRmi[Client|Server]SocketFactory SSL socket parameters. -# @author Luis-Miguel Alventosa -# @run clean SSLSocketParametersTest -# @run build SSLSocketParametersTest -# @run shell/timeout=300 SSLSocketParametersTest.sh - -echo ------------------------------------------------------------- -echo Launching test for `basename $0 .sh` -echo ------------------------------------------------------------- - -# case 1: /* default constructor - default config */ -${TESTJAVA}/bin/java ${TESTVMOPTS} -classpath ${TESTCLASSES} -Dtest.src=${TESTSRC} SSLSocketParametersTest 1 || exit $? - -# case 2: /* non-default constructor - default config */ -${TESTJAVA}/bin/java ${TESTVMOPTS} -classpath ${TESTCLASSES} -Dtest.src=${TESTSRC} SSLSocketParametersTest 2 || exit $? - -# case 3: /* needClientAuth=true */ -${TESTJAVA}/bin/java ${TESTVMOPTS} -classpath ${TESTCLASSES} -Dtest.src=${TESTSRC} SSLSocketParametersTest 3 || exit $? - -# case 4: /* server side dummy_ciphersuite */ -${TESTJAVA}/bin/java ${TESTVMOPTS} -classpath ${TESTCLASSES} -Dtest.src=${TESTSRC} SSLSocketParametersTest 4 || exit $? - -# case 5: /* server side dummy_protocol */ -${TESTJAVA}/bin/java ${TESTVMOPTS} -classpath ${TESTCLASSES} -Dtest.src=${TESTSRC} SSLSocketParametersTest 5 || exit $? - -# case 6: /* client side dummy_ciphersuite */ -${TESTJAVA}/bin/java ${TESTVMOPTS} -classpath ${TESTCLASSES} -Dtest.src=${TESTSRC} SSLSocketParametersTest 6 || exit $? - -# case 7: /* client side dummy_protocol */ -${TESTJAVA}/bin/java ${TESTVMOPTS} -classpath ${TESTCLASSES} -Dtest.src=${TESTSRC} SSLSocketParametersTest 7 || exit $? diff --git a/test/jdk/javax/script/JDK_8196959/BadFactoryTest.java b/test/jdk/javax/script/JDK_8196959/BadFactoryTest.java index 9f02c61511d..36e3391be7f 100644 --- a/test/jdk/javax/script/JDK_8196959/BadFactoryTest.java +++ b/test/jdk/javax/script/JDK_8196959/BadFactoryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -21,10 +21,34 @@ * questions. */ +import org.junit.jupiter.api.Test; + +import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineManager; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertTrue; +/* + * @test + * @bug 8196959 8320712 + * @summary Verify that ScriptEngineManager can load BadFactory without throwing NPE + * @build BadFactory BadFactoryTest + * @run junit/othervm BadFactoryTest + * @run junit/othervm -Djava.security.manager=allow BadFactoryTest + */ public class BadFactoryTest { - public static void main(String[] args) { + + @Test + public void scriptEngineManagerShouldLoadBadFactory() { + // Check that ScriptEngineManager initializes even in the + // presence of a ScriptEngineFactory returning nulls ScriptEngineManager m = new ScriptEngineManager(); + + // Sanity check that ScriptEngineManager actually found the BadFactory + Optional badFactory = m.getEngineFactories().stream() + .filter(fac -> fac.getClass() == BadFactory.class) + .findAny(); + assertTrue(badFactory.isPresent(), "BadFactory not found"); } } diff --git a/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh b/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh deleted file mode 100644 index e5d1a063840..00000000000 --- a/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright (c) 2018, 2023, 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 8196959 -# @summary BadFactory that results in NPE being thrown from ScriptEngineManager -# -# @build BadFactory BadFactoryTest -# @run shell BadFactoryTest.sh - -if [ "${TESTSRC}" = "" ] -then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 -fi - -. ${TESTSRC}/../CommonSetup.sh - -echo "Creating JAR file ..." - -$JAR ${TESTTOOLVMOPTS} -cf ${TESTCLASSES}/badfactory.jar \ - -C ${TESTCLASSES} BadFactory.class \ - -C ${TESTCLASSES} BadFactoryTest.class \ - -C "${TESTSRC}" META-INF/services/javax.script.ScriptEngineFactory - -echo "Running test with security manager ..." -$JAVA ${TESTVMOPTS} -Djava.security.manager -classpath \ - "${TESTCLASSES}${PS}${TESTCLASSES}/badfactory.jar" \ - BadFactoryTest - -ret=$? -if [ $ret -ne 0 ] -then - exit $ret -fi - -echo "Running test without security manager ..." -$JAVA ${TESTVMOPTS} -classpath \ - "${TESTCLASSES}${PS}${TESTCLASSES}/badfactory.jar" \ - BadFactoryTest diff --git a/test/jdk/javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java b/test/jdk/javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java index 5d8a5cfea27..8f68773398c 100644 --- a/test/jdk/javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java +++ b/test/jdk/javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java @@ -25,14 +25,16 @@ * @test * @bug 8284910 * @summary Check that the cleaner is not bound to the PasswordCallback object + * @library /test/lib/ + * @build jdk.test.lib.util.ForceGC + * @run main/othervm CheckCleanerBound */ import javax.security.auth.callback.PasswordCallback; -import java.util.WeakHashMap; +import java.lang.ref.WeakReference; +import jdk.test.lib.util.ForceGC; public final class CheckCleanerBound { - private final static WeakHashMap weakHashMap = - new WeakHashMap<>(); public static void main(String[] args) throws Exception { // Create an object @@ -40,20 +42,14 @@ public static void main(String[] args) throws Exception { new PasswordCallback("Password: ", false); passwordCallback.setPassword("ThisIsAPassword".toCharArray()); - weakHashMap.put(passwordCallback, null); + WeakReference weakRef = + new WeakReference<>(passwordCallback); passwordCallback = null; - // Check if the PasswordCallback object could be collected. - // Wait to trigger the cleanup. - for (int i = 0; i < 10 && weakHashMap.size() != 0; i++) { - System.gc(); - Thread.sleep(100); - } - // Check if the object has been collected. The collection will not // happen if the cleaner implementation in PasswordCallback is bound // to the PasswordCallback object. - if (weakHashMap.size() > 0) { + if (!ForceGC.wait(() -> weakRef.refersTo(null))) { throw new RuntimeException( "PasswordCallback object is not released"); } diff --git a/test/jdk/javax/swing/Action/bug4186951.java b/test/jdk/javax/swing/Action/bug4186951.java new file mode 100644 index 00000000000..3d3529f9470 --- /dev/null +++ b/test/jdk/javax/swing/Action/bug4186951.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 1999, 2023, 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 4186951 + @summary Bulletproofing for AbstractAction.ArrayTable Serialization. + @run main bug4186951 +*/ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; +import javax.swing.SwingUtilities; + +public class bug4186951 { + public static void main(String[] args) throws Exception { + AbstractAction ma = new MyAction(); + MyClassSer mcs = new MyClassSer(); + ma.putValue("serializable",mcs); + MyClassNonSer mcn = new MyClassNonSer(); + ma.putValue("non-serializable",mcn); + FileOutputStream fos = new FileOutputStream("file.test"); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(ma); + FileInputStream fis = new FileInputStream("file.test"); + ObjectInputStream ois = new ObjectInputStream(fis); + ma = (MyAction)ois.readObject(); + File fil = new File("file.test"); + if (fil!=null) { + fil.delete(); + } + if (!((MyClassSer)ma.getValue("serializable")).equals(mcs)) { + throw new RuntimeException("Serialisable class " + + " wasn't serialized..."); + } + if ((MyClassNonSer)ma.getValue("non-serializable") != null) { + throw new RuntimeException("Serialisation occurs for " + + " non-serialisable class..."); + } + } + + static class MyAction extends AbstractAction { + public void actionPerformed(ActionEvent e) {} + } + + static class MyClassSer implements Serializable { + String str = "default_string"; + public boolean equals(MyClassSer s) { + return str.equals(s.str); + } + } + + static class MyClassNonSer { + String str = "default_string"; + } + +} diff --git a/test/jdk/javax/swing/Action/bug4211425.java b/test/jdk/javax/swing/Action/bug4211425.java new file mode 100644 index 00000000000..8046ab0a81c --- /dev/null +++ b/test/jdk/javax/swing/Action/bug4211425.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 1999, 2023, 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 4211425 + @summary Verifies ClassCastException in AbstractAction + @run main bug4211425 +*/ + +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; + +public class bug4211425 { + + public static void main(String[] args) { + AbstractAction at = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + System.out.println("Action!"); + } + }; + for (int i = 0; i < 10; i++) { + at.putValue("key " + i, "name"); + at.putValue("key " + i, "name"); // Adding another with same key + // tickles this bug + } + } +} diff --git a/test/jdk/javax/swing/Action/bug4211454.java b/test/jdk/javax/swing/Action/bug4211454.java new file mode 100644 index 00000000000..9db82ba0602 --- /dev/null +++ b/test/jdk/javax/swing/Action/bug4211454.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 1999, 2023, 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 4211454 + @summary Verifies ClassCastException in AbstractAction + @run main bug4211454 +*/ + +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; + +public class bug4211454 { + + public static void main(String[] args) { + AbstractAction at = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + System.out.println("Action!"); + } + }; + for (int i = 0; i<9; i++) { + at.putValue("key " + i, "name"); + } + for (int i = 9; i>3; i--) { + at.putValue("key " + i, null); + at.putValue("Not a key " + i, null); + } + } +} diff --git a/test/jdk/javax/swing/Action/bug4244034.java b/test/jdk/javax/swing/Action/bug4244034.java new file mode 100644 index 00000000000..9efb11c8204 --- /dev/null +++ b/test/jdk/javax/swing/Action/bug4244034.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1999, 2023, 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 4244034 + @summary Tests that AbstractAction has method getKeys() + @run main bug4244034 +*/ + +import java.util.Arrays; +import java.util.List; +import java.awt.event.ActionEvent; +import javax.swing.Action; +import javax.swing.AbstractAction; + +public class bug4244034 { + + /** Auxilliary class extending AbstractAction + */ + static class NullAction extends AbstractAction { + public void actionPerformed(ActionEvent e) {} + } + + public static void main(String[] args) { + AbstractAction action = new NullAction(); + action.putValue(Action.SHORT_DESCRIPTION, "my short descr"); + action.putValue(Action.LONG_DESCRIPTION, "my long descr"); + action.putValue(Action.NAME, "my name"); + + Object[] keys = action.getKeys(); + List keysList = Arrays.asList(keys); + if (! keysList.contains(Action.SHORT_DESCRIPTION) || + ! keysList.contains(Action.LONG_DESCRIPTION) || + ! keysList.contains(Action.NAME)) { + + throw new Error("Failed: getKeys() works improperly"); + } + } +} diff --git a/test/jdk/javax/swing/JDialog/bug4859570.java b/test/jdk/javax/swing/JDialog/bug4859570.java new file mode 100644 index 00000000000..cc0f4f7adee --- /dev/null +++ b/test/jdk/javax/swing/JDialog/bug4859570.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2003, 2023, 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 4859570 + * @summary SwingUtilities.sharedOwnerFrame is never disposed + * @key headful + */ + +import java.awt.Robot; +import java.awt.Window; +import javax.swing.JDialog; +import javax.swing.SwingUtilities; + +public class bug4859570 { + static Window owner; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + JDialog dialog = new JDialog(); + dialog.setTitle("bug4859570"); + dialog.setBounds(100, 100, 100, 100); + dialog.setVisible(true); + + owner = dialog.getOwner(); + dialog.dispose(); + }); + + Robot r = new Robot(); + r.waitForIdle(); + r.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + if (owner.isDisplayable()) { + throw new RuntimeException("The shared owner frame should be disposed."); + } + }); + } +} diff --git a/test/jdk/javax/swing/JDialog/bug4936652.java b/test/jdk/javax/swing/JDialog/bug4936652.java new file mode 100644 index 00000000000..989c8e4194f --- /dev/null +++ b/test/jdk/javax/swing/JDialog/bug4936652.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2003, 2023, 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 4936652 + * @key headful + * @summary JDialog.setVisible, JDialog.dispose works incorrectly + */ + +import javax.swing.JDialog; +import javax.swing.SwingUtilities; + +public class bug4936652 { + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + for (int i = 0 ; i < 100; i++) { + System.out.println("i: " + i); + JDialog o = new JDialog(); + o.setTitle("bug4936652"); + o.setVisible(true); + o.setVisible(false); + o.dispose(); + } + }); + } +} diff --git a/test/jdk/javax/swing/JFileChooser/4524490/bug4524490.java b/test/jdk/javax/swing/JFileChooser/4524490/bug4524490.java index 92165f4add1..b2619cb3cc4 100644 --- a/test/jdk/javax/swing/JFileChooser/4524490/bug4524490.java +++ b/test/jdk/javax/swing/JFileChooser/4524490/bug4524490.java @@ -45,7 +45,7 @@ public class bug4524490 { public static void main(String[] args) throws Exception { Robot robot = new Robot(); - robot.setAutoDelay(50); + robot.setAutoDelay(100); UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel"); diff --git a/test/jdk/javax/swing/JFileChooser/bug4624353.java b/test/jdk/javax/swing/JFileChooser/bug4624353.java new file mode 100644 index 00000000000..c977cb9ed95 --- /dev/null +++ b/test/jdk/javax/swing/JFileChooser/bug4624353.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2003, 2023, 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 4624353 + * @summary Tests that Motif FileChooser is not able to show control buttons + * @key headful + * @run main bug4624353 + */ + +import java.awt.Component; +import java.awt.Container; +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +public class bug4624353 { + static volatile boolean passed = true; + static JFrame fr; + static JFileChooser fc; + + public static void main(String args[]) throws Exception { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel"); + + try { + SwingUtilities.invokeAndWait(() -> { + fr = new JFrame("bug4624353"); + fc = new JFileChooser(); + fc.setControlButtonsAreShown(false); + fr.getContentPane().add(fc); + fr.pack(); + fr.setVisible(true); + + passAround(fc); + }); + if (!passed) { + throw new RuntimeException("Test failed"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (fr != null) { + fr.dispose(); + } + }); + } + } + + public static void passAround(Container c) { + Component[] list = c.getComponents(); + if (list.length == 0) { + return; + } + for (int i = 0; i < list.length; i++) { + if (list[i] != null) { + if ((list[i] instanceof JButton) && + "OK".equals(((JButton)list[i]).getText())) { + passed = false; + return; + } + passAround((Container)list[i]); + } + } + } +} diff --git a/test/jdk/javax/swing/JFileChooser/bug4673161.java b/test/jdk/javax/swing/JFileChooser/bug4673161.java new file mode 100644 index 00000000000..82b6a5ea69c --- /dev/null +++ b/test/jdk/javax/swing/JFileChooser/bug4673161.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2002, 2023, 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 4673161 + * @requires (os.family == "windows") + * @summary Tests if JFileChooser preferred size depends on selected files + * @run main bug4673161 + */ + +import java.awt.Dimension; +import java.io.File; +import javax.swing.JFileChooser; +import javax.swing.UIManager; + +public class bug4673161 { + + public static void main(String[] args) throws Exception { + JFileChooser fc = new JFileChooser(); + Dimension d = fc.getPreferredSize(); + JFileChooser fc2 = new JFileChooser(); + File[] files = new File[50]; + for (int i = 0; i < 50; i++) { + files[i] = new File("file" + i); + } + fc2.setSelectedFiles(files); + Dimension d2 = fc2.getPreferredSize(); + if (!d.equals(d2)) { + throw new RuntimeException("Test failed: JFileChooser preferred " + + "size depends on selected files"); + } + + UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + + JFileChooser fc3 = new JFileChooser(); + d = fc3.getPreferredSize(); + fc2 = new JFileChooser(); + files = new File[50]; + for (int i = 0; i < 50; i++) { + files[i] = new File("file" + i); + } + fc2.setSelectedFiles(files); + d2 = fc2.getPreferredSize(); + if (!d.equals(d2)) { + throw new RuntimeException("Test failed: JFileChooser preferred " + + "size depends on selected files"); + } + } +} diff --git a/test/jdk/javax/swing/JFileChooser/bug4782168.java b/test/jdk/javax/swing/JFileChooser/bug4782168.java new file mode 100644 index 00000000000..0bfeb46ed18 --- /dev/null +++ b/test/jdk/javax/swing/JFileChooser/bug4782168.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2002, 2023, 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 4782168 + * @summary Tests if DefaultShellFolder.isHidden() crashes for the + root folder on Solaris + * @modules java.desktop/sun.awt.shell + * @run main bug4782168 + */ + +public class bug4782168 { + + public static void main(String args[]) throws Exception { + sun.awt.shell.ShellFolder sf = sun.awt.shell.ShellFolder. + getShellFolder(new java.io.File("/")); + sf.isHidden(); + } +} diff --git a/test/jdk/javax/swing/JFormattedTextField/bug4741926.java b/test/jdk/javax/swing/JFormattedTextField/bug4741926.java new file mode 100644 index 00000000000..58725e68780 --- /dev/null +++ b/test/jdk/javax/swing/JFormattedTextField/bug4741926.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2003, 2023, 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 4741926 + * @summary JFormattedTextField/JSpinner always consumes certain key events + * @key headful + * @run main bug4741926 + */ + +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; +import java.util.Date; +import javax.swing.AbstractAction; +import javax.swing.InputMap; +import javax.swing.JComponent; +import javax.swing.JFormattedTextField; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; + +public class bug4741926 { + + static MyFormattedTextField ftf; + static JFrame fr; + static Robot robot; + static volatile boolean passed_enter = false; + static volatile boolean passed_escape = false; + static volatile boolean ftfFocused = false; + static volatile boolean keyProcessed = false; + + public static void main(String[] args) throws Exception { + + try { + robot = new Robot(); + robot.setAutoDelay(100); + SwingUtilities.invokeAndWait(() -> { + fr = new JFrame("Test"); + ftf = new MyFormattedTextField(); + ftf.setValue("JFormattedTextField"); + JPanel p = (JPanel) fr.getContentPane(); + p.add(ftf); + ftf.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + ftfFocused = true; + } + }); + InputMap map = p.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); + + map.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), + "enter-action"); + p.getActionMap().put("enter-action", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + passed_enter = true; + keyProcessed = true; + } + }); + map.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + "escape-action"); + p.getActionMap().put("escape-action", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + passed_escape = true; + keyProcessed = true; + } + }); + fr.pack(); + fr.setLocationRelativeTo(null); + fr.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + test(); + if (!(passed_enter && passed_escape)) { + throw new RuntimeException("JFormattedTextField consume " + + "Enter/Escape key event"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (fr != null) { + fr.dispose(); + } + }); + } + } + + public static void test() throws Exception { + SwingUtilities.invokeAndWait(() -> { + ftf.requestFocus(); + }); + robot.delay(500); + doTest(KeyEvent.VK_ENTER); + doTest(KeyEvent.VK_ESCAPE); + } + + static void doTest(int keyCode) throws InterruptedException { + keyProcessed = false; + KeyEvent key = new KeyEvent(ftf, KeyEvent.KEY_PRESSED, + new Date().getTime(), 0, + keyCode, + KeyEvent.CHAR_UNDEFINED); + ftf.processKey(key); + } + + static class MyFormattedTextField extends JFormattedTextField { + public void processKey(KeyEvent e) { + processKeyEvent(e); + } + } +} diff --git a/test/jdk/javax/swing/JFormattedTextField/bug4863121.java b/test/jdk/javax/swing/JFormattedTextField/bug4863121.java new file mode 100644 index 00000000000..22e50f087c7 --- /dev/null +++ b/test/jdk/javax/swing/JFormattedTextField/bug4863121.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2003, 2023, 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 4863121 + * @summary JFormattedTextField's NotifyAction should invoke invalidEdit if + commit fails + * @key headful + * @run main bug4863121 + */ + +import java.awt.Robot; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; +import java.text.Format; +import java.text.DecimalFormat; +import javax.swing.JFormattedTextField; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class bug4863121 { + + static TestFormattedTextField ftf; + static JFrame fr; + static Robot robot; + + private static volatile boolean focused = false; + private static volatile boolean passed = false; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + robot.setAutoDelay(100); + SwingUtilities.invokeAndWait(() -> { + fr = new JFrame("Test"); + ftf = new TestFormattedTextField(new DecimalFormat("####")); + ftf.setText("q"); + fr.getContentPane().add(ftf); + + ftf.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + focused = true; + } + }); + fr.pack(); + fr.setLocationRelativeTo(null); + fr.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + ftf.requestFocus(); + }); + robot.waitForIdle(); + robot.delay(500); + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + if (!passed) { + throw new RuntimeException("JFormattedTextField's NotifyAction " + + "should invoke invalidEdit if commit fails"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (fr != null) { + fr.dispose(); + } + }); + } + } + + public static class TestFormattedTextField extends JFormattedTextField { + public TestFormattedTextField(Format f) { + super(f); + } + protected void invalidEdit() { + passed = true; + } + } +} diff --git a/test/jdk/javax/swing/JFormattedTextField/bug4886538.java b/test/jdk/javax/swing/JFormattedTextField/bug4886538.java new file mode 100644 index 00000000000..e50b15e9175 --- /dev/null +++ b/test/jdk/javax/swing/JFormattedTextField/bug4886538.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2003, 2023, 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 4886538 + * @summary JFormattedTextField not returning correct value (class) + * @run main bug4886538 + */ + +import javax.swing.JFormattedTextField; +import javax.swing.SwingUtilities; +import javax.swing.text.DefaultFormatterFactory; + +public class bug4886538 { + + public static void main(String[] args) throws Exception { + // test default display formatter + TestFormattedTextField field = new TestFormattedTextField(0.0); + field.setFormatter(((DefaultFormatterFactory) field. + getFormatterFactory()).getDisplayFormatter()); + field.setText("10"); + field.commitEdit(); + + Object dblValue = field.getValue(); + if (!(dblValue instanceof Double)) { + throw new RuntimeException("The JFormattedTextField's value " + + "should be instanceof Double"); + } + + // test default editor formatter + field = new TestFormattedTextField(0.0); + field.setFormatter(((DefaultFormatterFactory) field. + getFormatterFactory()).getEditFormatter()); + field.setText("10"); + field.commitEdit(); + + dblValue = field.getValue(); + if (!(dblValue instanceof Double)) { + throw new RuntimeException("The JFormattedTextField's value " + + "should be instanceof Double"); + } + + } + + static class TestFormattedTextField extends JFormattedTextField { + public TestFormattedTextField(Object value) { + super(value); + } + public void setFormatter(JFormattedTextField.AbstractFormatter formatter) { + super.setFormatter(formatter); + } + } + +} diff --git a/test/jdk/javax/swing/JFrame/JFrameBackgroundRefreshTest.java b/test/jdk/javax/swing/JFrame/JFrameBackgroundRefreshTest.java new file mode 100644 index 00000000000..cb2e0051216 --- /dev/null +++ b/test/jdk/javax/swing/JFrame/JFrameBackgroundRefreshTest.java @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2023, 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.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.MouseInfo; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +/* + * @test + * @key headful + * @bug 8187759 + * @summary Test to check if JFrame background is refreshed in Linux. + * @requires (os.family == "linux") + * @run main JFrameBackgroundRefreshTest + */ + +public class JFrameBackgroundRefreshTest { + public static JFrame frame; + private static final BufferedImage test = generateImage(); + private static Point p = new Point(); + private static Robot robot; + private static JFrame whiteFrame; + private static Point frameLocation; + private static int frameCenterX, frameCenterY, awayX, awayY; + private static int imageCenterX, imageCenterY; + + public static void main(String[] args) throws Exception { + try { + SwingUtilities.invokeAndWait(() -> { + try { + JFrameBackgroundRefreshTest.initialize(); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + + SwingUtilities.invokeAndWait(() -> { + frameLocation = whiteFrame.getLocationOnScreen(); + frameCenterX = frameLocation.x + whiteFrame.getWidth() / 2; + frameCenterY = frameLocation.y + whiteFrame.getHeight() / 2; + awayX = frameLocation.x + whiteFrame.getWidth() + 100; + awayY = frameLocation.y + whiteFrame.getHeight() / 2; + imageCenterX = p.x + test.getWidth() / 2; + imageCenterY = p.y + test.getHeight() / 2; + }); + robot.delay(100); + robot.waitForIdle(); + robot.mouseMove(imageCenterX, imageCenterY); + robot.delay(100); + robot.waitForIdle(); + moveMouseSlowly(frameCenterX, frameCenterY); + robot.delay(1000); + robot.waitForIdle(); + + moveMouseSlowly(awayX, awayY); + robot.delay(100); + robot.waitForIdle(); + Rectangle screenCaptureRect = new Rectangle(frameCenterX - 50, + frameCenterY - 50, 100, 100); + BufferedImage bufferedImage = robot.createScreenCapture(screenCaptureRect); + + if (!compareImages(bufferedImage)) { + try { + ImageIO.write(bufferedImage, "png", + new File("FailureImage.png")); + } catch (IOException e) { + e.printStackTrace(); + } + throw new RuntimeException("Test Failed!"); + } + System.out.println("Test Passed!"); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + if (whiteFrame != null) { + whiteFrame.dispose(); + } + }); + } + } + + private static void moveMouseSlowly( int targetX, int targetY) { + Point currentMousePos = MouseInfo.getPointerInfo().getLocation(); + int currentX = currentMousePos.x; + int currentY = currentMousePos.y; + int deltaX = targetX - currentX; + int deltaY = targetY - currentY; + int steps = 50; + double stepX = (double) deltaX / steps; + double stepY = (double) deltaY / steps; + for (int i = 1; i <= steps; i++) { + int nextX = currentX + (int) Math.round(i * stepX); + int nextY = currentY + (int) Math.round(i * stepY); + robot.mouseMove(nextX, nextY); + robot.delay(10); + } + robot.mouseMove(targetX, targetY); + } + + private static boolean compareImages(BufferedImage bufferedImage) { + int sampleRGB = bufferedImage.getRGB(0,0); + for (int x = 0; x < bufferedImage.getWidth(); x++) { + for (int y = 0; y < bufferedImage.getHeight(); y++) { + if (bufferedImage.getRGB(x, y) != sampleRGB) { + return false; + } + } + } + return true; + } + + public static void initialize() throws Exception { + frame = new JFrame("JFrame Background refresh test"); + whiteFrame = new JFrame("White Frame"); + robot = new Robot(); + whiteFrame.setSize(200, 200); + whiteFrame.setBackground(Color.WHITE); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setUndecorated(true); + frame.setExtendedState(JFrame.MAXIMIZED_BOTH); + frame.setBackground(new Color(0, 0, 0, 0)); + frame.setContentPane(new TranslucentPane()); + frame.addMouseMotionListener(new MouseDragListener()); + whiteFrame.setLocationRelativeTo(null); + whiteFrame.setVisible(true); + frame.setVisible(true); + frame.setAlwaysOnTop(true); + } + private static class MouseDragListener extends MouseAdapter { + @Override + public void mouseMoved(MouseEvent e) { + p = e.getPoint(); + frame.repaint(); + } + } + + /** Capture an image of any component **/ + private static BufferedImage getImage(Component c) { + if (c == null) { + return null; + } + BufferedImage image = new BufferedImage(c.getWidth(), + c.getHeight(), BufferedImage.TYPE_INT_ARGB); + Graphics2D g = image.createGraphics(); + c.printAll(g); + g.dispose(); + return image; + } + + /** Generates a dummy image to be painted on the frame **/ + private static BufferedImage generateImage() { + JLabel label = new JLabel("test"); + label.setFont(new Font("Arial", Font.BOLD, 24)); + label.setSize(label.getPreferredSize()); + return getImage(label); + } + + public static class TranslucentPane extends JPanel { + public TranslucentPane() { + setOpaque(false); + } + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2d = (Graphics2D) g.create(); + g2d.setColor(new Color(0,0,0,0)); + g2d.fillRect(0, 0, getWidth(), getHeight()); + g2d.drawImage(test, p.x, p.y, this); + g2d.dispose(); + } + } +} diff --git a/test/jdk/javax/swing/JInternalFrame/InternalFrameBorderTest.java b/test/jdk/javax/swing/JInternalFrame/InternalFrameBorderTest.java new file mode 100644 index 00000000000..69c38b535d2 --- /dev/null +++ b/test/jdk/javax/swing/JInternalFrame/InternalFrameBorderTest.java @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2022, 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.awt.AWTException; +import java.awt.Color; +import java.awt.GridBagLayout; +import java.awt.Image; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.MultiResolutionImage; +import java.awt.image.RenderedImage; +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.util.List; + +import javax.imageio.ImageIO; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.JLabel; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +/* + * @test + * @bug 8015739 + * @key headful + * @summary Tests whether background color of JInternalFrame is visible + * in the border region at different scales by checking the midpoints + * and corners of the border. + * + * @requires (os.family == "windows") + * @run main/othervm -Dsun.java2d.uiScale=1 InternalFrameBorderTest + * @run main/othervm -Dsun.java2d.uiScale=1.25 InternalFrameBorderTest + * @run main/othervm -Dsun.java2d.uiScale=1.5 InternalFrameBorderTest + * @run main/othervm -Dsun.java2d.uiScale=1.75 InternalFrameBorderTest + * @run main/othervm -Dsun.java2d.uiScale=2 InternalFrameBorderTest + * @run main/othervm -Dsun.java2d.uiScale=2.5 InternalFrameBorderTest + * @run main/othervm -Dsun.java2d.uiScale=3 InternalFrameBorderTest + */ + +/* + * @test + * @bug 8015739 + * @key headful + * @summary Tests whether background color of JInternalFrame is visible + * in the border region at different scales by checking the midpoints + * and corners of the border. + * + * @requires (os.family == "mac" | os.family == "linux") + * @run main/othervm -Dsun.java2d.uiScale=1 InternalFrameBorderTest + * @run main/othervm -Dsun.java2d.uiScale=2 InternalFrameBorderTest + */ + +public class InternalFrameBorderTest { + private static final int FRAME_SIZE = 300; + private static final int INTFRAME_SIZE = 150; + private static final int MIDPOINT = INTFRAME_SIZE / 2; + private static final int BORDER_THICKNESS = 4; + + private static final StringBuffer errorLog = new StringBuffer(); + + private static JFrame jFrame; + private static Rectangle jFrameBounds; + private static JInternalFrame iFrame; + private static Point iFrameLoc; + private static int iFrameMaxX; + private static int iFrameMaxY; + + private static Robot robot; + private static String uiScale; + + public static void main(String[] args) throws AWTException, + InterruptedException, InvocationTargetException { + try { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + } catch (Exception e) { + System.out.println("Metal LAF class not supported"); + return; + } + + try { + robot = new Robot(); + robot.setAutoDelay(200); + uiScale = System.getProperty("sun.java2d.uiScale"); + + SwingUtilities.invokeAndWait(InternalFrameBorderTest::createAndShowGUI); + robot.waitForIdle(); + robot.delay(500); + + SwingUtilities.invokeAndWait(() -> { + iFrameLoc = iFrame.getLocationOnScreen(); + iFrameMaxX = iFrameLoc.x + INTFRAME_SIZE; + iFrameMaxY = iFrameLoc.y + INTFRAME_SIZE; + jFrameBounds = jFrame.getBounds(); + }); + + // Check Borders + checkBorderMidPoints("TOP"); + checkBorderMidPoints("RIGHT"); + checkBorderMidPoints("BOTTOM"); + checkBorderMidPoints("LEFT"); + + // Check Corner Diagonals + checkCorners("TOP_LEFT"); + checkCorners("TOP_RIGHT"); + checkCorners("BOTTOM_RIGHT"); + checkCorners("BOTTOM_LEFT"); + + if (!errorLog.isEmpty()) { + saveScreenCapture("JIF_uiScale_" + uiScale + ".png"); + throw new RuntimeException("Following error(s) occurred: \n" + + errorLog); + } + } finally { + if (jFrame != null) { + jFrame.dispose(); + } + robot.delay(500); + } + } + + private static void checkBorderMidPoints(String borderDirection) { + int x, y; + int start, stop; + + switch (borderDirection) { + case "TOP" -> { + x = iFrameLoc.x + MIDPOINT; + y = iFrameLoc.y + BORDER_THICKNESS; + start = iFrameLoc.y; + stop = iFrameLoc.y + BORDER_THICKNESS - 1; + } + case "RIGHT" -> { + x = iFrameMaxX - BORDER_THICKNESS; + y = iFrameLoc.y + MIDPOINT; + start = iFrameMaxX - BORDER_THICKNESS + 1; + stop = iFrameMaxX; + } + case "BOTTOM" -> { + x = iFrameLoc.x + MIDPOINT; + y = iFrameMaxY - BORDER_THICKNESS; + start = iFrameMaxY - BORDER_THICKNESS + 1; + stop = iFrameMaxY; + } + case "LEFT" -> { + x = iFrameLoc.x; + y = iFrameLoc.y + MIDPOINT; + start = iFrameLoc.x; + stop = iFrameLoc.x + BORDER_THICKNESS - 1; + } + default -> throw new IllegalStateException("Unexpected value: " + + borderDirection); + } + + boolean isVertical = borderDirection.equals("RIGHT") + || borderDirection.equals("LEFT"); + boolean isHorizontal = borderDirection.equals("TOP") + || borderDirection.equals("BOTTOM"); + + robot.mouseMove(x, y); + for (int i = start; i < stop; i++) { + int locX = isVertical ? i : (iFrameLoc.x + MIDPOINT); + int locY = isHorizontal ? i : (iFrameLoc.y + MIDPOINT); + if (Color.RED.equals(robot.getPixelColor(locX, locY))) { + errorLog.append("At uiScale: " + uiScale + + ", Red background color detected at " + + borderDirection + " border.\n"); + break; + } + } + robot.delay(300); + } + + private static void checkCorners(String cornerLocation) { + int x, y; + + switch (cornerLocation) { + case "TOP_LEFT" -> { + x = iFrameLoc.x; + y = iFrameLoc.y; + } + case "TOP_RIGHT" -> { + x = iFrameMaxX; + y = iFrameLoc.y; + } + case "BOTTOM_RIGHT" -> { + x = iFrameMaxX; + y = iFrameMaxY; + } + case "BOTTOM_LEFT" -> { + x = iFrameLoc.x; + y = iFrameMaxY; + } + default -> throw new IllegalStateException("Unexpected value: " + + cornerLocation); + } + + boolean isTop = cornerLocation.equals("TOP_LEFT") + || cornerLocation.equals("TOP_RIGHT"); + boolean isLeft = cornerLocation.equals("TOP_LEFT") + || cornerLocation.equals("BOTTOM_LEFT"); + + robot.mouseMove(x, y); + for (int i = 0; i < BORDER_THICKNESS - 1; i++) { + int locX = isLeft ? (x + i) : (x - i); + int locY = isTop ? (y + i) : (y - i); + if (Color.RED.equals(robot.getPixelColor(locX, locY))) { + errorLog.append("At uiScale: " + uiScale + ", Red background color" + + " detected at " + cornerLocation + " corner.\n"); + break; + } + } + robot.delay(300); + } + + private static void createAndShowGUI() { + jFrame = new JFrame(); + jFrame.setSize(FRAME_SIZE, FRAME_SIZE); + jFrame.setLayout(null); + jFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + + JLabel scale = new JLabel("UI Scale: " + uiScale); + iFrame = new JInternalFrame("iframe", true); + iFrame.setLayout(new GridBagLayout()); + iFrame.setBackground(Color.RED); + iFrame.add(scale); + iFrame.setLocation(30, 30); + jFrame.getContentPane().add(iFrame); + iFrame.setSize(INTFRAME_SIZE, INTFRAME_SIZE); + iFrame.setVisible(true); + jFrame.setLocation(150, 150); + jFrame.setVisible(true); + } + + private static void saveScreenCapture(String filename) { + MultiResolutionImage mrImage = robot.createMultiResolutionScreenCapture(jFrameBounds); + List variants = mrImage.getResolutionVariants(); + RenderedImage image = (RenderedImage) variants.get(variants.size() - 1); + try { + ImageIO.write(image, "png", new File(filename)); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/test/jdk/java/util/Locale/Bug8026766.java b/test/jdk/javax/swing/JInternalFrame/bug4212562.java similarity index 65% rename from test/jdk/java/util/Locale/Bug8026766.java rename to test/jdk/javax/swing/JInternalFrame/bug4212562.java index 630737fdf99..e63186139b9 100644 --- a/test/jdk/java/util/Locale/Bug8026766.java +++ b/test/jdk/javax/swing/JInternalFrame/bug4212562.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2023, 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 @@ -21,25 +21,23 @@ * questions. */ +import javax.swing.JInternalFrame; + /* * @test - * @bug 8026766 - * @summary Confirm that LanguageRange.toString() returns an expected result. - * @run main Bug8026766 + * @bug 4212562 + * @summary To check if StackOverflow occurs if foreground is set to null. */ -import java.util.Locale.LanguageRange; - -public class Bug8026766 { - +public class bug4212562 { public static void main(String[] args) { - LanguageRange lr1 = new LanguageRange("ja", 1.0); - LanguageRange lr2 = new LanguageRange("fr", 0.0); - - if (!lr1.toString().equals("ja") || - !lr2.toString().equals("fr;q=0.0")) { - throw new RuntimeException("LanguageRange.toString() returned an unexpected result."); + try { + JInternalFrame jif = new JInternalFrame(); + jif.getContentPane().setForeground(null); + jif.getForeground(); + } catch (Exception e) { + throw new RuntimeException("Following exception occurred" + + " when getForeground() was called", e); } } - } diff --git a/test/jdk/javax/swing/JLabel/bug4768127.java b/test/jdk/javax/swing/JLabel/bug4768127.java new file mode 100644 index 00000000000..0ccb3c7998a --- /dev/null +++ b/test/jdk/javax/swing/JLabel/bug4768127.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2002, 2023, 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 4768127 + * @summary ToolTipManager not removed from components + * @key headful + */ + +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.MouseMotionListener; +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.JLabel; +import javax.swing.SwingUtilities; +import javax.swing.ToolTipManager; + +public class bug4768127 { + static JFrame fr; + static volatile Point p; + static volatile JLabel[] label = new JLabel[2]; + + public static void main(String[] args) throws Exception { + try { + SwingUtilities.invokeAndWait(() -> { + fr = new JFrame("bug4768127"); + + JDesktopPane jdp = new JDesktopPane(); + JInternalFrame jif1 = new JInternalFrame("jif 1"); + JInternalFrame jif2 = new JInternalFrame("jif 2"); + label[0] = new JLabel("Label 1"); + label[1] = new JLabel("Label 2"); + + label[0].setToolTipText("tooltip 1"); + jif1.getContentPane().add(label[0]); + jif1.setBounds(0, 0, 130, 160); + jif1.setVisible(true); + jdp.add(jif1); + + label[1].setToolTipText("tooltip 2"); + jif2.getContentPane().add(label[1]); + jif2.setBounds(210, 0, 130, 220); + jif2.setVisible(true); + jdp.add(jif2); + + fr.getContentPane().add(jdp); + fr.setLocationRelativeTo(null); + + fr.setSize(400, 300); + fr.setVisible(true); + }); + + Robot robot = new Robot(); + robot.setAutoDelay(10); + robot.waitForIdle(); + robot.delay(3000); + + clickLabel(0, robot); + robot.waitForIdle(); + robot.delay(3000); + + clickLabel(1, robot); + robot.waitForIdle(); + robot.delay(3000); + + clickLabel(0, robot); + robot.waitForIdle(); + robot.delay(3000); + + clickLabel(1, robot); + robot.waitForIdle(); + robot.delay(3000); + + MouseMotionListener[] mml = label[0].getMouseMotionListeners(); + if (mml.length > 0 && mml[0] instanceof ToolTipManager) { + throw new RuntimeException("Extra MouseMotionListeners were added to the label \"Label 1\" by ToolTipManager"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (fr != null) { + fr.dispose(); + } + }); + } + } + + static void clickLabel(int i, Robot robot) throws Exception { + SwingUtilities.invokeAndWait(() -> { + p = label[i].getLocationOnScreen(); + }); + final Rectangle rect = label[i].getBounds(); + robot.mouseMove(p.x + rect.width / 2, p.y + rect.height / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + //Generate mouseMotionEvent + robot.mouseMove(p.x + rect.width / 2 + 3, p.y + rect.height / 2 + 3); + robot.mouseMove(p.x + rect.width / 2, p.y + rect.height / 2); + } +} diff --git a/test/jdk/javax/swing/JLabel/bug4822331.java b/test/jdk/javax/swing/JLabel/bug4822331.java new file mode 100644 index 00000000000..5de8d88fc85 --- /dev/null +++ b/test/jdk/javax/swing/JLabel/bug4822331.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2003, 2023, 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 4822331 + * @summary setLaberFor does not transfer focus to the JSpinner editor + * @library /test/lib + * @key headful + * @run main bug4822331 + */ + +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; +import java.awt.FlowLayout; +import java.awt.Robot; +import javax.swing.JButton; +import javax.swing.JFormattedTextField; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JSpinner; +import javax.swing.SwingUtilities; +import jdk.test.lib.Platform; + +public class bug4822331 { + + static JFrame fr; + static JButton button; + static JSpinner spinner; + static volatile boolean tfFocused = false; + static volatile boolean passed = false; + + public static void main(String []args) throws Exception { + bug4822331 test = new bug4822331(); + test.init(); + } + + public void init() throws Exception { + try { + SwingUtilities.invokeAndWait(() -> { + fr = new JFrame("Test"); + fr.getContentPane().setLayout(new FlowLayout()); + + button = new JButton("Button"); + fr.getContentPane().add(button); + + spinner = new JSpinner(); + JLabel spinnerLabel = new JLabel("spinner"); + spinnerLabel.setDisplayedMnemonic(KeyEvent.VK_S); + spinnerLabel.setLabelFor(spinner); + fr.getContentPane().add(spinnerLabel); + fr.getContentPane().add(spinner); + + JSpinner.DefaultEditor editor = + (JSpinner.DefaultEditor) spinner.getEditor(); + JFormattedTextField ftf = editor.getTextField(); + ftf.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + passed = true; + } + }); + fr.pack(); + fr.setVisible(true); + }); + start(); + if ( !passed ) { + throw new RuntimeException("The activation of spinner's " + + "mnemonic didn't focus the editor component."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (fr != null) { + fr.dispose(); + } + }); + } + } + + public void start() throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(50); + robot.delay(1000); + robot.waitForIdle(); + button.requestFocus(); + if (Platform.isOSX()) { + robot.keyPress(KeyEvent.VK_CONTROL); + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_S); + robot.keyRelease(KeyEvent.VK_S); + robot.keyRelease(KeyEvent.VK_ALT); + robot.keyRelease(KeyEvent.VK_CONTROL); + } else { + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_S); + robot.keyRelease(KeyEvent.VK_S); + robot.keyRelease(KeyEvent.VK_ALT); + } + } +} diff --git a/test/jdk/javax/swing/JMenu/bug4143592.java b/test/jdk/javax/swing/JMenu/bug4143592.java new file mode 100644 index 00000000000..334128f39ff --- /dev/null +++ b/test/jdk/javax/swing/JMenu/bug4143592.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 1999, 2023, 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 4143592 + * @summary Tests the method add(Component, int) of JMenu for insertion + the given component to a specified position of menu + * @run main bug4143592 + */ + +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; + +public class bug4143592 { + + public static void main(String[] argv) { + JMenuBar mb = new JMenuBar(); + JMenu m = mb.add(new JMenu("Order")); + m.add("beginning"); + m.add("middle"); + m.add("end"); + m.add(new JMenuItem("in between"), 1); + if (!m.getItem(1).getText().equals("in between")) { + throw new RuntimeException("Item was inserted incorrectly."); + } + } +} diff --git a/test/jdk/javax/swing/JMenu/bug4148154.java b/test/jdk/javax/swing/JMenu/bug4148154.java new file mode 100644 index 00000000000..1da1549af19 --- /dev/null +++ b/test/jdk/javax/swing/JMenu/bug4148154.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2001, 2023, 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 4148154 + * @summary Tests that menu items created by JMenu.add(Action) method + have right HorizontalTextPosition. + * @run main bug4148154 + */ + +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; +import javax.swing.JMenu; +import javax.swing.JMenuItem; + +public class bug4148154 +{ + public static void main(String[] args) { + JMenu menu = new JMenu(); + JMenuItem mi = menu.add(new AbstractAction() { + public void actionPerformed(ActionEvent ev) {} + }); + if (mi.getHorizontalTextPosition() != JMenu.LEADING && + mi.getHorizontalTextPosition() != JMenu.TRAILING) { + + throw new RuntimeException("Failed:"); + } + } +} diff --git a/test/jdk/javax/swing/JMenu/bug4156316.java b/test/jdk/javax/swing/JMenu/bug4156316.java new file mode 100644 index 00000000000..2d569903205 --- /dev/null +++ b/test/jdk/javax/swing/JMenu/bug4156316.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 1999, 2023, 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 4156316 + * @summary checks if JMenu.add(Component) throws NullPointerException + * @run main bug4156316 + */ + +import javax.swing.JComponent; +import javax.swing.JMenu; + +public class bug4156316 { + + public static void main(String[] args) { + JMenu m = new JMenu("test"); + m.add(new XComponent()); + } + + static class XComponent extends JComponent { + } +} diff --git a/test/jdk/javax/swing/JMenu/bug4161866.java b/test/jdk/javax/swing/JMenu/bug4161866.java new file mode 100644 index 00000000000..0363404e486 --- /dev/null +++ b/test/jdk/javax/swing/JMenu/bug4161866.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1999, 2023, 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 4161866 + * @summary Method AccessibleJMenu.removeAccessibleSelection does not + remove selections correctly + * @run main bug4161866 + */ + +import javax.accessibility.AccessibleSelection; +import javax.swing.JMenu; +import javax.swing.JMenuBar; + +public class bug4161866 { + + public static void main(String[] argv) { + JMenuBar mb = new JMenuBar(); + JMenu mnu = new JMenu(); + AccessibleSelection acs = mnu.getAccessibleContext(). + getAccessibleSelection(); + mb.add(mnu); + JMenu jm = new JMenu(); + mnu.add(jm); + jm.setSelected(true); + acs.addAccessibleSelection(0); + if (!jm.isSelected()) { + throw new RuntimeException("Selection should be non-empty..."); + } + + acs.removeAccessibleSelection(0); + if (jm.isSelected()) { + throw new RuntimeException("Selection still non-empty after " + + "it was removed"); + } + } +} diff --git a/test/jdk/javax/swing/JMenu/bug4244796.java b/test/jdk/javax/swing/JMenu/bug4244796.java new file mode 100644 index 00000000000..cbb6d66280c --- /dev/null +++ b/test/jdk/javax/swing/JMenu/bug4244796.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1999, 2023, 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 4244796 + * @summary Tests that JMenu has JMenu(Action) constructor + * @run main bug4244796 + */ + +import java.awt.event.ActionEvent; +import java.beans.PropertyChangeListener; +import javax.swing.Action; +import javax.swing.JMenu; + +public class bug4244796 { + + /** + * Auxilliary class implementing Action + */ + static class NullAction implements Action { + public void addPropertyChangeListener( + PropertyChangeListener listener) {} + public void removePropertyChangeListener( + PropertyChangeListener listener) {} + public void putValue(String key, Object value) {} + public void setEnabled(boolean b) {} + public void actionPerformed(ActionEvent e) {} + + public Object getValue(String key) { return null; } + public boolean isEnabled() { return false; } + } + + public static void main(String[] argv) { + Action action = new NullAction(); + JMenu menu = new JMenu(action); + } +} diff --git a/test/jdk/javax/swing/JMenu/bug4767393.java b/test/jdk/javax/swing/JMenu/bug4767393.java new file mode 100644 index 00000000000..617d50983f9 --- /dev/null +++ b/test/jdk/javax/swing/JMenu/bug4767393.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2003, 2023, 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 4767393 + * @summary Disabled JMenu is selectable via mnemonic + * @key headful + * @run main bug4767393 + */ + +import java.awt.Robot; +import java.awt.event.KeyEvent; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.SwingUtilities; + +public class bug4767393 { + + public static JFrame mainFrame; + public static JMenuBar menuBar; + public static JMenu menu; + public static JMenu disabled; + public static volatile boolean disabledMenuSelected = true; + + public static void main(String[] args) throws Exception { + try { + Robot robo = new Robot(); + robo.setAutoDelay(100); + SwingUtilities.invokeAndWait(() -> { + mainFrame = new JFrame("Bug4767393"); + menuBar = new JMenuBar(); + menu = new JMenu("File"); + disabled = new JMenu("Disabled"); + menuBar.add(menu); + menu.add("Menu Item 1"); + menu.add("Menu Item 2"); + disabled.setEnabled(false); + disabled.setMnemonic('D'); + disabled.add("Dummy menu item"); + menu.add(disabled); + menu.add("Menu Item 3"); + menu.add("Menu Item 4"); + mainFrame.setJMenuBar(menuBar); + + mainFrame.setSize(200, 200); + mainFrame.setLocationRelativeTo(null); + mainFrame.setVisible(true); + }); + robo.waitForIdle(); + robo.delay(500); + + robo.keyPress(KeyEvent.VK_F10); + robo.keyRelease(KeyEvent.VK_F10); + robo.keyPress(KeyEvent.VK_DOWN); + robo.keyRelease(KeyEvent.VK_DOWN); + robo.delay(500); + robo.keyPress(KeyEvent.VK_D); + robo.keyRelease(KeyEvent.VK_D); + robo.delay(100); + + SwingUtilities.invokeAndWait(() -> { + disabledMenuSelected = disabled.isSelected(); + }); + + if (disabledMenuSelected) { + throw new RuntimeException("Disabled JMenu is selected" + + " by the mnemonic. Test failed."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (mainFrame != null) { + mainFrame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/javax/swing/JMenuBar/bug4403749.java b/test/jdk/javax/swing/JMenuBar/bug4403749.java new file mode 100644 index 00000000000..e98c0eaee3f --- /dev/null +++ b/test/jdk/javax/swing/JMenuBar/bug4403749.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2001, 2023, 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 4403749 + * @summary Tests that keyboard accelerator implementation in JMenuBar is + MenuElement aware + * @key headful + * @run main bug4403749 + */ + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JPanel; +import javax.swing.KeyStroke; +import javax.swing.MenuElement; +import javax.swing.MenuSelectionManager; +import javax.swing.SwingUtilities; + +public class bug4403749 { + static JFrame frame; + static volatile Point pt; + static volatile Dimension dim; + static volatile boolean passed; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(100); + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("bug4403749"); + JMenuBar mbar = new JMenuBar(); + JMenu menu = new JMenu("Menu"); + JPanel panel = new TestMenuElement(); + menu.add(panel); + mbar.add(menu); + frame.setJMenuBar(mbar); + + frame.getContentPane().add(new JButton("")); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setAlwaysOnTop(true); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + pt = frame.getLocationOnScreen(); + dim = frame.getSize(); + }); + robot.mouseMove(pt.x + dim.width / 2, pt.y + dim.height / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + robot.delay(200); + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_ALT); + if (!passed) { + throw new RuntimeException("Failed: processKeyBinding wasn't called"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + static class TestMenuElement extends JPanel implements MenuElement { + public void processMouseEvent(MouseEvent event, + MenuElement[] path, + MenuSelectionManager manager) {} + + public void processKeyEvent(KeyEvent event, + MenuElement[] path, + MenuSelectionManager manager) {} + + public void menuSelectionChanged(boolean isIncluded) {} + + public MenuElement[] getSubElements() { + return new MenuElement[0]; + } + + public Component getComponent() { + return this; + } + + protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, + int condition, boolean pressed) { + passed = true; + return super.processKeyBinding(ks, e, condition, pressed); + } + } +} diff --git a/test/jdk/javax/swing/JOptionPane/bug4191835.java b/test/jdk/javax/swing/JOptionPane/bug4191835.java new file mode 100644 index 00000000000..17709e9a8b9 --- /dev/null +++ b/test/jdk/javax/swing/JOptionPane/bug4191835.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 1999, 2023, 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 4191835 + * @summary JOptionPane should allow Dialog as window owner. + * @key headful + * @run main bug4191835 + */ + +import java.awt.Dialog; +import javax.swing.JDialog; +import javax.swing.JOptionPane; + +public class bug4191835 { + + public static void main(String[] args) { + JOptionPane op = new JOptionPane(); + Dialog dlg = new Dialog(new JDialog()); + JDialog jd = op.createDialog(dlg, "Dialog"); + } +} diff --git a/test/jdk/javax/swing/JPopupMenu/bug4123919.java b/test/jdk/javax/swing/JPopupMenu/bug4123919.java new file mode 100644 index 00000000000..fcc37795b7d --- /dev/null +++ b/test/jdk/javax/swing/JPopupMenu/bug4123919.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 1999, 2023, 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 4123919 + * @requires (os.family == "windows") + * @summary JPopupMenu.isPopupTrigger() under a different L&F. + * @key headful + * @run main bug4123919 + */ + +import javax.swing.JLabel; +import javax.swing.JPopupMenu; +import javax.swing.UIManager; +import javax.swing.SwingUtilities; +import java.awt.event.MouseEvent; +import java.util.Date; + +public class bug4123919 { + + public static void main(String[] args) throws Exception { + JPopupMenu popup = new JPopupMenu("Test"); + JLabel lb = new JLabel(); + UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel"); + SwingUtilities.updateComponentTreeUI(lb); + SwingUtilities.updateComponentTreeUI(popup); + if (!popup.isPopupTrigger(new MouseEvent(lb, MouseEvent.MOUSE_PRESSED, + (new Date()).getTime(), MouseEvent.BUTTON3_MASK, 10, 10, 1, true))) { + throw new RuntimeException("JPopupMenu.isPopupTrigger() fails on" + + " MotifLookAndFeel when mouse pressed..."); + } + if (popup.isPopupTrigger(new MouseEvent(lb, MouseEvent.MOUSE_RELEASED, + (new Date()).getTime(), MouseEvent.BUTTON3_MASK, 10, 10, 1, true))) { + throw new RuntimeException("JPopupMenu.isPopupTrigger() fails on" + + " MotifLookAndFeel when mouse released..."); + } + + UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + SwingUtilities.updateComponentTreeUI(lb); + SwingUtilities.updateComponentTreeUI(popup); + + if (popup.isPopupTrigger(new MouseEvent(lb, MouseEvent.MOUSE_PRESSED, + (new Date()).getTime(), MouseEvent.BUTTON3_MASK, 10, 10, 1, true))) { + throw new RuntimeException("JPopupMenu.isPopupTrigger() fails on" + + " WindowsLookAndFeel when mouse pressed..."); + } + if (!popup.isPopupTrigger(new MouseEvent(lb, MouseEvent.MOUSE_RELEASED, + (new Date()).getTime(), MouseEvent.BUTTON3_MASK, 10, 10, 1, true))) { + throw new RuntimeException("JPopupMenu.isPopupTrigger() fails on" + + " WindowsLookAndFeel when mouse released..."); + } + } +} diff --git a/test/jdk/javax/swing/JPopupMenu/bug4197019.java b/test/jdk/javax/swing/JPopupMenu/bug4197019.java new file mode 100644 index 00000000000..428bef49174 --- /dev/null +++ b/test/jdk/javax/swing/JPopupMenu/bug4197019.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 1999, 2023, 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 4197019 + * @key headful + * @run main bug4197019 + */ + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Polygon; +import java.awt.event.ActionEvent; + +import javax.swing.Action; +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.JMenuItem; +import javax.swing.JMenu; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; + +public class bug4197019 { + static volatile JMenuItem mi1; + static volatile JMenuItem mi2; + static volatile Icon i2; + static volatile boolean isPassed = false; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + JMenu fileMenu = new JMenu("File"); + JPopupMenu p = new JPopupMenu(); + Icon i = new ArrowIcon(); + Action a = new TestAction("Test", i); + mi1 = fileMenu.add(a); + mi2 = p.add(a); + + i2 = new SquareIcon(); + a.putValue(Action.SMALL_ICON, i2); + + isPassed = (mi2.getIcon() != i2) || (mi1.getIcon() != i2) || + (mi1.getIcon() != mi2.getIcon()); + }); + if (isPassed) { + throw new RuntimeException("Failed bug test 4197019"); + } + } + + private static class TestAction extends AbstractAction { + public TestAction(String s, Icon i) { + super(s,i); + } + public void actionPerformed(ActionEvent e) { + + } + } + + private static class ArrowIcon implements Icon { + public void paintIcon(Component c, Graphics g, int x, int y) { + Polygon p = new Polygon(); + p.addPoint(x, y); + p.addPoint(x+getIconWidth(), y+getIconHeight()/2); + p.addPoint(x, y+getIconHeight()); + g.fillPolygon(p); + + } + public int getIconWidth() { return 4; } + public int getIconHeight() { return 8; } + } // End class MenuArrowIcon + + private static class SquareIcon implements Icon { + public void paintIcon(Component c, Graphics g, int x, int y) { + g.setColor(Color.red); + g.fill3DRect(x,y,4,8,true); + } + public int getIconWidth() { return 8; } + public int getIconHeight() { return 8; } + } // End class MenuArrowIcon + +} diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfByteArray.java b/test/jdk/javax/swing/JSpinner/bug4522737.java similarity index 52% rename from test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfByteArray.java rename to test/jdk/javax/swing/JSpinner/bug4522737.java index 18991f63ddb..60ea8d5c10f 100644 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodySubscribersOfByteArray.java +++ b/test/jdk/javax/swing/JSpinner/bug4522737.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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 @@ -21,29 +21,31 @@ * questions. */ -import org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowSubscriberBlackboxVerification; +import javax.swing.JComponent; +import javax.swing.JSpinner; +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; -import java.net.http.HttpResponse.BodySubscribers; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.concurrent.Flow.Subscriber; +/* + * @test + * @bug 4522737 + * @summary Cannot serialize JSpinner twice. + * @run main bug4522737 + */ -/* See TckDriver.java for more information */ -public class BodySubscribersOfByteArray - extends FlowSubscriberBlackboxVerification> { +public class bug4522737 { + public static void main(String[] args) throws Exception { + final JComponent originalComponent = new JSpinner(); - public BodySubscribersOfByteArray() { - super(new TestEnvironment(450L)); - } + ByteArrayOutputStream byteArrayOutputStream = + new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = + new ObjectOutputStream(byteArrayOutputStream); + objectOutputStream.writeObject(originalComponent); - @Override - public Subscriber> createFlowSubscriber() { - return BodySubscribers.ofByteArray(); - } + objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); + objectOutputStream.writeObject(originalComponent); - @Override - public List createElement(int element) { - return S.listOfBuffersFromBufferOfNBytes(element % 17); + System.out.println("Test Passed!"); } } diff --git a/test/jdk/javax/swing/JSpinner/bug4656590.java b/test/jdk/javax/swing/JSpinner/bug4656590.java new file mode 100644 index 00000000000..b2cfd3123ee --- /dev/null +++ b/test/jdk/javax/swing/JSpinner/bug4656590.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2003, 2023, 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 javax.swing.JFormattedTextField; +import javax.swing.JFrame; +import javax.swing.JSpinner; +import javax.swing.SpinnerDateModel; +import javax.swing.SpinnerListModel; +import javax.swing.SpinnerNumberModel; +import javax.swing.SwingUtilities; +import java.awt.Font; +import java.awt.GridLayout; +import java.awt.Robot; + +/* + * @test + * @bug 4656590 + * @summary JSpinner.setFont() does nothing + * @key headful + * @run main bug4656590 + */ + +public class bug4656590 { + private static JSpinner[] spinner = new JSpinner[6]; + private static Font font = new Font("Arial", Font.BOLD, 24); + private static volatile boolean failed = false; + private static JFrame frame; + private static Robot robot; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame(); + frame.getContentPane().setLayout(new GridLayout(3, 2)); + spinner[0] = new JSpinner(); + spinner[0].setModel(new SpinnerNumberModel()); + spinner[0].setFont(font); + frame.getContentPane().add(spinner[0]); + + spinner[1] = new JSpinner(); + spinner[1].setModel(new SpinnerDateModel()); + spinner[1].setFont(font); + frame.getContentPane().add(spinner[1]); + + spinner[2] = new JSpinner(); + spinner[2].setModel(new SpinnerListModel + (new Object[]{"one", "two", "three"})); + spinner[2].setFont(font); + frame.getContentPane().add(spinner[2]); + + spinner[3] = new JSpinner(); + spinner[3].setFont(font); + spinner[3].setModel(new SpinnerNumberModel()); + frame.getContentPane().add(spinner[3]); + + spinner[4] = new JSpinner(); + spinner[4].setFont(font); + spinner[4].setModel(new SpinnerDateModel()); + frame.getContentPane().add(spinner[4]); + + spinner[5] = new JSpinner(); + spinner[5].setFont(font); + spinner[5].setModel(new SpinnerListModel + (new Object[]{"one", "two", "three"})); + frame.getContentPane().add(spinner[5]); + frame.pack(); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + JFormattedTextField ftf; + for (int i = 1; i < 6; i++) { + ftf = ((JSpinner.DefaultEditor) + spinner[i].getEditor()).getTextField(); + if (!ftf.getFont().equals(font)) { + failed = true; + } + } + }); + robot.waitForIdle(); + robot.delay(1000); + if (failed) { + throw new RuntimeException("JSpinner.setFont() " + + "doesn't set the font properly"); + } + System.out.println("Test Passed!"); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/javax/swing/JSpinner/bug4680204.java b/test/jdk/javax/swing/JSpinner/bug4680204.java new file mode 100644 index 00000000000..ecd923f2a4d --- /dev/null +++ b/test/jdk/javax/swing/JSpinner/bug4680204.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2003, 2023, 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 javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JSpinner; +import javax.swing.JTextField; +import javax.swing.SpinnerNumberModel; +import javax.swing.SwingUtilities; +import java.awt.Component; +import java.awt.FlowLayout; +import java.awt.Robot; + +/* + * @test + * @bug 4680204 + * @summary JSpinner shows ToolTipText only on it's border + * @key headful + * @run main bug4680204 + */ + +public class bug4680204 { + + private static JSpinner sp1, sp2; + private static final String TOOL_TIP_TEXT = "ToolTipText"; + private static JFrame frame; + private static Robot robot; + private static volatile boolean failed = false; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame(); + frame.getContentPane().setLayout(new FlowLayout()); + + sp1 = new JSpinner(new SpinnerNumberModel(1, 1, 100, 1)); + sp1.setToolTipText(TOOL_TIP_TEXT); + frame.getContentPane().add(sp1); + + sp2 = new JSpinner(); + sp2.setToolTipText(TOOL_TIP_TEXT); + frame.getContentPane().add(sp2); + sp2.setModel(new SpinnerNumberModel(1, 1, 100, 1)); + frame.setLocationRelativeTo(null); + frame.pack(); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + Component[] children = sp1.getComponents(); + for (int i = 0; i < children.length; i++) { + if (children[i] instanceof JSpinner.DefaultEditor) { + JTextField tf = ((JSpinner.DefaultEditor) children[i]).getTextField(); + if (!TOOL_TIP_TEXT.equals(tf.getToolTipText())) { + failed = true; + } + } else if (children[i] instanceof JComponent) { + String text = ((JComponent) children[i]).getToolTipText(); + if (!TOOL_TIP_TEXT.equals(text)) { + failed = true; + } + } + } + + children = sp2.getComponents(); + for (int i = 0; i < children.length; i++) { + if (children[i] instanceof JSpinner.DefaultEditor) { + JTextField tf = ((JSpinner.DefaultEditor) children[i]).getTextField(); + if (!TOOL_TIP_TEXT.equals(tf.getToolTipText())) { + failed = true; + } + } else if (children[i] instanceof JComponent) { + String text = ((JComponent) children[i]).getToolTipText(); + if (!TOOL_TIP_TEXT.equals(text)) { + failed = true; + } + } + } + }); + robot.waitForIdle(); + robot.delay(1000); + if (failed) { + throw new RuntimeException("The tooltip text is not correctly set for JSpinner"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + System.out.println("Test Passed!"); + } +} diff --git a/test/jdk/javax/swing/JSpinner/bug4862257.java b/test/jdk/javax/swing/JSpinner/bug4862257.java new file mode 100644 index 00000000000..b87b7b359a3 --- /dev/null +++ b/test/jdk/javax/swing/JSpinner/bug4862257.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2003, 2023, 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 javax.swing.JButton; +import javax.swing.JSpinner; + +/* + * @test + * @bug 4862257 + * @summary Class cast Exception occurred when JButton is set to JSpinner + * @run main bug4862257 + */ + +public class bug4862257 { + public static void main(String[] argv) { + JSpinner spinner = new JSpinner(); + spinner.setEditor(new JButton("JButton")); + System.out.println("Test Passed!"); + } +} diff --git a/test/jdk/javax/swing/JSpinner/bug5104421.java b/test/jdk/javax/swing/JSpinner/bug5104421.java new file mode 100644 index 00000000000..cad5d8c9e0a --- /dev/null +++ b/test/jdk/javax/swing/JSpinner/bug5104421.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2004, 2023, 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 javax.swing.SpinnerDateModel; + +/* + * @test + * @bug 5104421 + * @summary SpinnerDateModel.setValue(Object) throws exception with incorrect message + * @run main bug5104421 + */ + +public class bug5104421 { + public static void main(String[] args) { + SpinnerDateModel model = new SpinnerDateModel(); + try { + model.setValue(Integer.valueOf(42)); + } catch (IllegalArgumentException e) { + if (e.getMessage().toLowerCase().indexOf("null value") != -1) { + throw new RuntimeException("SpinnerDateModel.setValue(Object) throws " + + "exception with incorrect message"); + } + } + System.out.println("Test Passed!"); + } +} diff --git a/test/jdk/javax/swing/JSplitPane/4885629/bug4885629.java b/test/jdk/javax/swing/JSplitPane/4885629/bug4885629.java index c7e980081cf..fa6c1f21063 100644 --- a/test/jdk/javax/swing/JSplitPane/4885629/bug4885629.java +++ b/test/jdk/javax/swing/JSplitPane/4885629/bug4885629.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, 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 @@ -104,9 +104,9 @@ public void run() { SwingUtilities.convertPointToScreen(p, sp); - for (int i = 0; i < rect.width; i++) { + for (int i = 1; i < rect.width - 1; i++) { if (!BGCOLOR.equals(robot.getPixelColor(p.x + i, p.y + rect.height - 1))) { - throw new Error("The divider's area has incorrect color."); + throw new Error("The divider's area has incorrect color. i=" + i); } } } diff --git a/test/jdk/javax/swing/JTabbedPane/TabbedPaneNPECheck.java b/test/jdk/javax/swing/JTabbedPane/TabbedPaneNPECheck.java new file mode 100644 index 00000000000..57321435bc4 --- /dev/null +++ b/test/jdk/javax/swing/JTabbedPane/TabbedPaneNPECheck.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2024, 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 8322239 + * @summary [macos] a11y : java.lang.NullPointerException is thrown when + * focus is moved on the JTabbedPane + * @key headful + * @run main TabbedPaneNPECheck + */ + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Rectangle; +import java.lang.reflect.InvocationTargetException; +import javax.accessibility.Accessible; +import javax.accessibility.AccessibleComponent; +import javax.accessibility.AccessibleContext; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.SwingUtilities; + +public class TabbedPaneNPECheck { + JTabbedPane pane; + JFrame mainFrame; + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + TabbedPaneNPECheck me = new TabbedPaneNPECheck(); + SwingUtilities.invokeAndWait(me::setupGUI); + try { + SwingUtilities.invokeAndWait(me::test); + } finally { + SwingUtilities.invokeAndWait(me::shutdownGUI); + } + } + + public void setupGUI() { + mainFrame = new JFrame("TabbedPaneNPECheck"); + pane = new JTabbedPane(); + Dimension panelSize = new Dimension(200, 200); + for (int i = 0; i < 25; i++) { + JPanel p = new JPanel(); + p.setMinimumSize(panelSize); + p.setMaximumSize(panelSize); + p.setSize(panelSize); + pane.addTab("Tab no." + i, p); + } + mainFrame.setLayout(new BorderLayout()); + mainFrame.add(pane, BorderLayout.CENTER); + mainFrame.setLocationRelativeTo(null); + mainFrame.setSize(250, 250); + mainFrame.setVisible(true); + } + + public void test() { + AccessibleContext context = pane.getAccessibleContext(); + int nChild = context.getAccessibleChildrenCount(); + for (int i = 0; i < nChild; i++) { + Accessible accessible = context.getAccessibleChild(i); + if (accessible instanceof AccessibleComponent) { + try { + AccessibleComponent component = (AccessibleComponent) accessible; + Point p = component.getLocationOnScreen(); + Rectangle r = component.getBounds(); + } catch (NullPointerException npe) { + throw new RuntimeException("Unexpected NullPointerException " + + "while getting accessible component bounds: ", npe); + } + } + } + } + + public void shutdownGUI() { + if (mainFrame != null) { + mainFrame.setVisible(false); + mainFrame.dispose(); + } + } +} diff --git a/test/jdk/javax/swing/JTextArea/bug4265784.java b/test/jdk/javax/swing/JTextArea/bug4265784.java new file mode 100644 index 00000000000..3465fced595 --- /dev/null +++ b/test/jdk/javax/swing/JTextArea/bug4265784.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 1999, 2023, 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 4265784 4267291 + * @summary Tests work of TAB key in JTextArea + * @key headful + * @run main bug4265784 + */ + +import javax.swing.JFrame; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +public class bug4265784 { + static JFrame frame; + static JTextArea ta; + static volatile Point p; + static volatile int pos; + static volatile int pos1; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(100); + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("bug4265784"); + ta = new JTextArea(); + frame.getContentPane().add(ta); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + p = ta.getLocationOnScreen(); + }); + robot.mouseMove(p.x + 10, p.y + 10); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + SwingUtilities.invokeAndWait(() -> { + pos = ta.getCaretPosition(); + }); + System.out.println(pos); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + pos1 = ta.getCaretPosition(); + }); + System.out.println(pos1); + if (pos == pos1) { + throw new RuntimeException("TAB ignored"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/javax/swing/MultiMonitor/MultimonVImage.java b/test/jdk/javax/swing/MultiMonitor/MultimonVImage.java new file mode 100644 index 00000000000..42cb9c96da5 --- /dev/null +++ b/test/jdk/javax/swing/MultiMonitor/MultimonVImage.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2000, 2023, 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 4371134 + * @key headful + * @summary displays an animating fps (frames per second) + * counter. When the window is dragged from monitor to monitor, + * the speed of the animation should not change too greatly. + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MultimonVImage + */ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.JViewport; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class MultimonVImage { + private static final String instructionsText = + "This test should be run on any Windows platform that\n" + + "supports multiple monitors.\n" + + "You will see an animating fps (frames per second) counter at\n" + + "the bottom of the window. Drag the window into the other monitor\n" + + "and that counter should not change drastically. If the counter\n" + + "is much lower on one monitor than the other (barring situations\n" + + "described below) then the back buffer may not be accelerated\n" + + "on the second monitor and the test fails.\n" + + "Situations in which performance will differ even though there\n" + + "is acceleration on both monitors include:\n" + + " - different bit depths on each monitor. The higher the bits\n" + + " per pixel, the more data to push and the lower the fps number.\n" + + " Set the bit depths to be the same on both monitors to work\n" + + " around this issue.\n" + + " - the amount of acceleration available on each video card differs,\n" + + " so if your system uses different video cards then you should\n" + + " expect some difference between the cards. To work around this\n" + + " issue, try to use the same or similar video cards for each monitor."; + + public static void main(String[] args) throws Exception { + PassFailJFrame passFailJFrame = new PassFailJFrame.Builder() + .title("MultimonVImage Instructions") + .instructions(instructionsText) + .testTimeOut(5) + .rows(25) + .columns(50) + .build(); + + SwingUtilities.invokeAndWait(() -> { + AnimatingFrame af = new AnimatingFrame(); + af.test(); + af.run(); + + PassFailJFrame.addTestWindow(af); + PassFailJFrame.positionTestWindow(af, + PassFailJFrame.Position.HORIZONTAL); + }); + + passFailJFrame.awaitAndCheck(); + } +} + +class FrameCounter { + + String fpsString = "Calculating..."; + long startTime, endTime; + int numFrames; + + public FrameCounter() { + startTime = System.currentTimeMillis(); + } + + public String addFrame() { + ++numFrames; + return calculateFPS(); + } + + String calculateFPS() { + endTime = System.currentTimeMillis(); + double seconds = ((double) endTime - (double) startTime) / 1000; + if (seconds > 1) { + int fps = (int) (numFrames / seconds); + fpsString = fps + " fps"; + startTime = endTime; + numFrames = 0; + } + return fpsString; + } +} + +class AnimatingComponent extends JViewport { + + FrameCounter frameCounter; + int boxX, boxY; + int boxW, boxH; + int xStep = 1; + + public AnimatingComponent() { + frameCounter = new FrameCounter(); + boxX = 0; + boxY = 0; + boxW = 100; + boxH = 100; + } + + public void paintComponent(Graphics g) { + boxX += xStep; + if (boxX <= 0 || (boxX + boxW) > getWidth()) { + xStep = -xStep; + boxX += (2 * xStep); + } + g.setColor(Color.white); + g.fillRect(0, 0, getWidth(), getHeight()); + g.setColor(Color.green); + for (int i = 0; i < 100; ++i) { + g.fillRect(boxX, boxY, 100, 100); + } + g.setColor(Color.black); + g.drawString(frameCounter.addFrame(), 200, getHeight() - 30); + } +} + +class AnimatingFrame extends JFrame implements Runnable { + JViewport component; + Thread thread; + + public AnimatingFrame() { + setSize(500, 500); + setTitle("MultimonVImage Demo"); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + component = new AnimatingComponent(); + component.setPreferredSize(new Dimension(500, 500)); + setContentPane(component); + component.setVisible(true); + + setLocationRelativeTo(null); + pack(); + setVisible(true); + } + + public void test() { + thread = new Thread(this); + thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); + } + + public void run() { + Thread me = Thread.currentThread(); + while (thread == me) { + component.repaint(); + } + } +} + diff --git a/test/jdk/javax/swing/SwingGraphics/TranslateTest.java b/test/jdk/javax/swing/SwingGraphics/TranslateTest.java new file mode 100644 index 00000000000..305b5c0b3a4 --- /dev/null +++ b/test/jdk/javax/swing/SwingGraphics/TranslateTest.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 1999, 2023, 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 4207383 + * @summary This tests, in a round about manner, that SwingGraphics does + * not wrongly translate the original graphics when disposed. While + * this test seems rather ugly, it was possible to get this to happen + * in real world apps. This test is really only valid for 1.1.x. + * @key headful + * @run main TranslateTest + */ + +import java.io.File; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Image; +import java.awt.image.BufferedImage; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.plaf.ComponentUI; +import javax.imageio.ImageIO; + +public class TranslateTest { + static JFrame frame; + static volatile Point pt; + static volatile Dimension dim; + static final int WIDTH = 200; + static final int HEIGHT = 200; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("TranslateTest"); + + // paintComponent() triggers create swing graphics which will + // be invoked on child. + MyPanel panel = new MyPanel(); + panel.setPreferredSize(new Dimension(WIDTH, HEIGHT)); + frame.getContentPane().add(panel); + frame.pack(); + frame.setLocationRelativeTo(null); + panel.test(); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + pt = frame.getLocationOnScreen(); + dim = frame.getSize(); + }); + BufferedImage img = robot.createScreenCapture( + new Rectangle(pt.x + dim.width / 2, + pt.y + dim.height / 2, + WIDTH / 2, HEIGHT / 2)); + robot.waitForIdle(); + robot.delay(500); + Color c = new Color(img.getRGB(img.getWidth() / 2, img.getHeight() / 2)); + if (c.getRed() < 250) { + ImageIO.write(img, "png", new File("image.png")); + System.out.println("Color " + c); + throw new RuntimeException("Translated Color is not red"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + + static class MyPanel extends JPanel { + int state; + Graphics realG; + Image image; + + public void test() { + image = createImage(TranslateTest.WIDTH, TranslateTest.HEIGHT); + Graphics g = image.getGraphics(); + g.setClip(0, 0, TranslateTest.WIDTH, TranslateTest.HEIGHT); + realG = g; + state = 1; + paintComponent(g); + state = 3; + paintComponent(g); + state = 4; + } + + + public void paint(Graphics g) { + if (state == 0) { + test(); + } + super.paint(g); + } + + protected void paintComponent(Graphics g) { + super.paintComponent(g); + } + + public void updateUI() { + setUI(new ComponentUI() { + public void paint(Graphics g, JComponent c) { + if (state == 1) { + // g is the first SwingGraphics, when it is disposed + // translateX/translateY will be wrong + //System.out.println("FIRST:" + g); + g.translate(100, 100); + state = 2; + paintComponent(realG); + } + else if (state == 2) { + // g is the first SwingGraphics, when it is disposed + // translateX/translateY will be wrong + g.translate(100, 100); + //System.out.println("Second:" + g); + } + else if (state == 3) { + // g should be the same as the first, with the wrong + // translate. + // otherG should be the second graphics, again with + // the wrong translation, disposing the second will + // cause g to be translated to -100, -100, which + // should not happen. + Graphics otherG = g.create(0, 0, 100, 100); + //System.out.println("THIRD:" + g); + otherG.dispose(); + g.setColor(Color.red); + //System.out.println("LAST: " + g); + g.fillRect(100, 100, 100, 100); + } + else if (state == 4) { + g.drawImage(image, 0, 0, null); + } + } + }); + } + } +} diff --git a/test/jdk/javax/swing/event/bug4143690.java b/test/jdk/javax/swing/event/bug4143690.java new file mode 100644 index 00000000000..971d1984656 --- /dev/null +++ b/test/jdk/javax/swing/event/bug4143690.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 1999, 2023, 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 4143690 + @summary Tests that TreeSelectionEvent has isAddedPath(int) method + @run main bug4143690 +*/ + +import javax.swing.event.TreeSelectionEvent; +import javax.swing.tree.TreePath; + +public class bug4143690 { + + public static void main(String[] argv) throws Exception { + bug4143690 test = new bug4143690(); + TreePath p = new TreePath(""); + TreeSelectionEvent e = new TreeSelectionEvent(test, p, true, p, p); + + TreePath[] paths = e.getPaths(); + for(int i = 0; i < paths.length; i++) { + TreePath path = paths[i]; + if (e.isAddedPath(i) != true) { + throw new RuntimeException("Incorrect isAddedPath(int)..."); + } + } + } +} diff --git a/test/jdk/javax/swing/event/bug4160240.java b/test/jdk/javax/swing/event/bug4160240.java new file mode 100644 index 00000000000..4a3654271dc --- /dev/null +++ b/test/jdk/javax/swing/event/bug4160240.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1999, 2023, 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 4160240 + @summary InternalFrameEvent has getInternalFrame() method. + @run main bug4160240 +*/ + +import javax.swing.JInternalFrame; +import javax.swing.event.InternalFrameEvent; + +public class bug4160240 { + + public static void main(String[] argv) throws Exception { + JInternalFrame jif = new JInternalFrame(); + InternalFrameEvent ife = new InternalFrameEvent(jif, + InternalFrameEvent.INTERNAL_FRAME_OPENED); + if (ife.getInternalFrame() != jif) { + throw new RuntimeException("JInternalFrame.getInternalFrame " + + " doesn't work correctly..."); + } + } +} diff --git a/test/jdk/javax/swing/reliability/HangDuringStaticInitialization.java b/test/jdk/javax/swing/reliability/HangDuringStaticInitialization.java index fc820a32fa1..d6666d21309 100644 --- a/test/jdk/javax/swing/reliability/HangDuringStaticInitialization.java +++ b/test/jdk/javax/swing/reliability/HangDuringStaticInitialization.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, 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 @@ -33,7 +33,6 @@ /** * @test * @bug 8189604 8208702 - * @requires !vm.debug | os.family != "windows" * @run main/othervm -Djava.awt.headless=false HangDuringStaticInitialization * @run main/othervm -Djava.awt.headless=true HangDuringStaticInitialization */ diff --git a/test/jdk/javax/swing/text/StyledEditorKit/bug4253334.java b/test/jdk/javax/swing/text/StyledEditorKit/bug4253334.java new file mode 100644 index 00000000000..625b47055c0 --- /dev/null +++ b/test/jdk/javax/swing/text/StyledEditorKit/bug4253334.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1999, 2023, 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 javax.swing.Action; +import javax.swing.JEditorPane; +import javax.swing.text.AttributeSet; +import javax.swing.text.Caret; +import javax.swing.text.Element; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.html.HTMLDocument; +import javax.swing.text.html.HTMLEditorKit; +import java.awt.event.ActionEvent; +import java.io.StringReader; + +/* + * @test + * @bug 4253334 + * @summary Tests that bold attribute unsets properly + */ + +public class bug4253334 { + + public static void main(String[] args) throws Exception { + JEditorPane ep = new JEditorPane(); + ep.setEditable(true); + ep.setContentType("text/html"); + + HTMLEditorKit kit = (HTMLEditorKit)ep.getEditorKit(); + HTMLDocument doc = (HTMLDocument)kit.createDefaultDocument(); + ep.setDocument(doc); + String text = "somesampletext"; + kit.read(new StringReader(text), doc, 0); + + // make some text bold & italic + MutableAttributeSet attrs = new SimpleAttributeSet(); + StyleConstants.setBold(attrs, true); + StyleConstants.setItalic(attrs, true); + doc.setCharacterAttributes(3, 9, attrs, false); + + Action[] as = kit.getActions(); + Action boldAction = null; + + for (Action a : as) { + String s = (String) (a.getValue(Action.NAME)); + if (s.equals("font-bold")) { + boldAction = a; + } + } + Caret caret = ep.getCaret(); + ActionEvent event = new ActionEvent(ep, ActionEvent.ACTION_PERFORMED, + "font-bold"); + caret.setDot(3); + caret.moveDot(7); + boldAction.actionPerformed(event); + caret.setDot(7); + caret.moveDot(12); + boldAction.actionPerformed(event); + + Element elem = doc.getCharacterElement(9); + AttributeSet at = elem.getAttributes(); + if (StyleConstants.isBold(at)) { + throw new RuntimeException("Test Failed: bold attribute set"); + } + } +} diff --git a/test/jdk/javax/swing/text/StyledEditorKit/bug4329418.java b/test/jdk/javax/swing/text/StyledEditorKit/bug4329418.java new file mode 100644 index 00000000000..e06c9d36aa7 --- /dev/null +++ b/test/jdk/javax/swing/text/StyledEditorKit/bug4329418.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2000, 2023, 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.awt.Robot; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.text.Document; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledEditorKit; + +/* + * @test + * @bug 4329418 + * @key headful + * @summary Tests if setCharacterAttributes() is maintained + * after return in J(Editor/Text)Pane + */ + +public class bug4329418 { + private static JFrame jf; + private static StyledEditorKit sek; + + private static volatile boolean passed = false; + private static final int FONT_SIZE = 36; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + + SwingUtilities.invokeAndWait(bug4329418::createAndShowUI); + robot.waitForIdle(); + robot.delay(500); + + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + robot.delay(300); + + if (!passed) { + throw new RuntimeException("Test failed." + + " setCharacterAttributes() does not work correctly"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (jf != null) { + jf.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + jf = new JFrame("setCharacterAttributes Test"); + sek = new StyledEditorKit(); + JEditorPane jep = new JEditorPane(); + jep.setEditorKit(sek); + + MutableAttributeSet attrs = sek.getInputAttributes(); + StyleConstants.setFontSize(attrs, FONT_SIZE); + + jep.addKeyListener(new KeyAdapter() { + public void keyReleased(KeyEvent e) { + MutableAttributeSet attrs = sek.getInputAttributes(); + passed = (StyleConstants.getFontSize(attrs) == FONT_SIZE); + } + }); + + jep.setText("aaa"); + Document doc = jep.getDocument(); + jep.setCaretPosition(doc.getLength()); + + jf.getContentPane().add(jep); + jf.setLocationRelativeTo(null); + jf.setSize(200, 200); + jf.setVisible(true); + } +} diff --git a/test/jdk/javax/swing/text/bug4739057.java b/test/jdk/javax/swing/text/bug4739057.java new file mode 100644 index 00000000000..904ea8de18f --- /dev/null +++ b/test/jdk/javax/swing/text/bug4739057.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2003, 2023, 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 javax.swing.JFormattedTextField; +import javax.swing.SwingUtilities; +import javax.swing.text.MaskFormatter; +import java.text.ParseException; + +/* + * @test + * @bug 4739057 + * @summary replaceSelection() method fails on JFormattedTextField + */ + +public class bug4739057 { + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + MaskFormatter formatter; + try { + formatter = new MaskFormatter("(###) ###-####"); + } catch (ParseException e) { + throw new RuntimeException(e); + } + formatter.setPlaceholderCharacter('#'); + JFormattedTextField textField = new JFormattedTextField(formatter); + textField.replaceSelection("12345"); + if (!textField.getText().equals("(123) 45#-####")) { + throw new RuntimeException("Test Failed! replaceSelection() didn't replace text properly"); + } + }); + } +} diff --git a/test/jdk/javax/swing/text/bug4763466.java b/test/jdk/javax/swing/text/bug4763466.java new file mode 100644 index 00000000000..db2a914cb8b --- /dev/null +++ b/test/jdk/javax/swing/text/bug4763466.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2003, 2023, 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 javax.swing.JFormattedTextField; +import javax.swing.text.NumberFormatter; +import java.text.DecimalFormat; + +/* + * @test + * @bug 4763466 + * @summary JFormattedTextField and the - sign + */ + +public class bug4763466 { + + public static void main(String[] args) throws Exception { + DecimalFormat decimalFormat = new DecimalFormat("##0.00"); + NumberFormatter textFormatter = new NumberFormatter(decimalFormat); + textFormatter.setAllowsInvalid(false); + textFormatter.setValueClass(Double.class); + + JFormattedTextField ftf = new JFormattedTextField(textFormatter); + ftf.setCaretPosition(0); + ftf.setValue((double) -1); + + if (ftf.getCaretPosition() == 0) { + throw new RuntimeException("Test Failed. Caret position shouldn't be 0" + + " as the sign is literal"); + } + } +} diff --git a/test/jdk/javax/swing/text/html/HTMLDocument/bug4226914.java b/test/jdk/javax/swing/text/html/HTMLDocument/bug4226914.java new file mode 100644 index 00000000000..8bfaae935a2 --- /dev/null +++ b/test/jdk/javax/swing/text/html/HTMLDocument/bug4226914.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 1999, 2023, 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 javax.swing.JEditorPane; +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; + +/* + * @test + * @bug 4226914 + * @summary Tests if HTMLDocument streaming is broken + */ + +public class bug4226914 { + + public static void main(String[] args) throws Exception { + ObjectOutputStream oos = null; + try { + JEditorPane jtp = new JEditorPane("text/html", ""); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + oos = new ObjectOutputStream(baos); + oos.writeObject(jtp.getDocument()); + oos.flush(); + baos.toByteArray(); + } finally { + if (oos != null) { + oos.close(); + } + } + } +} diff --git a/test/jdk/javax/swing/text/html/HTMLDocument/bug4251593.java b/test/jdk/javax/swing/text/html/HTMLDocument/bug4251593.java new file mode 100644 index 00000000000..bdd51d68a2e --- /dev/null +++ b/test/jdk/javax/swing/text/html/HTMLDocument/bug4251593.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 1999, 2023, 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.awt.event.ActionEvent; +import javax.swing.Action; +import javax.swing.JTextPane; +import javax.swing.SwingUtilities; +import javax.swing.text.html.HTML; +import javax.swing.text.html.HTMLEditorKit; + +/* + * @test + * @bug 4251593 + * @summary Tests that hyperlinks can be inserted into JTextPane + * via InsertHTMLTextAction. + */ + +public class bug4251593 { + private static JTextPane editor; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + editor = new JTextPane(); + editor.setContentType("text/html"); + editor.setEditable(true); + + int beforeLen = editor.getDocument().getLength(); + + String href = "javasoft "; + Action a = new HTMLEditorKit.InsertHTMLTextAction("Tester", href, HTML.Tag.BODY, HTML.Tag.A); + a.actionPerformed(new ActionEvent(editor, 0, null)); + + int afterLen = editor.getDocument().getLength(); + try { + Thread.sleep(300); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if ((afterLen - beforeLen) < 8) { + throw new RuntimeException("Test Failed: link not inserted!!"); + } + }); + } +} diff --git a/test/jdk/javax/swing/text/html/HTMLDocument/bug4687405.java b/test/jdk/javax/swing/text/html/HTMLDocument/bug4687405.java new file mode 100644 index 00000000000..5e549477072 --- /dev/null +++ b/test/jdk/javax/swing/text/html/HTMLDocument/bug4687405.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2003, 2023, 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 javax.swing.JEditorPane; +import javax.swing.SwingUtilities; +import javax.swing.text.AttributeSet; +import javax.swing.text.View; +import javax.swing.text.html.CSS; +import javax.swing.text.html.HTMLEditorKit; + +/* + * @test + * @bug 4687405 + * @summary Tests if HTMLDocument very first paragraph doesn't have top margin. + */ + +public class bug4687405 { + private static JEditorPane jep; + private static volatile boolean passed = false; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(bug4687405::createHTMLEditor); + Thread.sleep(200); + + SwingUtilities.invokeAndWait(bug4687405::testEditorPane); + Thread.sleep(500); + + if (!passed) { + throw new RuntimeException("Test failed!!" + + " Top margin present in HTMLDocument"); + } + } + + public static void createHTMLEditor() { + jep = new JEditorPane(); + jep.setEditorKit(new HTMLEditorKit()); + jep.setEditable(false); + } + + private static void testEditorPane() { + View v = jep.getUI().getRootView(jep); + while (!(v instanceof javax.swing.text.html.ParagraphView)) { + int n = v.getViewCount(); + v = v.getView(n - 1); + } + AttributeSet attrs = v.getAttributes(); + String marginTop = attrs.getAttribute(CSS.Attribute.MARGIN_TOP).toString(); + // MARGIN_TOP of the very first paragraph of the default html + // document should be 0. + passed = "0".equals(marginTop); + } +} diff --git a/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4213373.java b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4213373.java new file mode 100644 index 00000000000..621547faca5 --- /dev/null +++ b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4213373.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 1999, 2023, 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 javax.swing.text.html.HTMLEditorKit; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +/* + * @test + * @bug 4213373 + * @summary Serialization bug on HTMLEditorKit. + */ + +public class bug4213373 { + + public static void main(String[] args) throws Exception { + HTMLEditorKit ekr = null; + ObjectOutputStream oos = null; + ObjectInputStream ois = null; + + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + HTMLEditorKit ekw = new HTMLEditorKit(); + oos = new ObjectOutputStream(baos); + oos.writeObject(ekw); + byte[] buf = baos.toByteArray(); + + ByteArrayInputStream bais = new ByteArrayInputStream(buf); + ois = new ObjectInputStream(bais); + ekr = (HTMLEditorKit) ois.readObject(); + } finally { + if (oos != null) { + oos.close(); + } + if (ois != null) { + ois.close(); + } + } + } +} diff --git a/test/jdk/javax/swing/text/html/Map/bug4322891.java b/test/jdk/javax/swing/text/html/Map/bug4322891.java new file mode 100644 index 00000000000..daee724e3a1 --- /dev/null +++ b/test/jdk/javax/swing/text/html/Map/bug4322891.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2000, 2023, 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 4322891 + * @summary Tests if image map receives correct coordinates. + * @key headful + * @run main bug4322891 +*/ + +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import javax.swing.JFrame; +import javax.swing.JEditorPane; +import javax.swing.SwingUtilities; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import javax.swing.text.html.HTMLEditorKit; + +public class bug4322891 { + + private boolean finished = false; + private static boolean passed = false; + private static Robot robot; + private static JFrame f; + private static JEditorPane jep; + private static volatile Point p; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + robot.setAutoDelay(100); + try { + bug4322891 test = new bug4322891(); + SwingUtilities.invokeAndWait(test::init); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + p = jep.getLocationOnScreen(); + }); + robot.mouseMove(p.x, p.y); + robot.waitForIdle(); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + for (int i = 1; i < 30; i++) { + robot.mouseMove(p.x + i, p.y + i); + robot.waitForIdle(); + } + if (!passed) { + throw new RuntimeException("Test failed."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } + + public void init() { + String text = "" + + "" + + "" + + ""; + + f = new JFrame(); + jep = new JEditorPane(); + jep.setEditorKit(new HTMLEditorKit()); + jep.setEditable(false); + + jep.setText(text); + + jep.addHyperlinkListener(new HyperlinkListener() { + public void hyperlinkUpdate(HyperlinkEvent e) { + passed = true; + } + }); + f.getContentPane().add(jep); + f.setSize(500,500); + f.setLocationRelativeTo(null); + f.setVisible(true); + } + +} diff --git a/test/jdk/javax/swing/text/html/StyleSheet/bug4476002.java b/test/jdk/javax/swing/text/html/StyleSheet/bug4476002.java new file mode 100644 index 00000000000..bb3a1d72b0e --- /dev/null +++ b/test/jdk/javax/swing/text/html/StyleSheet/bug4476002.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2003, 2023, 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 4476002 + * @summary Verifies JEditorPane:

    list numbers do not pick up color of the list text + * @key headful + * @run main bug4476002 +*/ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.SwingUtilities; + +public class bug4476002 { + + private static boolean passed = true; + private static JLabel htmlComponent; + + private static Robot robot; + private static JFrame mainFrame; + private static volatile Point p; + private static volatile Dimension d; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + + try { + SwingUtilities.invokeAndWait(() -> { + String htmlText = + "" + + "
    1. wwwww
    "; + + mainFrame = new JFrame("bug4476002"); + + htmlComponent = new JLabel(htmlText); + mainFrame.getContentPane().add(htmlComponent); + + mainFrame.pack(); + mainFrame.setLocationRelativeTo(null); + mainFrame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + p = htmlComponent.getLocationOnScreen(); + d = htmlComponent.getSize(); + }); + int x0 = p.x; + int y = p.y + d.height/2; + + for (int x = x0; x < x0 + d.width; x++) { + if (robot.getPixelColor(x, y).equals(Color.black)) { + passed = false; + break; + } + } + if (!passed) { + throw new RuntimeException("Test failed."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (mainFrame != null) { + mainFrame.dispose(); + } + }); + } + } + +} diff --git a/test/jdk/javax/swing/text/html/TableView/bug4412522.java b/test/jdk/javax/swing/text/html/TableView/bug4412522.java new file mode 100644 index 00000000000..f983b07ecfc --- /dev/null +++ b/test/jdk/javax/swing/text/html/TableView/bug4412522.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2003, 2023, 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 4412522 + * @summary Tests if HTML that has comments inside of tables is rendered correctly + * @key headful + * @run main bug4412522 +*/ + +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.text.View; +import javax.swing.text.html.HTMLEditorKit; + +import java.awt.Robot; +import java.awt.Shape; + +public class bug4412522 { + + private static boolean passed = false; + + private static JEditorPane jep; + private static JFrame f; + private static Robot robot; + + public void init() { + + String text = + "
TargetDebian treeDebian arch--openjdk-target=...TargetDebian treeDebian arch--openjdk-target=... --with-jvm-variants=...
x86busteri386i386-linux-gnux86busteri386i386-linux-gnu (all)
armbusterarmhfarm-linux-gnueabihfarmbusterarmhfarm-linux-gnueabihf (all)
aarch64busterarm64aarch64-linux-gnuaarch64busterarm64aarch64-linux-gnu (all)
ppc64lebusterppc64elpowerpc64le-linux-gnuppc64lebusterppc64elpowerpc64le-linux-gnu (all)
s390xbusters390xs390x-linux-gnus390xbusters390xs390x-linux-gnu (all)
mipslebustermipselmipsel-linux-gnumipslebustermipselmipsel-linux-gnu zero
mips64lebustermips64elmips64el-linux-gnueabi64mips64lebustermips64elmips64el-linux-gnueabi64 zero
armelbusterarmarm-linux-gnueabiarmelbusterarmarm-linux-gnueabi zero
ppcsidpowerpcpowerpc-linux-gnuppcsidpowerpcpowerpc-linux-gnu zero
ppc64besidppc64powerpc64-linux-gnuppc64besidppc64powerpc64-linux-gnu (all)
m68ksidm68km68k-linux-gnum68ksidm68km68k-linux-gnu zero
alphasidalphaalpha-linux-gnualphasidalphaalpha-linux-gnu zero
sh4sidsh4sh4-linux-gnush4sidsh4sh4-linux-gnu zero
" + + "" + + "" + + "
first cellsecond cell
row heading
"; + + JFrame f = new JFrame(); + jep = new JEditorPane(); + jep.setEditorKit(new HTMLEditorKit()); + jep.setEditable(false); + + jep.setText(text); + + f.getContentPane().add(jep); + f.setSize(500,500); + f.setLocationRelativeTo(null); + f.setVisible(true); + } + + + public static void main(String args[]) throws Exception { + robot = new Robot(); + robot.setAutoDelay(100); + bug4412522 test = new bug4412522(); + try { + SwingUtilities.invokeAndWait(() -> test.init()); + robot.waitForIdle(); + robot.delay(1000); + Shape r = jep.getBounds(); + View v = jep.getUI().getRootView(jep); + int tableWidth = 0; + int cellsWidth = 0; + + while (!(v instanceof javax.swing.text.html.ParagraphView)) { + + int n = v.getViewCount(); + Shape sh = v.getChildAllocation(n - 1, r); + String viewName = v.getClass().getName(); + if (viewName.endsWith("TableView")) { + tableWidth = r.getBounds().width; + } + + if (viewName.endsWith("CellView")) { + cellsWidth = r.getBounds().x + r.getBounds().width; + } + + v = v.getView(n - 1); + if (sh != null) { + r = sh; + } + } + + passed = ((tableWidth - cellsWidth) > 10); + if (!passed) { + throw new RuntimeException("Test failed."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } +} diff --git a/test/jdk/javax/swing/text/html/TableView/bug4690812.java b/test/jdk/javax/swing/text/html/TableView/bug4690812.java new file mode 100644 index 00000000000..263bba71f14 --- /dev/null +++ b/test/jdk/javax/swing/text/html/TableView/bug4690812.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2003, 2023, 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 4690812 + * @summary Tests if tables are correctly formatted in some cases + * @key headful + * @run main bug4690812 +*/ + +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.text.View; +import javax.swing.text.html.HTMLEditorKit; + +import java.awt.Robot; +import java.awt.Shape; + +public class bug4690812 { + + private static boolean passed = false; + + private static JEditorPane jep; + private static JFrame f; + + public void init() { + + String text = + "" + + "" + + "" + + "" + + "
a
something
"; + + JFrame f = new JFrame(); + jep = new JEditorPane(); + jep.setEditorKit(new HTMLEditorKit()); + jep.setEditable(false); + + jep.setText(text); + + f.getContentPane().add(jep); + f.setSize(500,500); + f.setLocationRelativeTo(null); + f.setVisible(true); + } + + public static void main(String args[]) throws Exception { + Robot robot = new Robot(); + bug4690812 test = new bug4690812(); + try { + SwingUtilities.invokeAndWait(() -> test.init()); + robot.waitForIdle(); + robot.delay(1000); + Shape r = jep.getBounds(); + View v = jep.getUI().getRootView(jep); + int tableHeight = 0; + while (!(v instanceof javax.swing.text.html.ParagraphView)) { + int n = v.getViewCount(); + Shape sh = v.getChildAllocation(n - 1, r); + v = v.getView(n - 1); + if (sh != null) { + r = sh; + } + } + // left column in the second table row should have width == 1 + passed = (r.getBounds().width == 1) ? true : false; + if (!passed) { + throw new RuntimeException("Test failed."); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } +} diff --git a/test/jdk/javax/swing/text/html/bug4210307.java b/test/jdk/javax/swing/text/html/bug4210307.java new file mode 100644 index 00000000000..6af4e62f805 --- /dev/null +++ b/test/jdk/javax/swing/text/html/bug4210307.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1999, 2023, 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 javax.swing.JButton; +import javax.swing.JEditorPane; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.text.Document; +import javax.swing.text.Element; +import javax.swing.text.html.FormView; + +/* + * @test + * @bug 4210307 4210308 + * @summary Tests that FormView button text is internationalized + */ + +public class bug4210307 { + private static final String RESET_PROPERTY = "TEST RESET"; + private static final String SUBMIT_PROPERTY = "TEST SUBMIT"; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + Object oldReset = UIManager.put("FormView.resetButtonText", + RESET_PROPERTY); + Object oldSubmit = UIManager.put("FormView.submitButtonText", + SUBMIT_PROPERTY); + + try { + JEditorPane ep = new JEditorPane("text/html", + ""); + Document doc = ep.getDocument(); + Element elem = findInputElement(doc.getDefaultRootElement()); + TestView view = new TestView(elem); + view.test(SUBMIT_PROPERTY); + + ep = new JEditorPane("text/html", + ""); + doc = ep.getDocument(); + elem = findInputElement(doc.getDefaultRootElement()); + view = new TestView(elem); + view.test(RESET_PROPERTY); + } finally { + UIManager.put("FormView.resetButtonText", oldReset); + UIManager.put("FormView.submitButtonText", oldSubmit); + } + }); + } + + private static Element findInputElement(Element root) { + for (int i = 0; i < root.getElementCount(); i++) { + Element elem = root.getElement(i); + if (elem.getName().equals("input")) { + return elem; + } else { + Element e = findInputElement(elem); + if (e != null) return e; + } + } + return null; + } + + static class TestView extends FormView { + public TestView(Element elem) { + super(elem); + } + + public void test(String caption) { + JButton comp = (JButton) createComponent(); + if (!comp.getText().equals(caption)) { + throw new RuntimeException("Failed: '" + comp.getText() + + "' instead of `" + caption + "'"); + } + } + } +} diff --git a/test/jdk/javax/swing/text/html/bug4839739.java b/test/jdk/javax/swing/text/html/bug4839739.java new file mode 100644 index 00000000000..1dc5fbef123 --- /dev/null +++ b/test/jdk/javax/swing/text/html/bug4839739.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2003, 2023, 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 javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.text.html.HTMLEditorKit; +import java.awt.Component; +import java.awt.KeyboardFocusManager; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +/* + * @test + * @bug 4839739 + * @key headful + * @summary Tests if JEditorPane works correctly with HTML comments. + */ + +public class bug4839739 { + + private static JFrame jFrame; + private static JEditorPane jep; + private static volatile Point p; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.delay(50); + + SwingUtilities.invokeAndWait(bug4839739::createAndShowUI); + robot.waitForIdle(); + robot.delay(500); + + SwingUtilities.invokeAndWait(() -> p = jep.getLocationOnScreen()); + robot.delay(200); + + robot.mouseMove(p.x + 20, p.y + 20); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + robot.delay(300); + + Component comp = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + if (!(comp instanceof JEditorPane)) { + throw new RuntimeException("Test failed." + + " JEditorPane doesn't work as expected with HTML comments"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (jFrame != null) { + jFrame.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + String text = "" + + "some always visible text"; + + jFrame = new JFrame("JEditorPane With HTML"); + jep = new JEditorPane(); + jep.setEditorKit(new HTMLEditorKit()); + jep.setEditable(false); + + jep.setText(text); + jFrame.getContentPane().add(jep); + jFrame.setSize(200,200); + jFrame.setLocationRelativeTo(null); + jFrame.setVisible(true); + } +} diff --git a/test/jdk/javax/swing/text/rtf/bug4178276.java b/test/jdk/javax/swing/text/rtf/bug4178276.java new file mode 100644 index 00000000000..fc6ea8e2963 --- /dev/null +++ b/test/jdk/javax/swing/text/rtf/bug4178276.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1999, 2023, 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 4178276 + * @key headful + * @summary RTFEditorkit.write(...) doesn't throw NPE when used in SecurityManager + * @run main/othervm/secure=allow bug4178276 + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; +import javax.swing.text.Document; +import javax.swing.text.rtf.RTFEditorKit; + +public class bug4178276 { + + public static void main(String[] argv) throws Exception { + System.setSecurityManager(new SecurityManager()); + + String test="{\\rtf1\\ansi\\deff0\\deftab720{\\fonttbl{\\f0\\f swiss MS Sans Serif;}}{\\colortbl\\red0\\green0\\blue0;}\\qc\\plain\\f0 Test 1 \\par \\ql\\plain\\f0 Test 2 \\par \\qr\\plain\\f0 Test 3 \\par \\qj\\plain\\f0 Test 4}"; + RTFEditorKit c = new RTFEditorKit(); + Document doc = c.createDefaultDocument(); + try { + c.read(new ByteArrayInputStream(test.getBytes( + StandardCharsets.ISO_8859_1)), doc, 0); + ByteArrayOutputStream sw = new ByteArrayOutputStream(); + c.write(sw, doc, 0, 0); + } catch (Exception e) { + throw new RuntimeException("Unexpected NPE exception...", e); + } + } +} diff --git a/test/jdk/sun/misc/URLClassPath/ClassnameCharTest.java b/test/jdk/jdk/internal/loader/URLClassPath/ClassnameCharTest.java similarity index 100% rename from test/jdk/sun/misc/URLClassPath/ClassnameCharTest.java rename to test/jdk/jdk/internal/loader/URLClassPath/ClassnameCharTest.java diff --git a/test/jdk/sun/misc/URLClassPath/FileLoaderTest.java b/test/jdk/jdk/internal/loader/URLClassPath/FileLoaderTest.java similarity index 100% rename from test/jdk/sun/misc/URLClassPath/FileLoaderTest.java rename to test/jdk/jdk/internal/loader/URLClassPath/FileLoaderTest.java diff --git a/test/jdk/sun/misc/URLClassPath/JarLoaderTest.java b/test/jdk/jdk/internal/loader/URLClassPath/JarLoaderTest.java similarity index 100% rename from test/jdk/sun/misc/URLClassPath/JarLoaderTest.java rename to test/jdk/jdk/internal/loader/URLClassPath/JarLoaderTest.java diff --git a/test/jdk/sun/misc/URLClassPath/testclasses.jar b/test/jdk/jdk/internal/loader/URLClassPath/testclasses.jar similarity index 100% rename from test/jdk/sun/misc/URLClassPath/testclasses.jar rename to test/jdk/jdk/internal/loader/URLClassPath/testclasses.jar diff --git a/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java b/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java index 08773b3e8b5..6307a93fa56 100644 --- a/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java +++ b/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java @@ -72,12 +72,12 @@ private static void testMemoryFailCount() { } else { long count = Metrics.systemMetrics().getMemoryFailCount(); - // Allocate 512M of data - byte[][] bytes = new byte[64][]; + // Allocate 512M of data in 1M chunks per iteration + byte[][] bytes = new byte[64 * 8][]; boolean atLeastOneAllocationWorked = false; - for (int i = 0; i < 64; i++) { + for (int i = 0; i < 64 * 8; i++) { try { - bytes[i] = new byte[8 * 1024 * 1024]; + bytes[i] = new byte[1024 * 1024]; atLeastOneAllocationWorked = true; // Break out as soon as we see an increase in failcount // to avoid getting killed by the OOM killer. diff --git a/test/jdk/jdk/jfr/event/compiler/TestCompilerCompile.java b/test/jdk/jdk/jfr/event/compiler/TestCompilerCompile.java index 77352ba26e9..775d7789bee 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestCompilerCompile.java +++ b/test/jdk/jdk/jfr/event/compiler/TestCompilerCompile.java @@ -47,6 +47,7 @@ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:CompileOnly=jdk.jfr.event.compiler.TestCompilerCompile::dummyMethod,jdk.jfr.event.compiler.TestCompilerCompile::doTest * jdk.jfr.event.compiler.TestCompilerCompile */ public class TestCompilerCompile { diff --git a/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java b/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java index 0df2b5802cf..d1b325833c6 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java +++ b/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java @@ -42,6 +42,7 @@ * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm -Xbootclasspath/a:. + * -XX:-NeverActAsServerClassMachine * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:CompileOnly=jdk.jfr.event.compiler.TestCompilerPhase::dummyMethod * -XX:+SegmentedCodeCache -Xbootclasspath/a:. diff --git a/test/jdk/jdk/jfr/event/gc/collection/GCEventAll.java b/test/jdk/jdk/jfr/event/gc/collection/GCEventAll.java index 6668078a2f6..023acfb144b 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/GCEventAll.java +++ b/test/jdk/jdk/jfr/event/gc/collection/GCEventAll.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, 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 @@ -267,13 +267,17 @@ private void verifySingleGcBatch(List batches) { Instant batchStartTime = endEvent.getStartTime(); Instant batchEndTime = endEvent.getEndTime(); for (RecordedEvent event : batch.getEvents()) { - if (event.getEventType().getName().contains("AllocationRequiringGC")) { + String name = event.getEventType().getName(); + if (name.contains("AllocationRequiringGC")) { // Unlike other events, these are sent *before* a GC. Asserts.assertLessThanOrEqual(event.getStartTime(), batchStartTime, "Timestamp in event after start event, should be sent before GC start"); } else { Asserts.assertGreaterThanOrEqual(event.getStartTime(), batchStartTime, "startTime in event before batch start event, should be sent after GC start"); } - Asserts.assertLessThanOrEqual(event.getEndTime(), batchEndTime, "endTime in event after batch end event, should be sent before GC end"); + // GCCPUTime is generated after GC is completed. + if (!EventNames.GCCPUTime.equals(name)) { + Asserts.assertLessThanOrEqual(event.getEndTime(), batchEndTime, "endTime in event after batch end event, should be sent before GC end"); + } } // Verify that all required events has been received. diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestGCCPUTimeEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestGCCPUTimeEvent.java new file mode 100644 index 00000000000..9e7d7ca5413 --- /dev/null +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestGCCPUTimeEvent.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2022, 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 jdk.jfr.event.gc.detailed; + +import java.util.List; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; +import jdk.test.lib.jfr.EventNames; +import jdk.test.lib.jfr.Events; +import jdk.test.whitebox.WhiteBox; + +/** + * @test id=Serial + * @key jfr + * @requires vm.hasJFR + * @requires vm.gc.Serial + * @library /test/lib /test/jdk + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -Xmx32m -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseSerialGC jdk.jfr.event.gc.detailed.TestGCCPUTimeEvent + */ + +/** + * @test id=Parallel + * @key jfr + * @requires vm.hasJFR + * @requires vm.gc.Parallel + * @library /test/lib /test/jdk + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -Xmx32m -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseParallelGC jdk.jfr.event.gc.detailed.TestGCCPUTimeEvent + */ + +/** + * @test id=G1 + * @key jfr + * @requires vm.hasJFR + * @requires vm.gc.G1 + * @library /test/lib /test/jdk + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -Xmx32m -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC jdk.jfr.event.gc.detailed.TestGCCPUTimeEvent + */ + +public class TestGCCPUTimeEvent { + private static final String EVENT_NAME = EventNames.GCCPUTime; + + public static void main(String[] args) throws Exception { + + try (Recording recording = new Recording()) { + + // Activate the event we are interested in and start recording + recording.enable(EVENT_NAME); + recording.start(); + + // Guarantee one young GC. + WhiteBox.getWhiteBox().youngGC(); + recording.stop(); + + // Verify recording + List events = Events.fromRecording(recording); + Events.hasEvent(events, EVENT_NAME); + + recording.close(); + } + } +} diff --git a/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java b/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java index 692cd45d410..0d1bb7f6844 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, 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 @@ -23,8 +23,10 @@ package jdk.jfr.event.runtime; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import jdk.jfr.Configuration; import jdk.jfr.Event; @@ -60,6 +62,7 @@ private static class MyRegistrationEvent extends Event { public static void main(String[] args) throws Throwable { testDefaultSettings();; testProfileSettings();; + testOnlyOnce(); testNewSettings(); testChangedSetting(); testUnregistered(); @@ -74,6 +77,39 @@ private static void testDefaultSettings() throws Exception { testSettingConfiguration("default"); } + private static void testOnlyOnce() throws Exception { + Configuration c = Configuration.getConfiguration("default"); + try (Recording r = new Recording(c)) { + r.enable(ACTIVE_SETTING_EVENT_NAME).withStackTrace(); + r.start(); + r.stop(); + Map settings = new HashMap<>(); + List events = Events.fromRecording(r); + for (RecordedEvent e : events) { + if (e.getEventType().getName().equals(ACTIVE_SETTING_EVENT_NAME)) { + long id = e.getLong("id"); + String name = e.getString("name"); + String value = e.getString("value"); + String s = id + "#" + name + "=" + value; + if (settings.containsKey(s)) { + System.out.println("Event:"); + System.out.println(settings.get(s)); + System.out.println("Duplicated by:"); + System.out.println(e); + String message = "Found duplicated setting '" + s + "'"; + for (EventType type : FlightRecorder.getFlightRecorder().getEventTypes()) { + if (type.getId() == id) { + throw new Exception(message+ " for " + type.getName()); + } + } + throw new Exception(message); + } + settings.put(s, e); + } + } + } + } + private static void testRegistration() throws Exception { // Register new try (Recording recording = new Recording()) { diff --git a/test/jdk/jdk/jfr/event/sampling/TestNative.java b/test/jdk/jdk/jfr/event/sampling/TestNative.java index 2e8753d4ea4..66640c2fbd5 100644 --- a/test/jdk/jdk/jfr/event/sampling/TestNative.java +++ b/test/jdk/jdk/jfr/event/sampling/TestNative.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, 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 @@ -48,9 +48,12 @@ public class TestNative { static volatile boolean alive = true; + // Please resist the temptation to speed up the test by decreasing + // the period. It is explicity set to 1100 ms to provoke the 1000 ms + // threshold in the JVM for os::naked_short_sleep(). public static void main(String[] args) throws Exception { try (RecordingStream rs = new RecordingStream()) { - rs.enable(NATIVE_EVENT).withPeriod(Duration.ofMillis(1)); + rs.enable(NATIVE_EVENT).withPeriod(Duration.ofMillis(1100)); rs.onEvent(NATIVE_EVENT, e -> { alive = false; rs.close(); diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java b/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java index abbd6fb5201..5d469c698c1 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, 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 @@ -74,43 +74,50 @@ public static void main(String[] args) throws Exception { } private static void testDump(String pathToGcRoots, Map settings, boolean expectedChains) throws Exception { - try (Recording r = new Recording()) { - Map p = new HashMap<>(settings); - p.put(EventNames.OldObjectSample + "#" + Enabled.NAME, "true"); - r.setName("dodo"); - r.setSettings(p); - r.setToDisk(true); - r.start(); - clearLeak(); - System.out.println("Recording id: " + r.getId()); - System.out.println("Settings: " + settings.toString()); - System.out.println("Command: JFR.dump " + pathToGcRoots); - System.out.println("Chains expected: " + expectedChains); - buildLeak(); - System.gc(); - System.gc(); - File recording = new File("TestJcmdDumpPathToGCRoots" + r.getId() + ".jfr"); - recording.delete(); - JcmdHelper.jcmd("JFR.dump", "name=dodo", pathToGcRoots, "filename=" + recording.getAbsolutePath()); - r.setSettings(Collections.emptyMap()); - List events = RecordingFile.readAllEvents(recording.toPath()); - if (events.isEmpty()) { - throw new Exception("No events found in recoding"); - } - boolean chains = hasChains(events); - if (expectedChains && !chains) { - System.out.println(events); - throw new Exception("Expected chains but found none"); - } - if (!expectedChains && chains) { - System.out.println(events); - throw new Exception("Didn't expect chains but found some"); + while (true) { + try (Recording r = new Recording()) { + Map p = new HashMap<>(settings); + p.put(EventNames.OldObjectSample + "#" + Enabled.NAME, "true"); + r.setName("dodo"); + r.setSettings(p); + r.setToDisk(true); + r.start(); + clearLeak(); + System.out.println("Recording id: " + r.getId()); + System.out.println("Settings: " + settings.toString()); + System.out.println("Command: JFR.dump " + pathToGcRoots); + System.out.println("Chains expected: " + expectedChains); + buildLeak(); + System.gc(); + System.gc(); + File recording = new File("TestJcmdDumpPathToGCRoots" + r.getId() + ".jfr"); + recording.delete(); + JcmdHelper.jcmd("JFR.dump", "name=dodo", pathToGcRoots, "filename=" + recording.getAbsolutePath()); + r.setSettings(Collections.emptyMap()); + List events = RecordingFile.readAllEvents(recording.toPath()); + if (events.isEmpty()) { + System.out.println("No events found in recording. Retrying."); + continue; + } + boolean chains = hasChains(events); + if (expectedChains && !chains) { + System.out.println(events); + System.out.println("Expected chains but found none. Retrying."); + continue; + } + if (!expectedChains && chains) { + System.out.println(events); + System.out.println("Didn't expect chains but found some. Retrying."); + continue; + } + return; // Success } } } private static void clearLeak() { leak.clear(); + System.gc(); } private static boolean hasChains(List events) throws IOException { diff --git a/test/jdk/jdk/modules/etc/JmodExcludedFiles.java b/test/jdk/jdk/modules/etc/JmodExcludedFiles.java new file mode 100644 index 00000000000..2dc20bbe777 --- /dev/null +++ b/test/jdk/jdk/modules/etc/JmodExcludedFiles.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2024, 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 8159927 + * @modules java.base/jdk.internal.util + * @run main JmodExcludedFiles + * @summary Test that JDK JMOD files do not include native debug symbols + */ + +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +public class JmodExcludedFiles { + public static void main(String[] args) throws Exception { + String javaHome = System.getProperty("java.home"); + Path jmods = Path.of(javaHome, "jmods"); + try (DirectoryStream stream = Files.newDirectoryStream(jmods, "*.jmod")) { + for (Path jmodFile : stream) { + try (ZipFile zip = new ZipFile(jmodFile.toFile())) { + if (zip.stream().map(ZipEntry::getName) + .anyMatch(JmodExcludedFiles::isNativeDebugSymbol)) { + throw new RuntimeException(jmodFile + " is expected not to include native debug symbols"); + } + } + } + } + } + + private static boolean isNativeDebugSymbol(String name) { + int index = name.indexOf("/"); + if (index < 0) { + throw new RuntimeException("unexpected entry name: " + name); + } + String section = name.substring(0, index); + if (section.equals("lib") || section.equals("bin")) { + if (System.getProperty("os.name").toLowerCase().contains("os x")) { + String n = name.substring(index+1); + int i = n.indexOf("/"); + if (i != -1) { + return n.substring(0, i).endsWith(".dSYM"); + } + } + return name.endsWith(".diz") + || name.endsWith(".debuginfo") + || name.endsWith(".map") + || name.endsWith(".pdb"); + } + return false; + } +} diff --git a/test/jdk/jdk/nio/zipfs/TestLocOffsetFromZip64EF.java b/test/jdk/jdk/nio/zipfs/TestLocOffsetFromZip64EF.java index 60fea1b9ac9..7fc789d5606 100644 --- a/test/jdk/jdk/nio/zipfs/TestLocOffsetFromZip64EF.java +++ b/test/jdk/jdk/nio/zipfs/TestLocOffsetFromZip64EF.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, 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 @@ -21,50 +21,72 @@ * questions. */ -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -import java.io.*; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; -import java.nio.file.FileSystem; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; -import java.util.List; +import java.nio.file.attribute.FileTime; +import java.time.Instant; +import java.util.HashSet; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.zip.ZipEntry; import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +import static org.junit.jupiter.api.Assertions.assertEquals; -import static java.lang.String.format; /** * @test * @bug 8255380 8257445 * @summary Test that Zip FS can access the LOC offset from the Zip64 extra field * @modules jdk.zipfs - * @requires (os.family == "linux") | (os.family == "mac") - * @run testng/manual TestLocOffsetFromZip64EF + * @run junit TestLocOffsetFromZip64EF */ public class TestLocOffsetFromZip64EF { - private static final String ZIP_FILE_NAME = "LargeZipTest.zip"; - // File that will be created with a size greater than 0xFFFFFFFF - private static final String LARGE_FILE_NAME = "LargeZipEntry.txt"; - // File that will be created with a size less than 0xFFFFFFFF - private static final String SMALL_FILE_NAME = "SmallZipEntry.txt"; - // The size (4GB) of the large file to be created - private static final long LARGE_FILE_SIZE = 4L * 1024L * 1024L * 1024L; + private static final String ZIP_FILE_NAME = "LocOffsetFromZip64.zip"; + + // Size of the data block of a Zip64 extended information field with long + // fields for 'uncompressed size', 'compressed size' and 'local header offset' + private static short ZIP64_DATA_SIZE = (short) Long.BYTES // Uncompressed size + + Long.BYTES // Compressed size + + Long.BYTES; // Loc offset + + // Size of the extra field header + private static short EXTRA_HEADER_SIZE = Short.BYTES // tag + + Short.BYTES; // data size + + // Size of a Zip64 extended information field including the header + private static final int ZIP64_SIZE = EXTRA_HEADER_SIZE + ZIP64_DATA_SIZE; + + // The Zip64 Magic value for 32-bit fields + private static final int ZIP64_MAGIC_VALUE = 0XFFFFFFFF; + // The 'unknown' tag, see APPNOTE.txt + private static final short UNKNOWN_TAG = (short) 0x9902; + // The 'Zip64 extended information' tag, see APPNOTE.txt + private static final short ZIP64_TAG = (short) 0x1; /** * Create the files used by this test + * * @throws IOException if an error occurs */ - @BeforeClass + @BeforeEach public void setUp() throws IOException { - System.out.println("In setup"); cleanup(); - createFiles(); createZipWithZip64Ext(); } @@ -72,39 +94,22 @@ public void setUp() throws IOException { * Delete files used by this test * @throws IOException if an error occurs */ - @AfterClass + @AfterEach public void cleanup() throws IOException { - System.out.println("In cleanup"); Files.deleteIfExists(Path.of(ZIP_FILE_NAME)); - Files.deleteIfExists(Path.of(LARGE_FILE_NAME)); - Files.deleteIfExists(Path.of(SMALL_FILE_NAME)); - } - - /** - * Create a Zip file that will result in the an Zip64 Extra (EXT) header - * being added to the CEN entry in order to find the LOC offset for - * SMALL_FILE_NAME. - */ - public static void createZipWithZip64Ext() { - System.out.println("Executing zip..."); - List commands = List.of("zip", "-0", ZIP_FILE_NAME, - LARGE_FILE_NAME, SMALL_FILE_NAME); - Result rc = run(new ProcessBuilder(commands)); - rc.assertSuccess(); } /* - * DataProvider used to verify that a Zip file that contains a Zip64 Extra + * MethodSource used to verify that a Zip file that contains a Zip64 Extra * (EXT) header can be traversed */ - @DataProvider(name = "zipInfoTimeMap") - protected Object[][] zipInfoTimeMap() { - return new Object[][]{ - {Map.of()}, - {Map.of("zipinfo-time", "False")}, - {Map.of("zipinfo-time", "true")}, - {Map.of("zipinfo-time", "false")} - }; + static Stream> zipInfoTimeMap() { + return Stream.of( + Map.of(), + Map.of("zipinfo-time", "False"), + Map.of("zipinfo-time", "true"), + Map.of("zipinfo-time", "false") + ); } /** @@ -112,8 +117,11 @@ protected Object[][] zipInfoTimeMap() { * @param env Zip FS properties to use when accessing the Zip file * @throws IOException if an error occurs */ - @Test(dataProvider = "zipInfoTimeMap") + @ParameterizedTest + @MethodSource("zipInfoTimeMap") public void walkZipFSTest(final Map env) throws IOException { + Set entries = new HashSet<>(); + try (FileSystem fs = FileSystems.newFileSystem(Paths.get(ZIP_FILE_NAME), env)) { for (Path root : fs.getRootDirectories()) { @@ -121,6 +129,7 @@ public void walkZipFSTest(final Map env) throws IOException { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + entries.add(file.getFileName().toString()); System.out.println(Files.readAttributes(file, BasicFileAttributes.class).toString()); return FileVisitResult.CONTINUE; @@ -128,6 +137,8 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes }); } } + // Sanity check that ZIP file had the expected entries + assertEquals(Set.of("entry", "entry2", "entry3"), entries); } /** @@ -139,92 +150,129 @@ public void walkZipFileTest() throws IOException { try (ZipFile zip = new ZipFile(ZIP_FILE_NAME)) { zip.stream().forEach(z -> System.out.printf("%s, %s, %s%n", z.getName(), z.getMethod(), z.getLastModifiedTime())); - } - } - /** - * Create the files that will be added to the ZIP file - * @throws IOException if there is a problem creating the files - */ - private static void createFiles() throws IOException { - try (RandomAccessFile file = new RandomAccessFile(LARGE_FILE_NAME, "rw") - ) { - System.out.printf("Creating %s%n", LARGE_FILE_NAME); - file.setLength(LARGE_FILE_SIZE); - System.out.printf("Creating %s%n", SMALL_FILE_NAME); - Files.writeString(Path.of(SMALL_FILE_NAME), "Hello"); + // Sanity check that ZIP file had the expected entries + assertEquals(zip.stream().map(ZipEntry::getName).collect(Collectors.toSet()), + Set.of("entry", "entry2", "entry3")); } } /** - * Utility method to execute a ProcessBuilder command - * @param pb ProcessBuilder to execute - * @return The Result(s) from the ProcessBuilder execution + * This produces a ZIP with similar features as the one created by 'Info-ZIP' which + * caused 'Extended timestamp' parsing to fail before JDK-8255380. + * + * The issue was sensitive to the ordering of 'Info-ZIP extended timestamp' fields and + * 'Zip64 extended information' fields. ZipOutputStream and 'Info-ZIP' order these differently. + * + * ZipFileSystem tried to read the Local file header while parsing the extended timestamp, + * but if the Zip64 extra field was not read yet, ZipFileSystem would incorrecly try to read + * the Local File header from offset 0xFFFFFFFF. + * + * This method creates a ZIP file which includes a CEN with the following features: + * + * - Its extra field has a 'Info-ZIP extended timestamp' field followed by a + * 'Zip64 extended information' field. + * - The sizes and offset fields values of the CEN are set to 0xFFFFFFFF (Zip64 magic values) + * */ - private static Result run(ProcessBuilder pb) { - Process p; - System.out.printf("Running: %s%n", pb.command()); - try { - p = pb.start(); - } catch (IOException e) { - throw new RuntimeException( - format("Couldn't start process '%s'", pb.command()), e); - } + public void createZipWithZip64Ext() throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try (ZipOutputStream zo = new ZipOutputStream(out)) { - String output; - try { - output = toString(p.getInputStream(), p.getErrorStream()); - } catch (IOException e) { - throw new RuntimeException( - format("Couldn't read process output '%s'", pb.command()), e); - } + ZipEntry e = new ZipEntry("entry"); + // Add an entry, make it STORED and empty to simplify parsing + e.setMethod(ZipEntry.STORED); + e.setSize(0); + e.setCrc(0); + zo.putNextEntry(e); + + // Add an additional entry as a sanity check that we can navigate past the first + ZipEntry e2 = new ZipEntry("entry2"); + e2.setMethod(ZipEntry.STORED); + e2.setSize(0); + e2.setCrc(0); + zo.putNextEntry(e2); + + // For good measure, add a third, DEFLATED entry with some content + ZipEntry e3 = new ZipEntry("entry3"); + e3.setMethod(ZipEntry.DEFLATED); + zo.putNextEntry(e3); + zo.write("Hello".getBytes(StandardCharsets.UTF_8)); - try { - p.waitFor(); - } catch (InterruptedException e) { - throw new RuntimeException( - format("Process hasn't finished '%s'", pb.command()), e); + zo.closeEntry(); // At this point, all LOC headers are written. + + // We want the first CEN entry to have two extra fields: + // 1: A 'Info-Zip extended timestamp' extra field, generated by ZipOutputStream + // when the following date fields are set: + e.setLastModifiedTime(FileTime.from(Instant.now())); + e.setLastAccessTime(FileTime.from(Instant.now())); + + // 2: An opaque extra field, right-sized for a Zip64 extended field, + // to be updated below + byte[] zip64 = makeOpaqueExtraField(); + e.setExtra(zip64); + + zo.finish(); // Write out CEN and END records } - return new Result(p.exitValue(), output); + + byte[] zip = out.toByteArray(); + + // ZIP now has the right structure, but we need to update the CEN to Zip64 format + updateToZip64(zip); + // Write the ZIP to disk + Files.write(Path.of(ZIP_FILE_NAME), zip); } /** - * Utility Method for combining the output from a ProcessBuilder invocation - * @param in1 ProccessBuilder.getInputStream - * @param in2 ProcessBuilder.getErrorStream - * @return The ProcessBuilder output - * @throws IOException if an error occurs + * Returns an opaque extra field with the tag 'unknown', which makes ZipEntry.setExtra ignore it. + * The returned field has the expected field and data size of a Zip64 extended information field + * including the fields 'uncompressed size' (8 bytes), 'compressed size' (8 bytes) and + * 'local header offset' (8 bytes). */ - static String toString(InputStream in1, InputStream in2) throws IOException { - try (ByteArrayOutputStream dst = new ByteArrayOutputStream(); - InputStream concatenated = new SequenceInputStream(in1, in2)) { - concatenated.transferTo(dst); - return new String(dst.toByteArray(), StandardCharsets.UTF_8); - } + private static byte[] makeOpaqueExtraField() { + byte[] zip64 = new byte[ZIP64_SIZE]; + ByteBuffer buffer = ByteBuffer.wrap(zip64).order(ByteOrder.LITTLE_ENDIAN); + // Using the 'unknown' tag makes ZipEntry.setExtra ignore it + buffer.putShort(UNKNOWN_TAG); + // Data size + buffer.putShort(ZIP64_DATA_SIZE); + return zip64; } /** - * Utility class used to hold the results from a ProcessBuilder execution + * Update the CEN record to Zip64 format */ - static class Result { - final int ec; - final String output; + private static void updateToZip64(byte[] bytes) throws IOException { - private Result(int ec, String output) { - this.ec = ec; - this.output = output; - } - Result assertSuccess() { - assertTrue(ec == 0, "Expected ec 0, got: ", ec, " , output [", output, "]"); - return this; - } + ByteBuffer buffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN); + + // Look up CEN offset from the End of central directory header + int cenOff = getCenOffet(buffer); + + // Read name, extra field and comment lengths from CEN + short nlen = buffer.getShort(cenOff + ZipFile.CENNAM); + short elen = buffer.getShort(cenOff + ZipFile.CENEXT); + + // Update CEN sizes and loc offset to 0xFFFFFFFF, meaning + // actual values should be read from the Zip64 field + buffer.putInt(cenOff + ZipFile.CENLEN, ZIP64_MAGIC_VALUE); + buffer.putInt(cenOff + ZipFile.CENSIZ, ZIP64_MAGIC_VALUE); + buffer.putInt(cenOff + ZipFile.CENOFF, ZIP64_MAGIC_VALUE); + + // Offset of the extra fields + int extraOff = cenOff + ZipFile.CENHDR + nlen; + + // Position at the start of the Zip64 extra field + int zip64ExtraOff = extraOff + elen - ZIP64_SIZE; + + // Update tag / Header ID to be the actual Zip64 tag instead of the 'unknown' + buffer.putShort(zip64ExtraOff, ZIP64_TAG); } - static void assertTrue(boolean cond, Object ... failedArgs) { - if (cond) - return; - StringBuilder sb = new StringBuilder(); - for (Object o : failedArgs) - sb.append(o); - Assert.fail(sb.toString()); + + /** + * Look up the CEN offset field from the End of central directory header + */ + private static int getCenOffet(ByteBuffer buffer) { + return buffer.getInt(buffer.capacity() - ZipFile.ENDHDR + ZipFile.ENDOFF); } } diff --git a/test/jdk/jdk/security/logging/RecursiveEventHelper.java b/test/jdk/jdk/security/logging/RecursiveEventHelper.java new file mode 100644 index 00000000000..936d01f8115 --- /dev/null +++ b/test/jdk/jdk/security/logging/RecursiveEventHelper.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2024, 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.util.logging.*; + +import jdk.internal.event.EventHelper; + +/* + * @test + * @bug 8329013 + * @summary StackOverflowError when starting Apache Tomcat with signed jar + * @modules java.base/jdk.internal.event:+open + * @run main/othervm -Xmx32m -Djava.util.logging.manager=RecursiveEventHelper RecursiveEventHelper + */ +public class RecursiveEventHelper extends LogManager { + // an extra check to ensure the custom manager is in use + static volatile boolean customMethodCalled; + + public static void main(String[] args) throws Exception { + String classname = System.getProperty("java.util.logging.manager"); + if (!classname.equals("RecursiveEventHelper")) { + throw new RuntimeException("java.util.logging.manager not set"); + } + + // this call will trigger initialization of logging framework + // which will call into our custom LogManager and use the + // custom getProperty method below. EventHelper.isLoggingSecurity() + // is also on the code path of original report and triggers + // similar recursion. + System.getLogger("testLogger"); + if (!customMethodCalled) { + throw new RuntimeException("Method not called"); + } + } + + @Override + public String getProperty(String p) { + // this call mimics issue reported in initial bug report where + // opening of a signed jar during System logger initialization triggered + // a recursive call (via EventHelper.isLoggingSecurity) back into + // logger API + EventHelper.isLoggingSecurity(); + customMethodCalled = true; + return super.getProperty(p); + } +} diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java index b5bb698e458..0b832366286 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, 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 @@ -30,6 +30,9 @@ * @run main/othervm -Djava.security.debug=certpath,ocsp * CAInterop actalisauthenticationrootca OCSP * @run main/othervm/timeout=180 -Djava.security.debug=certpath,ocsp + * -Dcom.sun.security.ocsp.useget=false + * CAInterop actalisauthenticationrootca OCSP + * @run main/othervm/timeout=180 -Djava.security.debug=certpath,ocsp * CAInterop actalisauthenticationrootca CRL */ @@ -40,6 +43,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca1 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca1 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca1 CRL */ @@ -50,6 +54,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca2 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca2 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca2 CRL */ @@ -60,6 +65,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca3 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca3 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca3 CRL */ @@ -70,6 +76,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca4 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca4 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca4 CRL */ @@ -80,6 +87,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass2ca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop buypassclass2ca OCSP * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass2ca CRL */ @@ -90,6 +98,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass3ca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop buypassclass3ca OCSP * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass3ca CRL */ @@ -100,6 +109,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop comodorsaca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop comodorsaca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop comodorsaca CRL */ @@ -110,6 +120,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop comodoeccca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop comodoeccca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop comodoeccca CRL */ @@ -120,6 +131,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop usertrustrsaca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop usertrustrsaca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop usertrustrsaca CRL */ @@ -130,6 +142,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop usertrusteccca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop usertrusteccca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop usertrusteccca CRL */ @@ -140,6 +153,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop letsencryptisrgx1 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop letsencryptisrgx1 DEFAULT */ /* @@ -149,6 +163,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop letsencryptisrgx2 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop letsencryptisrgx2 DEFAULT */ /* @@ -158,6 +173,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop globalsignrootcar6 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop globalsignrootcar6 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop globalsignrootcar6 CRL */ @@ -168,6 +184,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop entrustrootcaec1 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop entrustrootcaec1 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop entrustrootcaec1 CRL */ @@ -178,6 +195,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop entrustrootcag4 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop entrustrootcag4 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop entrustrootcag4 CRL */ @@ -188,6 +206,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop godaddyrootg2ca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop godaddyrootg2ca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop godaddyrootg2ca CRL */ @@ -198,6 +217,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop starfieldrootg2ca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop starfieldrootg2ca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop starfieldrootg2ca CRL */ @@ -207,8 +227,8 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop globalsigneccrootcar4 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop globalsigneccrootcar4 CRL + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop globalsigneccrootcar4 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop globalsigneccrootcar4 DEFAULT */ /* @@ -217,8 +237,8 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar1 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop gtsrootcar1 CRL + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar1 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootcar1 DEFAULT */ /* @@ -227,8 +247,8 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar2 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop gtsrootcar2 CRL + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar2 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootcar2 DEFAULT */ /* @@ -237,8 +257,8 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar3 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop gtsrootecccar3 CRL + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar3 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootecccar3 DEFAULT */ /* @@ -247,8 +267,8 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar4 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop gtsrootecccar4 CRL + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootecccar4 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar4 DEFAULT */ /* @@ -258,6 +278,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop microsoftecc2017 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop microsoftecc2017 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop microsoftecc2017 CRL */ @@ -268,6 +289,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop microsoftrsa2017 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop microsoftrsa2017 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop microsoftrsa2017 CRL */ @@ -278,6 +300,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop quovadisrootca1g3 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop quovadisrootca1g3 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop quovadisrootca1g3 CRL */ @@ -288,6 +311,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop quovadisrootca2g3 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop quovadisrootca2g3 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop quovadisrootca2g3 CRL */ @@ -298,6 +322,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop quovadisrootca3g3 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop quovadisrootca3g3 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop quovadisrootca3g3 CRL */ @@ -308,6 +333,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop digicerttlseccrootg5 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop digicerttlseccrootg5 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop digicerttlseccrootg5 CRL */ @@ -318,6 +344,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop digicerttlsrsarootg5 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop digicerttlsrsarootg5 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop digicerttlsrsarootg5 CRL */ @@ -328,6 +355,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop sslrootrsaca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop sslrootrsaca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop sslrootrsaca CRL */ @@ -338,6 +366,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop sslrootevrsaca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop sslrootevrsaca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop sslrootevrsaca CRL */ @@ -348,6 +377,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop sslrooteccca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop sslrooteccca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop sslrooteccca CRL */ @@ -358,6 +388,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop teliasonerarootcav1 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop teliasonerarootcav1 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop teliasonerarootcav1 CRL */ @@ -368,6 +399,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop twcaglobalrootca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop twcaglobalrootca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop twcaglobalrootca CRL */ @@ -378,6 +410,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop certignarootca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop certignarootca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop certignarootca CRL */ @@ -388,6 +421,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustcommercialca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustcommercialca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustcommercialca CRL */ @@ -398,6 +432,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustnetworkingca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustnetworkingca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustnetworkingca CRL */ @@ -408,6 +443,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustpremiumca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustpremiumca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustpremiumca CRL */ @@ -418,6 +454,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustpremiumeccca OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustpremiumeccca OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustpremiumeccca CRL */ @@ -428,6 +465,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop teliarootcav2 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop teliarootcav2 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop teliarootcav2 CRL */ @@ -438,6 +476,7 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop emsignrootcag1 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop emsignrootcag1 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop emsignrootcag1 CRL */ @@ -448,9 +487,30 @@ * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop emsigneccrootcag3 OCSP + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop emsigneccrootcag3 OCSP * @run main/othervm -Djava.security.debug=certpath CAInterop emsigneccrootcag3 CRL */ +/* + * @test id=certainlyrootr1 + * @bug 8321408 + * @summary Interoperability tests with Certainly Root R1 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop certainlyrootr1 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop certainlyrootr1 DEFAULT + */ + +/* + * @test id=certainlyroote1 + * @bug 8321408 + * @summary Interoperability tests with Certainly Root E1 + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop certainlyroote1 DEFAULT + * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop certainlyroote1 DEFAULT + */ + /** * Collection of certificate validation tests for interoperability with external CAs */ @@ -613,6 +673,13 @@ private CATestURLs getTestURLs(String alias) { new CATestURLs("https://testovg3.emsign.com/RootOVG3.html", "https://testovg3r.emsign.com/RootOVG3MR.html"); + case "certainlyrootr1" -> + new CATestURLs("https://valid.root-r1.certainly.com", + "https://revoked.root-r1.certainly.com"); + case "certainlyroote1" -> + new CATestURLs("https://valid.root-e1.certainly.com", + "https://revoked.root-e1.certainly.com"); + default -> throw new RuntimeException("No test setup found for: " + alias); }; } diff --git a/test/jdk/sun/awt/PaletteTester.java b/test/jdk/sun/awt/PaletteTester.java new file mode 100644 index 00000000000..7fb0d6b26ad --- /dev/null +++ b/test/jdk/sun/awt/PaletteTester.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2001, 2023, 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 4366799 + * @key headful + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary verifies that Windows applications react to palette + * changes in 8-bit mode correctly. + * @run main/manual PaletteTester +*/ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Frame; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.VolatileImage; +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import java.io.File; + +public class PaletteTester { + + static VImageColors demo; + + private static final String INSTRUCTIONS = """ + This test should be run on any Windows platform in 8-bit + (256 color) display mode only. To check for errors, run a browser + application (Firefox or Internet Explorer) at the same time + and switch between this test and the browser (by clicking on the + title bars). + + The three panels in this test should look roughly the same (there + may be some dithering differences if you switch display modes + during the test, but the overall look should be the same. If + completely different colors are being used (either for the orange + background fill, the text, the image, or the rectangles), then the + test has failed. + """; + + private static void init() { + + int width = 300, height = 300; + + demo = new VImageColors(); + Frame f = new Frame("PaletteTester"); + f.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) {} + public void windowDeiconified(WindowEvent e) { demo.start(); } + public void windowIconified(WindowEvent e) { demo.stop(); } + }); + f.add(demo); + f.setSize(new Dimension(width, height)); + f.setLocationRelativeTo(null); + + PassFailJFrame.addTestWindow(f); + PassFailJFrame.positionTestWindow(f, PassFailJFrame.Position.HORIZONTAL); + f.setVisible(true); + + demo.start(); + + }//End init() + + public static void main( String args[] ) throws Exception { + + PassFailJFrame passFailJFrame = new PassFailJFrame.Builder() + .title("PaletteTester Instructions") + .instructions(INSTRUCTIONS) + .testTimeOut(5) + .rows(15) + .columns(40) + .screenCapture() + .build(); + + EventQueue.invokeAndWait(PaletteTester::init); + + + try { + passFailJFrame.awaitAndCheck(); + } finally { + demo.stop(); + } + }//main +} + +//************ Begin classes defined for the test **************** + +class VImageColors extends JPanel implements Runnable { + + VolatileImage vImage; + Image bImage; + private static int width = 300, height = 300; + private Thread thread; + Color fillColor = new Color(240, 188, 136); + Color textColor = new Color(40, 18, 97); + Color rectColor = new Color(0, 150, 0); + File f = new File(System.getProperty("test.src", "."), "duke.gif"); + Image duke = new ImageIcon(f.toString()).getImage(); + + public void initOffscreen() { + vImage = this.createVolatileImage(getWidth()/3, getHeight()); + bImage = this.createImage(getWidth()/3, getHeight()); + } + + public void paint(Graphics g) { + int width = getWidth(); + int height = getHeight(); + + if (vImage == null) { + initOffscreen(); + } + + // Render the left panel via VolatileImage + do { + if ( + vImage.validate(getGraphicsConfiguration()) == + VolatileImage.IMAGE_INCOMPATIBLE) + { + vImage = createVolatileImage(width/3, height); + } + Graphics vg = vImage.createGraphics(); + vg.setColor(fillColor); + vg.fillRect(0, 0, width/3, height); + vg.drawImage(duke, 0, 0, null); + vg.setColor(textColor); + vg.drawString("Vol Image", 5, height-1); + vg.setColor(rectColor); + vg.drawRect(0, 0, width/3-1, height-1); + vg.dispose(); + g.drawImage(vImage, 0, 0, width/3, height, null); + } while (vImage.contentsLost()); + + // Render the middle panel via BufferedImage + Graphics bg = bImage.getGraphics(); + bg.setColor(fillColor); + bg.fillRect(0, 0, width/3, height); + bg.drawImage(duke, 0, 0, null); + bg.setColor(textColor); + bg.drawString("Buff Image", 5, height-1); + bg.setColor(rectColor); + bg.drawRect(0, 0, width/3-1, height-1); + bg.dispose(); + g.drawImage(bImage, width/3, 0, width/3, height, null); + + // Render the right panel directly to the screen + g.setColor(fillColor); + g.fillRect(2*(width/3), 0, width/3, height); + g.drawImage(duke, 2*(width/3), 0, null); + g.setColor(textColor); + g.drawString("Screen", 2*(width/3) + 5, height-1); + g.setColor(rectColor); + g.drawRect(2*(width/3), 0, width/3-1, height-1); + + } + + public void start() { + thread = new Thread(this); + thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); + } + + public synchronized void stop() { + thread = null; + } + + public void run() { + Thread me = Thread.currentThread(); + while (thread == me) { + try { + thread.sleep(100); + } catch (InterruptedException e) { break; } + } + thread = null; + } +} + +//************** End classes defined for the test ******************* diff --git a/test/jdk/sun/awt/duke.gif b/test/jdk/sun/awt/duke.gif new file mode 100644 index 00000000000..ed32e0ff79b Binary files /dev/null and b/test/jdk/sun/awt/duke.gif differ diff --git a/test/jdk/sun/awt/font/DoubleAntialiasTest.java b/test/jdk/sun/awt/font/DoubleAntialiasTest.java new file mode 100644 index 00000000000..e9057922895 --- /dev/null +++ b/test/jdk/sun/awt/font/DoubleAntialiasTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2000, 2023, 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.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Panel; +import java.awt.Robot; + +import static java.awt.RenderingHints.KEY_ANTIALIASING; +import static java.awt.RenderingHints.KEY_TEXT_ANTIALIASING; +import static java.awt.RenderingHints.VALUE_ANTIALIAS_ON; +import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON; + +/* + * @test + * @bug 4357180 + * @key headful + * @summary When both KEY_ANTIALIASING and KEY_TEXT_ANTIALIASING hints + * were turned on, java aborts with EXCEPTION_ACCESS_VIOLATION + * at attempt to draw characters in Hebrew or Arabic. + * This could happen immediately or after several draws, + * depending on th locale and platform. This test draws + * large number of characters that are among this range repeatedly. + */ + +public class DoubleAntialiasTest extends Panel { + private static Frame frame; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + EventQueue.invokeAndWait(() -> { + frame = new Frame(); + frame.setTitle("DoubleAntialiasTest"); + frame.add(new DoubleAntialiasTest()); + frame.pack(); + frame.setSize(500, 500); + frame.setVisible(true); + }); + + robot.waitForIdle(); + robot.delay(2000); + } catch (Exception e) { + throw new RuntimeException("Following exception occurred" + + " when testing Antialiasing Rendering hints: ", e); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + @Override + public void paint(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + int y = 50; + for (int i = 0; i < 2; i++) { + int k = 5; + for (int j = 0x500; j < 0x700; j++) { + g2.setRenderingHint(KEY_TEXT_ANTIALIASING, + VALUE_TEXT_ANTIALIAS_ON); + g2.setRenderingHint(KEY_ANTIALIASING, + VALUE_ANTIALIAS_ON); + g2.drawString(String.valueOf((char) j), (5 + k), y); + k = k + 15; + } + k = 5; + y += 50; + for (int j = 0x700; j > 0x500; j--) { + g2.setRenderingHint(KEY_TEXT_ANTIALIASING, + VALUE_TEXT_ANTIALIAS_ON); + g2.setRenderingHint(KEY_ANTIALIASING, + VALUE_ANTIALIAS_ON); + g2.drawString(String.valueOf((char) j), (5 + k), y); + k = k + 15; + } + y += 50; + } + } +} diff --git a/test/jdk/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java b/test/jdk/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java index 22e055fbe8e..97ed058ff5a 100644 --- a/test/jdk/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java +++ b/test/jdk/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, 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 @@ -23,7 +23,7 @@ /** * @test - * @bug 6476665 7033534 6830714 8052162 8196572 + * @bug 6476665 7033534 6830714 8052162 8196572 8326661 * @summary Verifies color conversion of Component Color Model based images * @run main ColConvCCMTest */ @@ -59,8 +59,8 @@ public class ColConvCCMTest extends ColConvTest { 2.5, // sRGB (isOpenProfile() ? 45.0 : 10.1), // LINEAR_RGB 10.5, // GRAY - (isOpenProfile() ? 215.0 : 45.5), // PYCC - (isOpenProfile() ? 56.0 : 47.5) // CIEXYZ + (isOpenProfile() ? 215.0 : 64.5), // PYCC + (isOpenProfile() ? 56.0 : 55.5) // CIEXYZ }; final static String [] gldImgNames = { diff --git a/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java b/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java index f8035767710..f5f7ea97fa1 100644 --- a/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java +++ b/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java @@ -43,7 +43,7 @@ /* * @test - * @bug 8012229 + * @bug 8012229 8323210 * @summary one more test to check the alpha channel */ public final class ColCvtAlphaDifferentSrcDst { diff --git a/test/jdk/sun/java2d/marlin/ClipShapeTest.java b/test/jdk/sun/java2d/marlin/ClipShapeTest.java index 65de6e750c9..3bdbd416e63 100644 --- a/test/jdk/sun/java2d/marlin/ClipShapeTest.java +++ b/test/jdk/sun/java2d/marlin/ClipShapeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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 @@ -52,20 +52,43 @@ import javax.imageio.ImageWriter; import javax.imageio.stream.ImageOutputStream; -/** - * @test +/* + * @test id=Poly * @bug 8191814 - * @summary Verifies that Marlin rendering generates the same - * images with and without clipping optimization with all possible - * stroke (cap/join) and/or dashes or fill modes (EO rules) - * for paths made of either 9 lines, 4 quads, 2 cubics (random) - * Note: Use the argument -slow to run more intensive tests (too much time) - * + * @summary Runs the test with "-poly" option * @run main/othervm/timeout=300 -Dsun.java2d.renderer=sun.java2d.marlin.DMarlinRenderingEngine ClipShapeTest -poly + */ + +/* + * @test id=PolyDoDash + * @bug 8191814 + * @summary Runs the test with "-poly -doDash" options * @run main/othervm/timeout=300 -Dsun.java2d.renderer=sun.java2d.marlin.DMarlinRenderingEngine ClipShapeTest -poly -doDash + */ + +/* + * @test id=Cubic + * @bug 8191814 + * @summary Runs the test with "-cubic" option * @run main/othervm/timeout=300 -Dsun.java2d.renderer=sun.java2d.marlin.DMarlinRenderingEngine ClipShapeTest -cubic + */ + +/* + * @test id=CubicDoDash + * @bug 8191814 + * @summary Runs the test with "-cubic -doDash" options * @run main/othervm/timeout=300 -Dsun.java2d.renderer=sun.java2d.marlin.DMarlinRenderingEngine ClipShapeTest -cubic -doDash -*/ + */ + +/** + * Verifies that Marlin rendering generates the same images with and without + * clipping optimization with all possible stroke (cap/join) and/or dashes or + * fill modes (EO rules) for paths made of either 9 lines, 4 quads, 2 cubics + * (random). + *

+ * Note: Use the argument {@code -slow} to run more intensive tests (too much + * time). + */ public final class ClipShapeTest { // test options: diff --git a/test/jdk/sun/java2d/marlin/DefaultRenderingEngine.java b/test/jdk/sun/java2d/marlin/DefaultRenderingEngine.java new file mode 100644 index 00000000000..8ba6945d903 --- /dev/null +++ b/test/jdk/sun/java2d/marlin/DefaultRenderingEngine.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020, 2024, 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 sun.java2d.pipe.RenderingEngine; + +/** + * @test + * @bug 8241307 + * @summary Verifies that the Marlin renderer is the default RenderingEngine + * @modules java.desktop/sun.java2d.pipe + */ +public final class DefaultRenderingEngine { + + public static void main(String[] argv) { + + final RenderingEngine engine = RenderingEngine.getInstance(); + + if (!engine.getClass().getSimpleName().contains("Marlin")) { + throw new RuntimeException("Marlin must be the default RenderingEngine"); + } + } +} diff --git a/test/jdk/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java b/test/jdk/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java index 114ddaa3022..7e129c15e23 100644 --- a/test/jdk/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java +++ b/test/jdk/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2023, 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 @@ -323,10 +323,9 @@ public void terminate() { private void executeJava() throws Throwable { String className = JavaProcess.class.getName(); - String classPath = System.getProperty("test.classes"); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + ProcessBuilder pb = ProcessTools.createTestJvm( "-Dtest.timeout.factor=" + System.getProperty("test.timeout.factor", "1.0"), - "-cp", classPath, className, mainArgsIdentifier); + className, mainArgsIdentifier); OutputAnalyzer ob = ProcessTools.executeProcess(pb); System.out.println("Java Process " + getMainArgsIdentifier() + " stderr:" + ob.getStderr()); diff --git a/test/jdk/sun/net/www/B8185898.java b/test/jdk/sun/net/www/B8185898.java index a50c6f93c7e..cfa54e15a52 100644 --- a/test/jdk/sun/net/www/B8185898.java +++ b/test/jdk/sun/net/www/B8185898.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, 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 @@ -23,7 +23,7 @@ /** * @test - * @bug 8185898 + * @bug 8185898 8163921 * @modules java.base/sun.net.www * @library /test/lib * @run main/othervm B8185898 @@ -143,32 +143,32 @@ static void testMessageHeaderMethods() throws IOException { // {{inputString1, expectedToString1, expectedPrint1}, {...}} String[][] strings = { {"HTTP/1.1 200 OK\r\n" - + "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n" + + "Accept: */*\r\n" + "Connection: keep-alive\r\n" + "Host: 127.0.0.1:12345\r\n" + "User-agent: Java/12\r\n\r\nfoooo", "pairs: {null: HTTP/1.1 200 OK}" - + "{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}" + + "{Accept: */*}" + "{Connection: keep-alive}" + "{Host: 127.0.0.1:12345}" + "{User-agent: Java/12}", - "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n" + "Accept: */*\r\n" + "Connection: keep-alive\r\n" + "Host: 127.0.0.1:12345\r\n" + "User-agent: Java/12\r\n\r\n"}, {"HTTP/1.1 200 OK\r\n" - + "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n" + + "Accept: */*\r\n" + "Connection: keep-alive\r\n" + "Host: 127.0.0.1:12345\r\n" + "User-agent: Java/12\r\n" + "X-Header:\r\n\r\n", "pairs: {null: HTTP/1.1 200 OK}" - + "{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}" + + "{Accept: */*}" + "{Connection: keep-alive}" + "{Host: 127.0.0.1:12345}" + "{User-agent: Java/12}" + "{X-Header: }", - "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n" + "Accept: */*\r\n" + "Connection: keep-alive\r\n" + "Host: 127.0.0.1:12345\r\n" + "User-agent: Java/12\r\n" diff --git a/test/jdk/sun/net/www/http/HttpClient/B8209178.java b/test/jdk/sun/net/www/http/HttpClient/B8209178.java index fec17ff84d1..9d1a89aabd5 100644 --- a/test/jdk/sun/net/www/http/HttpClient/B8209178.java +++ b/test/jdk/sun/net/www/http/HttpClient/B8209178.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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 @@ -214,13 +214,14 @@ private synchronized Thread pipe(InputStream is, OutputStream os, char tag) { public void run() { try { try { - int c; - while ((c = is.read()) != -1) { - os.write(c); + int len; + byte[] buf = new byte[16 * 1024]; + while ((len = is.read(buf)) != -1) { + os.write(buf, 0, len); os.flush(); // if DEBUG prints a + or a - for each transferred // character. - if (DEBUG) System.out.print(tag); + if (DEBUG) System.out.print(String.valueOf(tag).repeat(len)); } is.close(); } finally { diff --git a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java index 80e5931b2b2..03f3f4fe6ac 100644 --- a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java +++ b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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 @@ -29,6 +29,7 @@ * 8223499 8225392 8232019 8234245 8233223 8225068 8225069 8243321 8243320 * 8243559 8225072 8258630 8259312 8256421 8225081 8225082 8225083 8245654 * 8305975 8304760 8307134 8295894 8314960 8317373 8317374 8318759 8319187 + * 8321408 * @summary Check root CA entries in cacerts file */ import java.io.ByteArrayInputStream; @@ -47,12 +48,12 @@ public class VerifyCACerts { + File.separator + "security" + File.separator + "cacerts"; // The numbers of certs now. - private static final int COUNT = 106; + private static final int COUNT = 108; // SHA-256 of cacerts, can be generated with // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95 private static final String CHECKSUM - = "61:5F:6D:C5:9C:A3:8A:65:3F:CB:F9:F5:26:04:23:F4:53:A6:8C:B3:8B:2B:0A:F0:66:7D:9E:67:B9:4D:AC:B7"; + = "81:D4:84:F6:92:78:A4:82:25:06:DC:42:25:C9:5D:6C:63:E4:99:CE:BC:ED:66:B3:8C:BA:E6:BA:6B:34:0F:01"; // Hex formatter to upper case with ":" delimiter private static final HexFormat HEX = HexFormat.ofDelimiter(":").withUpperCase(); @@ -273,6 +274,10 @@ public class VerifyCACerts { "86:A1:EC:BA:08:9C:4A:8D:3B:BE:27:34:C6:12:BA:34:1D:81:3E:04:3C:F9:E8:A8:62:CD:5C:57:A3:6B:BE:6B"); put("emsignrootcag2 [jdk]", "1A:A0:C2:70:9E:83:1B:D6:E3:B5:12:9A:00:BA:41:F7:EE:EF:02:08:72:F1:E6:50:4B:F0:F6:C3:F2:4F:3A:F3"); + put("certainlyrootr1 [jdk]", + "77:B8:2C:D8:64:4C:43:05:F7:AC:C5:CB:15:6B:45:67:50:04:03:3D:51:C6:0C:62:02:A8:E0:C3:34:67:D3:A0"); + put("certainlyroote1 [jdk]", + "B4:58:5F:22:E4:AC:75:6A:4E:86:12:A1:36:1C:5D:9D:03:1A:93:FD:84:FE:BB:77:8F:A3:06:8B:0F:C4:2D:C2"); } }; diff --git a/test/jdk/sun/security/pkcs11/Cipher/TestRawRSACipher.java b/test/jdk/sun/security/pkcs11/Cipher/TestRawRSACipher.java index 2991dcfa5d8..9eceea3a394 100644 --- a/test/jdk/sun/security/pkcs11/Cipher/TestRawRSACipher.java +++ b/test/jdk/sun/security/pkcs11/Cipher/TestRawRSACipher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 6994008 + * @bug 6994008 8289401 * @summary basic test for RSA/ECB/NoPadding cipher * @author Valerie Peng * @library /test/lib .. @@ -38,6 +38,7 @@ import java.security.KeyPairGenerator; import java.security.Provider; import java.util.Arrays; +import java.util.HexFormat; import java.util.Random; import javax.crypto.Cipher; @@ -71,6 +72,9 @@ public void main(Provider p) throws Exception { cipherText = c1.doFinal(plainText); recoveredText = c2.doFinal(cipherText); if (!Arrays.equals(plainText, recoveredText)) { + System.out.println("*** E/D Test:"); + System.out.println("\tplainText = " + HexFormat.of().formatHex(plainText)); + System.out.println("\trecoveredText = " + HexFormat.of().formatHex(recoveredText)); throw new RuntimeException("E/D Test against SunJCE Failed!"); } @@ -79,6 +83,9 @@ public void main(Provider p) throws Exception { cipherText = c2.doFinal(plainText); recoveredText = c1.doFinal(cipherText); if (!Arrays.equals(plainText, recoveredText)) { + System.out.println("*** D/E Test:"); + System.out.println("\tplainText = " + HexFormat.of().formatHex(plainText)); + System.out.println("\trecoveredText = " + HexFormat.of().formatHex(recoveredText)); throw new RuntimeException("D/E Test against SunJCE Failed!"); } diff --git a/test/jdk/sun/security/pkcs11/KeyStore/ClientAuth.java b/test/jdk/sun/security/pkcs11/KeyStore/ClientAuth.java index 259f9ed33e4..1af1258d173 100644 --- a/test/jdk/sun/security/pkcs11/KeyStore/ClientAuth.java +++ b/test/jdk/sun/security/pkcs11/KeyStore/ClientAuth.java @@ -389,6 +389,10 @@ void startClient (boolean newThread) { * Our client thread just died. */ System.err.println("Client died..."); + // if the exception is thrown before connecting to the + // server, the test will time out and the exception will + // be lost/hidden. + e.printStackTrace(System.err); clientException = e; } }); diff --git a/test/jdk/sun/security/pkcs11/PKCS11Test.java b/test/jdk/sun/security/pkcs11/PKCS11Test.java index 9c61ffe47cf..becbc9695a1 100644 --- a/test/jdk/sun/security/pkcs11/PKCS11Test.java +++ b/test/jdk/sun/security/pkcs11/PKCS11Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, 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 @@ -45,7 +45,6 @@ import java.security.spec.ECParameterSpec; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -54,7 +53,11 @@ import java.util.ServiceConfigurationError; import java.util.ServiceLoader; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import jdk.test.lib.Platform; import jdk.test.lib.artifacts.Artifact; import jdk.test.lib.artifacts.ArtifactResolver; import jdk.test.lib.artifacts.ArtifactResolverException; @@ -74,6 +77,11 @@ public abstract class PKCS11Test { private static final String PKCS11_REL_PATH = "sun/security/pkcs11"; private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray(); + // Version of the NSS artifact. This coincides with the version of + // the NSS version + private static final String NSS_BUNDLE_VERSION = "3.91"; + private static final String NSSLIB = "jpg.tests.jdk.nsslib"; + static double nss_version = -1; static ECCState nss_ecc_status = ECCState.Basic; @@ -248,30 +256,19 @@ private static Path getNSSLibPath() throws Exception { static Path getNSSLibPath(String library) throws Exception { String osid = getOsId(); - String[] nssLibDirs = getNssLibPaths(osid); - if (nssLibDirs == null) { - System.out.println("Warning: unsupported OS: " + osid + String nssLibDir = fetchNssLib(osid); + if (nssLibDir == null) { + throw new SkippedException("Warning: unsupported OS: " + osid + ", please initialize NSS library location, skipping test"); - return null; - } - if (nssLibDirs.length == 0) { - System.out.println("Warning: NSS not supported on this platform, skipping test"); - return null; } - Path nssLibPath = null; - for (String dir : nssLibDirs) { - Path libPath = Paths.get(dir).resolve(System.mapLibraryName(library)); - if (Files.exists(libPath)) { - nssLibPath = libPath; - break; - } - } - if (nssLibPath == null) { - System.out.println("Warning: can't find NSS library on this machine, skipping test"); - return null; + String libraryName = System.mapLibraryName(library); + Path libPath = Paths.get(nssLibDir).resolve(libraryName); + if (!Files.exists(libPath)) { + throw new SkippedException("NSS library \"" + libraryName + "\" was not found in " + nssLibDir); } - return nssLibPath; + + return libPath; } private static String getOsId() { @@ -595,71 +592,6 @@ private static ECParameterSpec getECParameterSpec(Provider p, String name) return parameters.getParameterSpec(ECParameterSpec.class); } - // Location of the NSS libraries on each supported platform - private static Map getOsMap() { - if (osMap != null) { - return osMap; - } - - osMap = new HashMap<>(); - osMap.put("Linux-i386-32", new String[]{ - "/usr/lib/i386-linux-gnu/", - "/usr/lib32/", - "/usr/lib/"}); - osMap.put("Linux-amd64-64", new String[]{ - "/usr/lib/x86_64-linux-gnu/", - "/usr/lib/x86_64-linux-gnu/nss/", - "/usr/lib64/"}); - osMap.put("Linux-ppc64-64", new String[]{"/usr/lib64/"}); - osMap.put("Linux-ppc64le-64", new String[]{"/usr/lib64/"}); - osMap.put("Linux-s390x-64", new String[]{"/usr/lib64/"}); - osMap.put("Windows-x86-32", new String[]{}); - osMap.put("Windows-amd64-64", new String[]{}); - osMap.put("MacOSX-x86_64-64", new String[]{}); - osMap.put("Linux-arm-32", new String[]{ - "/usr/lib/arm-linux-gnueabi/nss/", - "/usr/lib/arm-linux-gnueabihf/nss/"}); - osMap.put("Linux-aarch64-64", new String[] { - "/usr/lib/aarch64-linux-gnu/", - "/usr/lib/aarch64-linux-gnu/nss/", - "/usr/lib64/" }); - return osMap; - } - - private static String[] getNssLibPaths(String osId) { - String[] preferablePaths = getPreferableNssLibPaths(osId); - if (preferablePaths.length != 0) { - return preferablePaths; - } else { - return getOsMap().get(osId); - } - } - - private static String[] getPreferableNssLibPaths(String osId) { - List nssLibPaths = new ArrayList<>(); - - String customNssLibPaths = System.getProperty("test.nss.lib.paths"); - if (customNssLibPaths == null) { - // If custom local NSS lib path is not provided, - // try to download NSS libs from artifactory - String path = fetchNssLib(osId); - if (path != null) { - nssLibPaths.add(path); - } - } else { - String[] paths = customNssLibPaths.split(","); - for (String path : paths) { - if (!path.endsWith(File.separator)) { - nssLibPaths.add(path + File.separator); - } else { - nssLibPaths.add(path); - } - } - } - - return nssLibPaths.toArray(new String[0]); - } - public static String toString(byte[] b) { if (b == null) { return "(null)"; @@ -744,18 +676,28 @@ static byte[] generateData(int length) { private static String fetchNssLib(String osId) { switch (osId) { - case "Windows-x86-32": - return fetchNssLib(WINDOWS_X86.class); - case "Windows-amd64-64": return fetchNssLib(WINDOWS_X64.class); case "MacOSX-x86_64-64": return fetchNssLib(MACOSX_X64.class); + case "MacOSX-aarch64-64": + return fetchNssLib(MACOSX_AARCH64.class); + case "Linux-amd64-64": - return fetchNssLib(LINUX_X64.class); + if (Platform.isOracleLinux7()) { + throw new SkippedException("Skipping Oracle Linux prior to v8"); + } else { + return fetchNssLib(LINUX_X64.class); + } + case "Linux-aarch64-64": + if (Platform.isOracleLinux7()) { + throw new SkippedException("Skipping Oracle Linux prior to v8"); + } else { + return fetchNssLib(LINUX_AARCH64.class); + } default: return null; } @@ -765,8 +707,8 @@ private static String fetchNssLib(Class clazz) { String path = null; try { path = ArtifactResolver.resolve(clazz).entrySet().stream() - .findAny().get().getValue() + File.separator + "nsslib" - + File.separator; + .findAny().get().getValue() + File.separator + "nss" + + File.separator + "lib" + File.separator; } catch (ArtifactResolverException e) { Throwable cause = e.getCause(); if (cause == null) { @@ -868,34 +810,43 @@ protected void copyNssCertKeyToClassesDir(Path dbPath) throws IOException { public static enum ECCState {None, Basic, Extended} @Artifact( - organization = "jpg.tests.jdk.nsslib", + organization = NSSLIB, name = "nsslib-windows_x64", - revision = "3.46-VS2017", + revision = NSS_BUNDLE_VERSION, extension = "zip") private static class WINDOWS_X64 { } @Artifact( - organization = "jpg.tests.jdk.nsslib", - name = "nsslib-windows_x86", - revision = "3.46-VS2017", + organization = NSSLIB, + name = "nsslib-macosx_x64", + revision = NSS_BUNDLE_VERSION, extension = "zip") - private static class WINDOWS_X86 { + private static class MACOSX_X64 { } @Artifact( - organization = "jpg.tests.jdk.nsslib", - name = "nsslib-macosx_x64", - revision = "3.46", + organization = NSSLIB, + name = "nsslib-macosx_aarch64", + revision = NSS_BUNDLE_VERSION, extension = "zip") - private static class MACOSX_X64 { + private static class MACOSX_AARCH64 { } @Artifact( - organization = "jpg.tests.jdk.nsslib", + organization = NSSLIB, name = "nsslib-linux_x64", - revision = "3.46", + revision = NSS_BUNDLE_VERSION, extension = "zip") private static class LINUX_X64 { } + + @Artifact( + organization = NSSLIB, + name = "nsslib-linux_aarch64", + revision = NSS_BUNDLE_VERSION, + extension = "zip" + ) + private static class LINUX_AARCH64{ + } } diff --git a/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.java b/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.java index 5d6fb68aceb..ddce6e8733d 100644 --- a/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.java +++ b/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, 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 @@ -21,6 +21,7 @@ * questions. */ + import sun.security.pkcs11.SunPKCS11; import javax.security.auth.Subject; @@ -32,12 +33,10 @@ import java.io.IOException; import java.lang.ref.WeakReference; import java.security.*; -import java.util.Iterator; import java.util.PropertyPermission; -import java.util.ServiceConfigurationError; -import java.util.ServiceLoader; import jdk.test.lib.util.ForceGC; +import jtreg.SkippedException; public class MultipleLogins { private static final String KS_TYPE = "PKCS11"; @@ -46,7 +45,13 @@ public class MultipleLogins { static final Policy DEFAULT_POLICY = Policy.getPolicy(); public static void main(String[] args) throws Exception { - String nssConfig = PKCS11Test.getNssConfig(); + String nssConfig = null; + try { + nssConfig = PKCS11Test.getNssConfig(); + } catch (SkippedException exc) { + System.out.println("Skipping test: " + exc.getMessage()); + } + if (nssConfig == null) { // No test framework support yet. Ignore System.out.println("No NSS config found. Skipping."); diff --git a/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.sh b/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.sh index 4e8da9b9003..30cacd4f909 100644 --- a/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.sh +++ b/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.sh @@ -26,6 +26,7 @@ # @summary # @library /test/lib/ # @build jdk.test.lib.util.ForceGC +# jdk.test.lib.Platform # @run shell MultipleLogins.sh # set a few environment variables so that the shell-script can run stand-alone diff --git a/test/jdk/sun/security/pkcs11/README b/test/jdk/sun/security/pkcs11/README index 31efd034501..9b4c39dd41c 100644 --- a/test/jdk/sun/security/pkcs11/README +++ b/test/jdk/sun/security/pkcs11/README @@ -4,14 +4,15 @@ perform as a result of bugs or features in NSS or other pkcs11 libraries. - How to get NSS libraries? The libraries come from the following sources. -1. Specified by system property test.nss.lib.paths -System property test.nss.lib.paths can specify a set of absolute paths to -the local NSS library directories. The paths are separated by comma. +1. Specified by system property jdk.test.lib.artifacts. +The system property, jdk.test.lib.artifacts., can specify an absolute path +to the local NSS library directory. The component should be replaced with +the name element of the appropriate @Artifact class. +(See `test/jdk/sun/security/pkcs11/PKCS11Test.java`) 2. Pre-built NSS libraries from artifactory server -If the value of system property test.nss.lib.paths is not set, the tests will try -to download pre-built NSS libraries from artifactory server. Currently, the -tests only looks for libraries for Windows and MacOSX platforms on artifactory. +If the value of system property jdk.test.lib.artifacts. is not set, the +tests will try to download pre-built NSS libraries from artifactory server. Please note that JIB jar MUST be present in classpath when downloading the libraries. diff --git a/test/jdk/sun/security/ssl/SSLContextImpl/SSLContextDefault.java b/test/jdk/sun/security/ssl/SSLContextImpl/SSLContextDefault.java index b0327d69a66..7a790e72a1e 100644 --- a/test/jdk/sun/security/ssl/SSLContextImpl/SSLContextDefault.java +++ b/test/jdk/sun/security/ssl/SSLContextImpl/SSLContextDefault.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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 @@ -28,8 +28,9 @@ /* * @test - * @bug 8202343 - * @summary Check that SSLv3, TLSv1 and TLSv1.1 are disabled by default + * @bug 8202343 8256660 + * @summary Check that SSLv3, TLSv1, TLSv1.1, and DTLSv1.0 are disabled + * by default * @run main/othervm SSLContextDefault */ @@ -38,26 +39,43 @@ public class SSLContextDefault { - private final static String[] protocols = { + private static final String[] tlsProtocols = { "", "SSL", "TLS", "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3" }; - private final static List disabledProtocols = List.of( + private static final String[] dtlsProtocols = { + "DTLS", "DTLSv1.0", "DTLSv1.2" + }; + + private static final List disabledTlsProtocols = List.of( "SSLv3", "TLSv1", "TLSv1.1" ); + private static final List disabledDtlsProtocols = List.of( + "DTLSv1.0" + ); + public static void main(String[] args) throws Exception { - for (String protocol : protocols) { - System.out.println("//"); - System.out.println("// " + "Testing for SSLContext of " + - (protocol.isEmpty() ? "" : protocol)); - System.out.println("//"); - checkForProtocols(protocol); - System.out.println(); + for (String tlsProtocol : tlsProtocols) { + testProtocol(tlsProtocol, disabledTlsProtocols); + } + for (String dtlsProtocol : dtlsProtocols) { + testProtocol(dtlsProtocol, disabledDtlsProtocols); } } - public static void checkForProtocols(String protocol) throws Exception { + private static void testProtocol(String protocol, + List disabledProtocols) throws Exception { + System.out.println("//"); + System.out.println("// " + "Testing for SSLContext of " + + (protocol.isEmpty() ? "" : protocol)); + System.out.println("//"); + checkForProtocols(protocol, disabledProtocols); + System.out.println(); + } + + private static void checkForProtocols(String protocol, + List disabledProtocols) throws Exception { SSLContext context; if (protocol.isEmpty()) { context = SSLContext.getDefault(); @@ -68,32 +86,35 @@ public static void checkForProtocols(String protocol) throws Exception { // check for the presence of supported protocols of SSLContext SSLParameters parameters = context.getSupportedSSLParameters(); - checkProtocols(parameters.getProtocols(), + checkProtocols(parameters.getProtocols(), disabledProtocols, "Supported protocols in SSLContext", false); - // check for the presence of default protocols of SSLContext parameters = context.getDefaultSSLParameters(); - checkProtocols(parameters.getProtocols(), + checkProtocols(parameters.getProtocols(), disabledProtocols, "Enabled protocols in SSLContext", true); // check for the presence of supported protocols of SSLEngine SSLEngine engine = context.createSSLEngine(); - checkProtocols(engine.getSupportedProtocols(), + checkProtocols(engine.getSupportedProtocols(), disabledProtocols, "Supported protocols in SSLEngine", false); // Check for the presence of default protocols of SSLEngine - checkProtocols(engine.getEnabledProtocols(), + checkProtocols(engine.getEnabledProtocols(), disabledProtocols, "Enabled protocols in SSLEngine", true); + if (protocol.startsWith("DTLS")) { + return; + } + SSLSocketFactory factory = context.getSocketFactory(); try (SSLSocket socket = (SSLSocket)factory.createSocket()) { // check for the presence of supported protocols of SSLSocket - checkProtocols(socket.getSupportedProtocols(), + checkProtocols(socket.getSupportedProtocols(), disabledProtocols, "Supported cipher suites in SSLSocket", false); // Check for the presence of default protocols of SSLSocket - checkProtocols(socket.getEnabledProtocols(), + checkProtocols(socket.getEnabledProtocols(), disabledProtocols, "Enabled protocols in SSLSocket", true); } @@ -102,16 +123,19 @@ public static void checkForProtocols(String protocol) throws Exception { (SSLServerSocket)serverFactory.createServerSocket()) { // check for the presence of supported protocols of SSLServerSocket checkProtocols(serverSocket.getSupportedProtocols(), - "Supported cipher suites in SSLServerSocket", false); + disabledProtocols, "Supported cipher suites in SSLServerSocket", + false); // Check for the presence of default protocols of SSLServerSocket checkProtocols(serverSocket.getEnabledProtocols(), - "Enabled protocols in SSLServerSocket", true); + disabledProtocols, "Enabled protocols in SSLServerSocket", + true); } } private static void checkProtocols(String[] protocols, - String title, boolean disabled) throws Exception { + List disabledProtocols, String title, boolean disabled) + throws Exception { showProtocols(protocols, title); if (disabled) { diff --git a/test/jdk/sun/security/tools/keytool/NssTest.java b/test/jdk/sun/security/tools/keytool/NssTest.java index 968e19df28d..db5d1240153 100644 --- a/test/jdk/sun/security/tools/keytool/NssTest.java +++ b/test/jdk/sun/security/tools/keytool/NssTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -58,8 +58,9 @@ private static void copyFiles() throws IOException { Path dbPath = srcPath.getParent().getParent() .resolve("pkcs11").resolve("nss").resolve("db"); - Files.copy(dbPath.resolve("cert8.db"), Paths.get("cert8.db")); - Files.copy(dbPath.resolve("key3.db"), Paths.get("key3.db")); - Files.copy(dbPath.resolve("secmod.db"), Paths.get("secmod.db")); + Path destDir = Path.of( "tmpdb"); + Files.createDirectory(destDir); + Files.copy(dbPath.resolve("cert9.db"), destDir.resolve("cert9.db")); + Files.copy(dbPath.resolve("key4.db"), destDir.resolve("key4.db")); } } diff --git a/test/jdk/sun/security/tools/keytool/p11-nss.txt b/test/jdk/sun/security/tools/keytool/p11-nss.txt index dd200a326c0..9c8ac0a43ab 100644 --- a/test/jdk/sun/security/tools/keytool/p11-nss.txt +++ b/test/jdk/sun/security/tools/keytool/p11-nss.txt @@ -6,7 +6,7 @@ slot = 2 library = ${nss.lib} -nssArgs = "configdir='.' certPrefix='' keyPrefix='' secmod='secmod.db'" +nssArgs = "configdir='sql:./tmpdb' certPrefix='' keyPrefix='' secmod='secmod.db'" #forceLogin = true diff --git a/test/jdk/tools/jimage/VerifyJimage.java b/test/jdk/tools/jimage/VerifyJimage.java index 963ff57d0d6..59d0a5cecf4 100644 --- a/test/jdk/tools/jimage/VerifyJimage.java +++ b/test/jdk/tools/jimage/VerifyJimage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, 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 @@ -195,18 +195,13 @@ private String toClassName(String entry) { .replaceAll("\\.class$", "").replace('/', '.'); } - private static Set EXCLUDED_MODULES = - Set.of("javafx.deploy", "jdk.deploy", "jdk.plugin", "jdk.javaws", - // All JVMCI packages other than jdk.vm.ci.services are dynamically - // exported to jdk.internal.vm.compiler - "jdk.internal.vm.compiler" - ); + // All JVMCI packages other than jdk.vm.ci.services are dynamically + // exported to jdk.internal.vm.compiler + private static Set EXCLUDED_MODULES = Set.of("jdk.internal.vm.compiler"); private boolean accept(String entry) { int index = entry.indexOf('/', 1); String mn = index > 1 ? entry.substring(1, index) : ""; - // filter deployment modules - if (mn.isEmpty() || EXCLUDED_MODULES.contains(mn)) { return false; } diff --git a/test/jdk/tools/jlink/plugins/CDSPluginTest.java b/test/jdk/tools/jlink/plugins/CDSPluginTest.java new file mode 100644 index 00000000000..f85769645ce --- /dev/null +++ b/test/jdk/tools/jlink/plugins/CDSPluginTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.JDKToolFinder; +import jdk.test.lib.Platform; +import jdk.test.lib.process.*; + +import tests.Helper; + +import jtreg.SkippedException; + +/* @test + * @bug 8264322 + * @summary Test the --generate-cds-archive plugin + * @requires vm.cds + * @library ../../lib + * @library /test/lib + * @modules java.base/jdk.internal.jimage + * jdk.jdeps/com.sun.tools.classfile + * jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jmod + * jdk.jlink/jdk.tools.jimage + * jdk.compiler + * @build tests.* + * @run main CDSPluginTest + */ + +public class CDSPluginTest { + + public static void main(String[] args) throws Throwable { + + if (!Platform.isDefaultCDSArchiveSupported()) + throw new SkippedException("not a supported platform"); + + Helper helper = Helper.newHelper(); + if (helper == null) { + System.err.println("Test not run"); + return; + } + + var module = "cds"; + helper.generateDefaultJModule(module); + var image = helper.generateDefaultImage(new String[] { "--generate-cds-archive" }, + module) + .assertSuccess(); + + String subDir; + String sep = File.separator; + if (Platform.isWindows()) { + subDir = "bin" + sep; + } else { + subDir = "lib" + sep; + } + subDir += "server" + sep; + + if (Platform.isAArch64() || Platform.isX64()) { + helper.checkImage(image, module, null, null, + new String[] { subDir + "classes.jsa", subDir + "classes_nocoops.jsa" }); + } else { + helper.checkImage(image, module, null, null, + new String[] { subDir + "classes.jsa" }); + } + + // Simulate different platforms between current runtime and target image. + if (Platform.isLinux()) { + System.out.println("---- Test different platforms scenario ----"); + String jlinkPath = JDKToolFinder.getJDKTool("jlink"); + String[] cmd = {jlinkPath, "--add-modules", "java.base,java.logging", + "-J-Dos.name=windows", "--generate-cds-archive", + "--output", System.getProperty("test.classes") + sep + module + "-tmp"}; + StringBuilder cmdLine = new StringBuilder(); + for (String s : cmd) { + cmdLine.append(s).append(' '); + } + System.out.println("Command line: [" + cmdLine.toString() + "]"); + ProcessBuilder pb = new ProcessBuilder(cmd); + OutputAnalyzer out = new OutputAnalyzer(pb.start()); + System.out.println(" stdout: " + out.getStdout()); + out.shouldMatch("Error: Cannot generate CDS archives: target image platform linux-.*is different from runtime platform windows-.*"); + out.shouldHaveExitValue(1); + } + } +} diff --git a/test/jdk/tools/jpackage/linux/LinuxResourceTest.java b/test/jdk/tools/jpackage/linux/LinuxResourceTest.java index 9f4e4cfad2f..250b71cd876 100644 --- a/test/jdk/tools/jpackage/linux/LinuxResourceTest.java +++ b/test/jdk/tools/jpackage/linux/LinuxResourceTest.java @@ -102,6 +102,7 @@ public static void testHardcodedProperties() throws IOException { "License: APPLICATION_LICENSE_TYPE", "Prefix: %{dirname:APPLICATION_DIRECTORY}", "Provides: dont-install-me", + "%define _build_id_links none", "%description", "APPLICATION_DESCRIPTION", "%prep", diff --git a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfInputStream.java b/test/jdk/tools/jpackage/linux/LinuxWeirdOutputDirTest.java similarity index 52% rename from test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfInputStream.java rename to test/jdk/tools/jpackage/linux/LinuxWeirdOutputDirTest.java index 3f27782ea5b..4ce3c1a4614 100644 --- a/test/jdk/java/net/httpclient/reactivestreams-tck-tests/BodyPublishersOfInputStream.java +++ b/test/jdk/tools/jpackage/linux/LinuxWeirdOutputDirTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -21,31 +21,30 @@ * questions. */ -import org.reactivestreams.tck.TestEnvironment; -import org.reactivestreams.tck.flow.FlowPublisherVerification; +import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.Annotations.Parameter; +import jdk.jpackage.test.JPackageCommand; -import java.io.InputStream; -import java.net.http.HttpRequest.BodyPublishers; -import java.nio.ByteBuffer; -import java.util.concurrent.Flow.Publisher; -import java.util.function.Supplier; - -/* See TckDriver.java for more information */ -public class BodyPublishersOfInputStream - extends FlowPublisherVerification { - - public BodyPublishersOfInputStream() { - super(new TestEnvironment(450L)); - } - - @Override - public Publisher createFlowPublisher(long nElements) { - Supplier s = () -> S.inputStreamOfNReads((int) nElements); - return BodyPublishers.ofInputStream(s); - } +/* + * @test + * @summary jpackage with values of --dest parameter breaking jpackage launcher + * @requires (os.family == "linux") + * @bug 8268974 + * @library ../helpers + * @build jdk.jpackage.test.* + * @modules jdk.jpackage/jdk.jpackage.internal + * @compile LinuxWeirdOutputDirTest.java + * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=LinuxWeirdOutputDirTest + */ +public class LinuxWeirdOutputDirTest { - @Override - public Publisher createFailedFlowPublisher() { - return null; + @Test + @Parameter("bin") + @Parameter("lib") + public void test(String outputPath) { + JPackageCommand cmd = JPackageCommand.helloAppImage(); + cmd.setArgumentValue("--dest", cmd.outputDir().resolve(outputPath)); + cmd.executeAndAssertHelloAppImageCreated(); } } diff --git a/test/jdk/tools/launcher/RunpathTest.java b/test/jdk/tools/launcher/RunpathTest.java index cc050c589c7..c83a43195db 100644 --- a/test/jdk/tools/launcher/RunpathTest.java +++ b/test/jdk/tools/launcher/RunpathTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, 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,8 @@ /* * @test * @bug 7190813 8022719 - * @summary Check for extended RPATHs on *nixes + * @summary Check for extended RPATHs on Linux + * @requires os.family == "linux" * @compile -XDignore.symbol.file RunpathTest.java * @run main RunpathTest * @author ksrini @@ -57,25 +58,23 @@ void elfCheck(String javacmd, String expectedRpath) { final TestResult tr = doExec(elfreaderCmd, "-d", javacmd); if (!tr.matches(expectedRpath)) { System.out.println(tr); - throw new RuntimeException("FAILED: RPATH/RUNPATH strings " + + throw new RuntimeException("FAILED: RPATH strings " + expectedRpath + " not found in " + javaCmd); } - System.out.println(javacmd + " contains expected RPATHS/RUNPATH"); + System.out.println(javacmd + " contains expected RPATHS"); } void testRpath() { - String expectedRpath = ".*R(UN)?PATH.*\\$ORIGIN/../lib.*"; + String expectedRpath = ".*RPATH.*\\$ORIGIN/../lib.*"; elfCheck(javaCmd, expectedRpath); } public static void main(String... args) throws Exception { - if (isLinux) { - RunpathTest rp = new RunpathTest(); - if (rp.elfreaderCmd == null) { - System.err.println("Warning: test passes vacuously"); - return; - } - rp.testRpath(); + RunpathTest rp = new RunpathTest(); + if (rp.elfreaderCmd == null) { + System.err.println("Warning: test passes vacuously"); + return; } + rp.testRpath(); } } diff --git a/test/jdk/tools/launcher/Settings.java b/test/jdk/tools/launcher/Settings.java index 76e62ffbe57..29af50d5c02 100644 --- a/test/jdk/tools/launcher/Settings.java +++ b/test/jdk/tools/launcher/Settings.java @@ -25,7 +25,7 @@ /* * @test - * @bug 6994753 7123582 8305950 + * @bug 6994753 7123582 8305950 8281658 * @summary tests -XshowSettings options * @modules jdk.compiler * jdk.zipfs @@ -67,6 +67,13 @@ static void checkNotContains(TestResult tr, String str) { private static final String VM_SETTINGS = "VM settings:"; private static final String PROP_SETTINGS = "Property settings:"; private static final String LOCALE_SETTINGS = "Locale settings:"; + private static final String SEC_PROPS_SETTINGS = "Security properties:"; + private static final String SEC_SUMMARY_PROPS_SETTINGS = + "Security settings summary:"; + private static final String SEC_PROVIDER_SETTINGS = + "Security provider static configuration:"; + private static final String SEC_TLS_SETTINGS = "Security TLS configuration"; + private static final String BAD_SEC_OPTION_MSG = "Unrecognized security subcommand"; private static final String SYSTEM_SETTINGS = "Operating System Metrics:"; private static final String STACKSIZE_SETTINGS = "Stack Size:"; private static final String TZDATA_SETTINGS = "tzdata version"; @@ -75,6 +82,11 @@ static void containsAllOptions(TestResult tr) { checkContains(tr, VM_SETTINGS); checkContains(tr, PROP_SETTINGS); checkContains(tr, LOCALE_SETTINGS); + // no verbose security settings unless "security" used + checkNotContains(tr, SEC_PROPS_SETTINGS); + checkContains(tr, SEC_SUMMARY_PROPS_SETTINGS); + checkContains(tr, SEC_PROVIDER_SETTINGS); + checkContains(tr, SEC_TLS_SETTINGS); checkContains(tr, TZDATA_SETTINGS); if (System.getProperty("os.name").contains("Linux")) { checkContains(tr, SYSTEM_SETTINGS); @@ -144,6 +156,54 @@ static void runTestOptionLocale() throws IOException { checkContains(tr, TZDATA_SETTINGS); } + static void runTestOptionSecurity() throws IOException { + TestResult tr = doExec(javaCmd, "-XshowSettings:security"); + checkNotContains(tr, VM_SETTINGS); + checkNotContains(tr, PROP_SETTINGS); + checkContains(tr, SEC_PROPS_SETTINGS); + checkContains(tr, SEC_PROVIDER_SETTINGS); + checkContains(tr, SEC_TLS_SETTINGS); + } + + static void runTestOptionSecurityProps() throws IOException { + TestResult tr = doExec(javaCmd, "-XshowSettings:security:properties"); + checkContains(tr, SEC_PROPS_SETTINGS); + checkNotContains(tr, SEC_PROVIDER_SETTINGS); + checkNotContains(tr, SEC_TLS_SETTINGS); + // test a well known property for sanity + checkContains(tr, "keystore.type=pkcs12"); + } + + static void runTestOptionSecurityProv() throws IOException { + TestResult tr = doExec(javaCmd, "-XshowSettings:security:providers"); + checkNotContains(tr, SEC_PROPS_SETTINGS); + checkContains(tr, SEC_PROVIDER_SETTINGS); + checkNotContains(tr, SEC_TLS_SETTINGS); + // test a well known Provider for sanity + checkContains(tr, "Provider name: SUN"); + // test for a well known alias (SunJCE: AlgorithmParameterGenerator.DiffieHellman) + checkContains(tr, "aliases: [1.2.840.113549.1.3.1, " + + "DH, OID.1.2.840.113549.1.3.1]"); + } + + static void runTestOptionSecurityTLS() throws IOException { + TestResult tr = doExec(javaCmd, "-XshowSettings:security:tls"); + checkNotContains(tr, SEC_PROPS_SETTINGS); + checkNotContains(tr, SEC_PROVIDER_SETTINGS); + checkContains(tr, SEC_TLS_SETTINGS); + // test a well known TLS config for sanity + checkContains(tr, "TLSv1.2"); + } + + // ensure error message is printed when unrecognized option used + static void runTestOptionBadSecurityOption() throws IOException { + TestResult tr = doExec(javaCmd, "-XshowSettings:security:bad"); + checkContains(tr, BAD_SEC_OPTION_MSG); + // we print all security settings in such scenario + checkNotContains(tr, SEC_PROPS_SETTINGS); + checkNotContains(tr, SEC_PROVIDER_SETTINGS); + checkNotContains(tr, SEC_TLS_SETTINGS); + } static void runTestOptionSystem() throws IOException { TestResult tr = doExec(javaCmd, "-XshowSettings:system"); if (System.getProperty("os.name").contains("Linux")) { @@ -181,6 +241,11 @@ public static void main(String... args) throws IOException { runTestOptionVM(); runTestOptionProperty(); runTestOptionLocale(); + runTestOptionSecurity(); + runTestOptionSecurityProps(); + runTestOptionSecurityProv(); + runTestOptionSecurityTLS(); + runTestOptionBadSecurityOption(); runTestOptionSystem(); runTestBadOptions(); runTest7123582(); diff --git a/test/jtreg-ext/requires/VMProps.java b/test/jtreg-ext/requires/VMProps.java index be2a9002079..452f3c9dce2 100644 --- a/test/jtreg-ext/requires/VMProps.java +++ b/test/jtreg-ext/requires/VMProps.java @@ -557,14 +557,15 @@ private String jdkContainerized() { * Checks if we are in almost out-of-box configuration, i.e. the flags * which JVM is started with don't affect its behavior "significantly". * {@code TEST_VM_FLAGLESS} enviroment variable can be used to force this - * method to return true and allow any flags. + * method to return true or false and allow or reject any flags. * * @return true if there are no JVM flags */ private String isFlagless() { boolean result = true; - if (System.getenv("TEST_VM_FLAGLESS") != null) { - return "" + result; + String flagless = System.getenv("TEST_VM_FLAGLESS"); + if (flagless != null) { + return "" + "true".equalsIgnoreCase(flagless); } List allFlags = new ArrayList(); diff --git a/test/langtools/TEST.groups b/test/langtools/TEST.groups index 8df9dcaadf5..2acd9855f60 100644 --- a/test/langtools/TEST.groups +++ b/test/langtools/TEST.groups @@ -67,10 +67,13 @@ langtools_sjavac = \ tools/all \ tools/sjavac +# All tests + +all = \ + :langtools_all + langtools_all = \ - jdk \ - lib \ - tools + / # Tiered testing definitions diff --git a/test/langtools/jdk/javadoc/doclet/5093723/T5093723.java b/test/langtools/jdk/javadoc/doclet/5093723/T5093723.java index cf5bb4a7cc6..f27b716ded1 100644 --- a/test/langtools/jdk/javadoc/doclet/5093723/T5093723.java +++ b/test/langtools/jdk/javadoc/doclet/5093723/T5093723.java @@ -36,7 +36,7 @@ public class T5093723 extends JavadocTester { public static void main(String... args) throws Exception { - T5093723 tester = new T5093723(); + var tester = new T5093723(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/AccessAsciiArt/AccessAsciiArt.java b/test/langtools/jdk/javadoc/doclet/AccessAsciiArt/AccessAsciiArt.java index 9714154b9b3..8bd40055b77 100644 --- a/test/langtools/jdk/javadoc/doclet/AccessAsciiArt/AccessAsciiArt.java +++ b/test/langtools/jdk/javadoc/doclet/AccessAsciiArt/AccessAsciiArt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -36,7 +36,7 @@ public class AccessAsciiArt extends JavadocTester { public static void main(String... args) throws Exception { - AccessAsciiArt tester = new AccessAsciiArt(); + var tester = new AccessAsciiArt(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/AccessH1/AccessH1.java b/test/langtools/jdk/javadoc/doclet/AccessH1/AccessH1.java index e199f232c54..9722ad3df04 100644 --- a/test/langtools/jdk/javadoc/doclet/AccessH1/AccessH1.java +++ b/test/langtools/jdk/javadoc/doclet/AccessH1/AccessH1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -37,7 +37,7 @@ public class AccessH1 extends JavadocTester { public static void main(String... args) throws Exception { - AccessH1 tester = new AccessH1(); + var tester = new AccessH1(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/AccessSkipNav/AccessSkipNav.java b/test/langtools/jdk/javadoc/doclet/AccessSkipNav/AccessSkipNav.java index 6577029c9cc..7e7a29e1515 100644 --- a/test/langtools/jdk/javadoc/doclet/AccessSkipNav/AccessSkipNav.java +++ b/test/langtools/jdk/javadoc/doclet/AccessSkipNav/AccessSkipNav.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -36,7 +36,7 @@ public class AccessSkipNav extends JavadocTester { public static void main(String... args) throws Exception { - AccessSkipNav tester = new AccessSkipNav(); + var tester = new AccessSkipNav(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/AccessSummary/AccessSummary.java b/test/langtools/jdk/javadoc/doclet/AccessSummary/AccessSummary.java index dd4377fcc11..343a931b0ab 100644 --- a/test/langtools/jdk/javadoc/doclet/AccessSummary/AccessSummary.java +++ b/test/langtools/jdk/javadoc/doclet/AccessSummary/AccessSummary.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -40,7 +40,7 @@ public class AccessSummary extends JavadocTester { * @throws Exception if the test fails */ public static void main(String... args) throws Exception { - AccessSummary tester = new AccessSummary(); + var tester = new AccessSummary(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/AuthorDD/AuthorDD.java b/test/langtools/jdk/javadoc/doclet/AuthorDD/AuthorDD.java index bbd89fee15a..75a52ce3ce1 100644 --- a/test/langtools/jdk/javadoc/doclet/AuthorDD/AuthorDD.java +++ b/test/langtools/jdk/javadoc/doclet/AuthorDD/AuthorDD.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -39,7 +39,7 @@ public class AuthorDD extends JavadocTester { public static void main(String... args) throws Exception { - AuthorDD tester = new AuthorDD(); + var tester = new AuthorDD(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/DocRootSlash/DocRootSlash.java b/test/langtools/jdk/javadoc/doclet/DocRootSlash/DocRootSlash.java index 52e547f7324..85b6d26aeeb 100644 --- a/test/langtools/jdk/javadoc/doclet/DocRootSlash/DocRootSlash.java +++ b/test/langtools/jdk/javadoc/doclet/DocRootSlash/DocRootSlash.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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,7 +43,7 @@ public class DocRootSlash extends JavadocTester { public static void main(String... args) throws Exception { - DocRootSlash tester = new DocRootSlash(); + var tester = new DocRootSlash(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/InheritDocForUserTags/DocTest.java b/test/langtools/jdk/javadoc/doclet/InheritDocForUserTags/DocTest.java index 4bee547be4b..99c70b33759 100644 --- a/test/langtools/jdk/javadoc/doclet/InheritDocForUserTags/DocTest.java +++ b/test/langtools/jdk/javadoc/doclet/InheritDocForUserTags/DocTest.java @@ -42,7 +42,7 @@ */ public class DocTest extends JavadocTester { public static void main(String... args) throws Exception { - DocTest tester = new DocTest(); + var tester = new DocTest(); tester.runTests(); } @@ -58,10 +58,6 @@ public void test() { testSrc("DocTest.java") ); checkExit(Exit.OK); - - // javadoc does not report an exit code for an internal exception (!) - // so monitor stderr for stack dumps. - checkOutput(Output.STDERR, false, "at com.sun"); } /** diff --git a/test/langtools/jdk/javadoc/doclet/JavascriptWinTitle/JavascriptWinTitle.java b/test/langtools/jdk/javadoc/doclet/JavascriptWinTitle/JavascriptWinTitle.java index 766765c6912..69b4dca6348 100644 --- a/test/langtools/jdk/javadoc/doclet/JavascriptWinTitle/JavascriptWinTitle.java +++ b/test/langtools/jdk/javadoc/doclet/JavascriptWinTitle/JavascriptWinTitle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -37,7 +37,7 @@ public class JavascriptWinTitle extends JavadocTester { public static void main(String... args) throws Exception { - JavascriptWinTitle tester = new JavascriptWinTitle(); + var tester = new JavascriptWinTitle(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/MetaTag/MetaTag.java b/test/langtools/jdk/javadoc/doclet/MetaTag/MetaTag.java index f5d5a901a75..d4aa8a1ffeb 100644 --- a/test/langtools/jdk/javadoc/doclet/MetaTag/MetaTag.java +++ b/test/langtools/jdk/javadoc/doclet/MetaTag/MetaTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -45,7 +45,7 @@ public class MetaTag extends JavadocTester { * @throws Exception if the test fails */ public static void main(String... args) throws Exception { - MetaTag tester = new MetaTag(); + var tester = new MetaTag(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/T6735320/T6735320.java b/test/langtools/jdk/javadoc/doclet/T6735320/T6735320.java index 7d945627596..9a5697f4099 100644 --- a/test/langtools/jdk/javadoc/doclet/T6735320/T6735320.java +++ b/test/langtools/jdk/javadoc/doclet/T6735320/T6735320.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, 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 @@ -36,7 +36,7 @@ public class T6735320 extends JavadocTester { public static void main(String... args) throws Exception { - T6735320 tester = new T6735320(); + var tester = new T6735320(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/ValidHtml/ValidHtml.java b/test/langtools/jdk/javadoc/doclet/ValidHtml/ValidHtml.java index 3a7443cbaea..303b77f5e55 100644 --- a/test/langtools/jdk/javadoc/doclet/ValidHtml/ValidHtml.java +++ b/test/langtools/jdk/javadoc/doclet/ValidHtml/ValidHtml.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -39,7 +39,7 @@ public class ValidHtml extends JavadocTester { public static void main(String... args) throws Exception { - ValidHtml tester = new ValidHtml(); + var tester = new ValidHtml(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/VersionNumber/VersionNumber.java b/test/langtools/jdk/javadoc/doclet/VersionNumber/VersionNumber.java index 25702cf630b..55630abf245 100644 --- a/test/langtools/jdk/javadoc/doclet/VersionNumber/VersionNumber.java +++ b/test/langtools/jdk/javadoc/doclet/VersionNumber/VersionNumber.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -40,7 +40,7 @@ public class VersionNumber extends JavadocTester { public static void main(String... args) throws Exception { - VersionNumber tester = new VersionNumber(); + var tester = new VersionNumber(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/WindowTitles/WindowTitles.java b/test/langtools/jdk/javadoc/doclet/WindowTitles/WindowTitles.java index a40fae5932f..49706de79fe 100644 --- a/test/langtools/jdk/javadoc/doclet/WindowTitles/WindowTitles.java +++ b/test/langtools/jdk/javadoc/doclet/WindowTitles/WindowTitles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -39,7 +39,7 @@ public class WindowTitles extends JavadocTester { public static void main(String... args) throws Exception { - WindowTitles tester = new WindowTitles(); + var tester = new WindowTitles(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/constantValues/TestConstantValuesDriver.java b/test/langtools/jdk/javadoc/doclet/constantValues/TestConstantValuesDriver.java index 92f0acaba44..4f6bdbc2537 100644 --- a/test/langtools/jdk/javadoc/doclet/constantValues/TestConstantValuesDriver.java +++ b/test/langtools/jdk/javadoc/doclet/constantValues/TestConstantValuesDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -35,7 +35,7 @@ public class TestConstantValuesDriver extends JavadocTester { public static void main(String... args) throws Exception { - TestConstantValuesDriver tester = new TestConstantValuesDriver(); + var tester = new TestConstantValuesDriver(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/dupThrowsTags/TestDupThrowsTags.java b/test/langtools/jdk/javadoc/doclet/dupThrowsTags/TestDupThrowsTags.java index bf4e0189beb..0526d5bd1f0 100644 --- a/test/langtools/jdk/javadoc/doclet/dupThrowsTags/TestDupThrowsTags.java +++ b/test/langtools/jdk/javadoc/doclet/dupThrowsTags/TestDupThrowsTags.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -35,7 +35,7 @@ public class TestDupThrowsTags extends JavadocTester { public static void main(String... args) throws Exception { - TestDupThrowsTags tester = new TestDupThrowsTags(); + var tester = new TestDupThrowsTags(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testAbsLinkPath/TestAbsLinkPath.java b/test/langtools/jdk/javadoc/doclet/testAbsLinkPath/TestAbsLinkPath.java index 72704b9ec93..1bbc2195d60 100644 --- a/test/langtools/jdk/javadoc/doclet/testAbsLinkPath/TestAbsLinkPath.java +++ b/test/langtools/jdk/javadoc/doclet/testAbsLinkPath/TestAbsLinkPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -36,7 +36,7 @@ public class TestAbsLinkPath extends JavadocTester { public static void main(String... args) throws Exception { - TestAbsLinkPath tester = new TestAbsLinkPath(); + var tester = new TestAbsLinkPath(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testAbstractMethod/TestAbstractMethod.java b/test/langtools/jdk/javadoc/doclet/testAbstractMethod/TestAbstractMethod.java index d834bbae92f..baf5effba18 100644 --- a/test/langtools/jdk/javadoc/doclet/testAbstractMethod/TestAbstractMethod.java +++ b/test/langtools/jdk/javadoc/doclet/testAbstractMethod/TestAbstractMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, 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 @@ -37,7 +37,7 @@ public class TestAbstractMethod extends JavadocTester { public static void main(String... args) throws Exception { - TestAbstractMethod tester = new TestAbstractMethod(); + var tester = new TestAbstractMethod(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testAnchorNames/TestAnchorNames.java b/test/langtools/jdk/javadoc/doclet/testAnchorNames/TestAnchorNames.java index 3c8a0a83ced..524048e5069 100644 --- a/test/langtools/jdk/javadoc/doclet/testAnchorNames/TestAnchorNames.java +++ b/test/langtools/jdk/javadoc/doclet/testAnchorNames/TestAnchorNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, 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 @@ -42,8 +42,8 @@ public class TestAnchorNames extends JavadocTester { public final ToolBox tb; public static void main(String... args) throws Exception { - TestAnchorNames tester = new TestAnchorNames(); - tester.runTests(m -> new Object[] { Paths.get(m.getName()) }); + var tester = new TestAnchorNames(); + tester.runTests(); } public TestAnchorNames() { diff --git a/test/langtools/jdk/javadoc/doclet/testAnnotationOptional/TestAnnotationOptional.java b/test/langtools/jdk/javadoc/doclet/testAnnotationOptional/TestAnnotationOptional.java index 0971d7c616d..14ba754abfa 100644 --- a/test/langtools/jdk/javadoc/doclet/testAnnotationOptional/TestAnnotationOptional.java +++ b/test/langtools/jdk/javadoc/doclet/testAnnotationOptional/TestAnnotationOptional.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2022, 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 @@ -37,7 +37,7 @@ public class TestAnnotationOptional extends JavadocTester { public static void main(String... args) throws Exception { - TestAnnotationOptional tester = new TestAnnotationOptional(); + var tester = new TestAnnotationOptional(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java b/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java index 8ad39de828c..0251d1ddc6c 100644 --- a/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java +++ b/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2022, 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 @@ -38,7 +38,7 @@ public class TestAnnotationTypes extends JavadocTester { public static void main(String... args) throws Exception { - TestAnnotationTypes tester = new TestAnnotationTypes(); + var tester = new TestAnnotationTypes(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testAuthor/TestAuthor.java b/test/langtools/jdk/javadoc/doclet/testAuthor/TestAuthor.java index 13f4277c414..630b5f2c29e 100644 --- a/test/langtools/jdk/javadoc/doclet/testAuthor/TestAuthor.java +++ b/test/langtools/jdk/javadoc/doclet/testAuthor/TestAuthor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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,7 +41,7 @@ public class TestAuthor extends JavadocTester { public static void main(String... args) throws Exception { - TestAuthor tester = new TestAuthor(); + var tester = new TestAuthor(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testAutoLoadTaglets/TestAutoLoadTaglets.java b/test/langtools/jdk/javadoc/doclet/testAutoLoadTaglets/TestAutoLoadTaglets.java index cd9d88cb423..c4d160d2d87 100644 --- a/test/langtools/jdk/javadoc/doclet/testAutoLoadTaglets/TestAutoLoadTaglets.java +++ b/test/langtools/jdk/javadoc/doclet/testAutoLoadTaglets/TestAutoLoadTaglets.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, 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 @@ -50,8 +50,8 @@ public class TestAutoLoadTaglets extends JavadocTester { final ToolBox tb; public static void main(String... args) throws Exception { - TestAutoLoadTaglets tester = new TestAutoLoadTaglets(); - tester.runTests(m -> new Object[]{Paths.get(m.getName())}); + var tester = new TestAutoLoadTaglets(); + tester.runTests(); } TestAutoLoadTaglets() { diff --git a/test/langtools/jdk/javadoc/doclet/testBackSlashInLink/TestBackSlashInLink.java b/test/langtools/jdk/javadoc/doclet/testBackSlashInLink/TestBackSlashInLink.java index e5ef8841239..0335af57b43 100644 --- a/test/langtools/jdk/javadoc/doclet/testBackSlashInLink/TestBackSlashInLink.java +++ b/test/langtools/jdk/javadoc/doclet/testBackSlashInLink/TestBackSlashInLink.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -37,7 +37,7 @@ public class TestBackSlashInLink extends JavadocTester { public static void main(String... args) throws Exception { - TestBackSlashInLink tester = new TestBackSlashInLink(); + var tester = new TestBackSlashInLink(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testBadHtml/TestBadHtml.java b/test/langtools/jdk/javadoc/doclet/testBadHtml/TestBadHtml.java index 88aa55dffcf..0455882bf07 100644 --- a/test/langtools/jdk/javadoc/doclet/testBadHtml/TestBadHtml.java +++ b/test/langtools/jdk/javadoc/doclet/testBadHtml/TestBadHtml.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, 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 @@ -36,7 +36,7 @@ public class TestBadHtml extends JavadocTester { public static void main(String... args) throws Exception { - TestBadHtml tester = new TestBadHtml(); + var tester = new TestBadHtml(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testBadPackageFileInJar/TestBadPackageFileInJar.java b/test/langtools/jdk/javadoc/doclet/testBadPackageFileInJar/TestBadPackageFileInJar.java index e57062fd8ae..37844d28c1f 100644 --- a/test/langtools/jdk/javadoc/doclet/testBadPackageFileInJar/TestBadPackageFileInJar.java +++ b/test/langtools/jdk/javadoc/doclet/testBadPackageFileInJar/TestBadPackageFileInJar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -47,7 +47,7 @@ public class TestBadPackageFileInJar extends JavadocTester { final ToolBox tb = new ToolBox(); public static void main(String... args) throws Exception { - TestBadPackageFileInJar tester = new TestBadPackageFileInJar(); + var tester = new TestBadPackageFileInJar(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testBadSourceFile/TestBadSourceFile.java b/test/langtools/jdk/javadoc/doclet/testBadSourceFile/TestBadSourceFile.java index edc041c9406..92ae60b9142 100644 --- a/test/langtools/jdk/javadoc/doclet/testBadSourceFile/TestBadSourceFile.java +++ b/test/langtools/jdk/javadoc/doclet/testBadSourceFile/TestBadSourceFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -42,7 +42,7 @@ public class TestBadSourceFile extends JavadocTester { * @throws Exception if the test fails */ public static void main(String... args) throws Exception { - TestBadSourceFile tester = new TestBadSourceFile(); + var tester = new TestBadSourceFile(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testBaseClass/TestBaseClass.java b/test/langtools/jdk/javadoc/doclet/testBaseClass/TestBaseClass.java index c26319d22dd..1711759ba3e 100644 --- a/test/langtools/jdk/javadoc/doclet/testBaseClass/TestBaseClass.java +++ b/test/langtools/jdk/javadoc/doclet/testBaseClass/TestBaseClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -37,7 +37,7 @@ public class TestBaseClass extends JavadocTester { public static void main(String... args) throws Exception { - TestBaseClass tester = new TestBaseClass(); + var tester = new TestBaseClass(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testBimodalTaglets/TestBimodalTaglets.java b/test/langtools/jdk/javadoc/doclet/testBimodalTaglets/TestBimodalTaglets.java index 7e6cb4b3c76..c091d33845a 100644 --- a/test/langtools/jdk/javadoc/doclet/testBimodalTaglets/TestBimodalTaglets.java +++ b/test/langtools/jdk/javadoc/doclet/testBimodalTaglets/TestBimodalTaglets.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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 @@ -49,7 +49,7 @@ public class TestBimodalTaglets extends JavadocTester implements Taglet { public static void main(String... args) throws Exception { - new TestBimodalTaglets().runTests(m -> new Object[] { Path.of(m.getName()) }); + new TestBimodalTaglets().runTests(); } ToolBox tb = new ToolBox(); diff --git a/test/langtools/jdk/javadoc/doclet/testBreakIterator/TestBreakIterator.java b/test/langtools/jdk/javadoc/doclet/testBreakIterator/TestBreakIterator.java index 4d33d550caf..72b1336dc59 100644 --- a/test/langtools/jdk/javadoc/doclet/testBreakIterator/TestBreakIterator.java +++ b/test/langtools/jdk/javadoc/doclet/testBreakIterator/TestBreakIterator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -39,7 +39,7 @@ public class TestBreakIterator extends JavadocTester { public static void main(String... args) throws Exception { - TestBreakIterator tester = new TestBreakIterator(); + var tester = new TestBreakIterator(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testCRLineSeparator/TestCRLineSeparator.java b/test/langtools/jdk/javadoc/doclet/testCRLineSeparator/TestCRLineSeparator.java index 1d68abffe32..5a0840f4f19 100644 --- a/test/langtools/jdk/javadoc/doclet/testCRLineSeparator/TestCRLineSeparator.java +++ b/test/langtools/jdk/javadoc/doclet/testCRLineSeparator/TestCRLineSeparator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2022, 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 @@ -39,7 +39,7 @@ public class TestCRLineSeparator extends JavadocTester { public static void main(String... args) throws Exception { - TestCRLineSeparator tester = new TestCRLineSeparator(); + var tester = new TestCRLineSeparator(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testCharset/TestCharset.java b/test/langtools/jdk/javadoc/doclet/testCharset/TestCharset.java index 2a5c05648f9..3900c2f27d8 100644 --- a/test/langtools/jdk/javadoc/doclet/testCharset/TestCharset.java +++ b/test/langtools/jdk/javadoc/doclet/testCharset/TestCharset.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, 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 @@ -37,7 +37,7 @@ public class TestCharset extends JavadocTester { public static void main(String... args) throws Exception { - TestCharset tester = new TestCharset(); + var tester = new TestCharset(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testCharsetDocencodingOptions/TestCharsetDocencodingOptions.java b/test/langtools/jdk/javadoc/doclet/testCharsetDocencodingOptions/TestCharsetDocencodingOptions.java index 32c6c65dccc..d77993a083b 100644 --- a/test/langtools/jdk/javadoc/doclet/testCharsetDocencodingOptions/TestCharsetDocencodingOptions.java +++ b/test/langtools/jdk/javadoc/doclet/testCharsetDocencodingOptions/TestCharsetDocencodingOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, 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 @@ -36,7 +36,7 @@ public class TestCharsetDocencodingOptions extends JavadocTester { public static void main(String... args) throws Exception { - TestCharsetDocencodingOptions tester = new TestCharsetDocencodingOptions(); + var tester = new TestCharsetDocencodingOptions(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testClassCrossReferences/TestClassCrossReferences.java b/test/langtools/jdk/javadoc/doclet/testClassCrossReferences/TestClassCrossReferences.java index dfb4a345e7c..982e38dafaa 100644 --- a/test/langtools/jdk/javadoc/doclet/testClassCrossReferences/TestClassCrossReferences.java +++ b/test/langtools/jdk/javadoc/doclet/testClassCrossReferences/TestClassCrossReferences.java @@ -39,7 +39,7 @@ public class TestClassCrossReferences extends JavadocTester { static final String uri = "http://docs.oracle.com/javase/8/docs/api/"; public static void main(String... args) throws Exception { - TestClassCrossReferences tester = new TestClassCrossReferences(); + var tester = new TestClassCrossReferences(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testClassLinks/TestClassLinks.java b/test/langtools/jdk/javadoc/doclet/testClassLinks/TestClassLinks.java index 6a608b8c286..a2bffa15305 100644 --- a/test/langtools/jdk/javadoc/doclet/testClassLinks/TestClassLinks.java +++ b/test/langtools/jdk/javadoc/doclet/testClassLinks/TestClassLinks.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, 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 @@ -37,7 +37,7 @@ public class TestClassLinks extends JavadocTester { public static void main(String... args) throws Exception { - TestClassLinks tester = new TestClassLinks(); + var tester = new TestClassLinks(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testClassTree/TestClassTree.java b/test/langtools/jdk/javadoc/doclet/testClassTree/TestClassTree.java index 520a87f406d..52a0e3ff55c 100644 --- a/test/langtools/jdk/javadoc/doclet/testClassTree/TestClassTree.java +++ b/test/langtools/jdk/javadoc/doclet/testClassTree/TestClassTree.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2022, 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 @@ -39,7 +39,7 @@ public class TestClassTree extends JavadocTester { public static void main(String... args) throws Exception { - TestClassTree tester = new TestClassTree(); + var tester = new TestClassTree(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testCmndLineClass/TestCmndLineClass.java b/test/langtools/jdk/javadoc/doclet/testCmndLineClass/TestCmndLineClass.java index fb466159d0d..285cd119ebd 100644 --- a/test/langtools/jdk/javadoc/doclet/testCmndLineClass/TestCmndLineClass.java +++ b/test/langtools/jdk/javadoc/doclet/testCmndLineClass/TestCmndLineClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -38,7 +38,7 @@ public class TestCmndLineClass extends JavadocTester { public static void main(String... args) throws Exception { - TestCmndLineClass tester = new TestCmndLineClass(); + var tester = new TestCmndLineClass(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testCompletionFailure/TestCompletionFailure.java b/test/langtools/jdk/javadoc/doclet/testCompletionFailure/TestCompletionFailure.java index b9c774b1454..d9ca6dd01df 100644 --- a/test/langtools/jdk/javadoc/doclet/testCompletionFailure/TestCompletionFailure.java +++ b/test/langtools/jdk/javadoc/doclet/testCompletionFailure/TestCompletionFailure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, 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 @@ -36,7 +36,7 @@ public class TestCompletionFailure extends JavadocTester { public static void main(String... args) throws Exception { - TestCompletionFailure tester = new TestCompletionFailure(); + var tester = new TestCompletionFailure(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testConditionalPages/TestConditionalPages.java b/test/langtools/jdk/javadoc/doclet/testConditionalPages/TestConditionalPages.java index 01f75e54779..4e7d7950fc9 100644 --- a/test/langtools/jdk/javadoc/doclet/testConditionalPages/TestConditionalPages.java +++ b/test/langtools/jdk/javadoc/doclet/testConditionalPages/TestConditionalPages.java @@ -44,8 +44,8 @@ public class TestConditionalPages extends JavadocTester { public static void main(String... args) throws Exception { - TestConditionalPages tester = new TestConditionalPages(); - tester.runTests(m -> new Object[] { Path.of(m.getName()) }); + var tester = new TestConditionalPages(); + tester.runTests(); } ToolBox tb = new ToolBox(); diff --git a/test/langtools/jdk/javadoc/doclet/testConstantValuesPage/TestConstantValuesPage.java b/test/langtools/jdk/javadoc/doclet/testConstantValuesPage/TestConstantValuesPage.java index 107776f6a57..324a876a5c5 100644 --- a/test/langtools/jdk/javadoc/doclet/testConstantValuesPage/TestConstantValuesPage.java +++ b/test/langtools/jdk/javadoc/doclet/testConstantValuesPage/TestConstantValuesPage.java @@ -37,7 +37,7 @@ public class TestConstantValuesPage extends JavadocTester { public static void main(String... args) throws Exception { - TestConstantValuesPage tester = new TestConstantValuesPage(); + var tester = new TestConstantValuesPage(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testConstructorIndent/TestConstructorIndent.java b/test/langtools/jdk/javadoc/doclet/testConstructorIndent/TestConstructorIndent.java index f24286d8752..01e2f25d69c 100644 --- a/test/langtools/jdk/javadoc/doclet/testConstructorIndent/TestConstructorIndent.java +++ b/test/langtools/jdk/javadoc/doclet/testConstructorIndent/TestConstructorIndent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -37,7 +37,7 @@ public class TestConstructorIndent extends JavadocTester { public static void main(String... args) throws Exception { - TestConstructorIndent tester = new TestConstructorIndent(); + var tester = new TestConstructorIndent(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testConstructors/TestConstructors.java b/test/langtools/jdk/javadoc/doclet/testConstructors/TestConstructors.java index 927b6caa881..d08f193eb4a 100644 --- a/test/langtools/jdk/javadoc/doclet/testConstructors/TestConstructors.java +++ b/test/langtools/jdk/javadoc/doclet/testConstructors/TestConstructors.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, 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 @@ -36,7 +36,7 @@ public class TestConstructors extends JavadocTester { public static void main(String... args) throws Exception { - TestConstructors tester = new TestConstructors(); + var tester = new TestConstructors(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java b/test/langtools/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java index 0a26e9c3458..a0989833e0f 100644 --- a/test/langtools/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java +++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java @@ -36,7 +36,7 @@ public class TestCopyFiles extends JavadocTester { public static void main(String... args) throws Exception { - TestCopyFiles tester = new TestCopyFiles(); + var tester = new TestCopyFiles(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/TestDeprecatedDocs.java b/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/TestDeprecatedDocs.java index 4f8d61b767b..d11c80914d8 100644 --- a/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/TestDeprecatedDocs.java +++ b/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/TestDeprecatedDocs.java @@ -37,7 +37,7 @@ public class TestDeprecatedDocs extends JavadocTester { public static void main(String... args) throws Exception { - TestDeprecatedDocs tester = new TestDeprecatedDocs(); + var tester = new TestDeprecatedDocs(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testDiagsLineCaret/TestDiagsLineCaret.java b/test/langtools/jdk/javadoc/doclet/testDiagsLineCaret/TestDiagsLineCaret.java index c9b7a3fd432..35c6670c73c 100644 --- a/test/langtools/jdk/javadoc/doclet/testDiagsLineCaret/TestDiagsLineCaret.java +++ b/test/langtools/jdk/javadoc/doclet/testDiagsLineCaret/TestDiagsLineCaret.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, 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 @@ -40,7 +40,7 @@ public class TestDiagsLineCaret extends JavadocTester { public static void main(String... args) throws Exception { - TestDiagsLineCaret tester = new TestDiagsLineCaret(); + var tester = new TestDiagsLineCaret(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testDocEncoding/TestDocEncoding.java b/test/langtools/jdk/javadoc/doclet/testDocEncoding/TestDocEncoding.java index 0406ef794d7..c89ca62d4af 100644 --- a/test/langtools/jdk/javadoc/doclet/testDocEncoding/TestDocEncoding.java +++ b/test/langtools/jdk/javadoc/doclet/testDocEncoding/TestDocEncoding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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,7 +43,7 @@ public class TestDocEncoding extends JavadocTester { public static void main(String... args) throws Exception { - TestDocEncoding tester = new TestDocEncoding(); + var tester = new TestDocEncoding(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testDocErrorReporter/TestDocErrorReporter.java b/test/langtools/jdk/javadoc/doclet/testDocErrorReporter/TestDocErrorReporter.java index 427300d8931..aae9e523b0b 100644 --- a/test/langtools/jdk/javadoc/doclet/testDocErrorReporter/TestDocErrorReporter.java +++ b/test/langtools/jdk/javadoc/doclet/testDocErrorReporter/TestDocErrorReporter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -42,7 +42,7 @@ public class TestDocErrorReporter extends JavadocTester { * @throws Exception if the test fails */ public static void main(String... args) throws Exception { - TestDocErrorReporter tester = new TestDocErrorReporter(); + var tester = new TestDocErrorReporter(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testDocFileDir/TestDocFileDir.java b/test/langtools/jdk/javadoc/doclet/testDocFileDir/TestDocFileDir.java index d2f9e98fa9c..479d896ef2d 100644 --- a/test/langtools/jdk/javadoc/doclet/testDocFileDir/TestDocFileDir.java +++ b/test/langtools/jdk/javadoc/doclet/testDocFileDir/TestDocFileDir.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -40,7 +40,7 @@ public class TestDocFileDir extends JavadocTester { public static void main(String... args) throws Exception { - TestDocFileDir tester = new TestDocFileDir(); + var tester = new TestDocFileDir(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testDocFiles/TestDocFiles.java b/test/langtools/jdk/javadoc/doclet/testDocFiles/TestDocFiles.java index c3f94515b36..4c5e27cb86b 100644 --- a/test/langtools/jdk/javadoc/doclet/testDocFiles/TestDocFiles.java +++ b/test/langtools/jdk/javadoc/doclet/testDocFiles/TestDocFiles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, 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 @@ -42,8 +42,8 @@ public class TestDocFiles extends JavadocTester { public static void main(String... args) throws Exception { - TestDocFiles tester = new TestDocFiles(); - tester.runTests(m -> new Object[] { Path.of(m.getName()) }); + var tester = new TestDocFiles(); + tester.runTests(); } ToolBox tb = new ToolBox(); diff --git a/test/langtools/jdk/javadoc/doclet/testDocLintOption/TestDocLintOption.java b/test/langtools/jdk/javadoc/doclet/testDocLintOption/TestDocLintOption.java index 55f696ec80b..d85c4ecdfd5 100644 --- a/test/langtools/jdk/javadoc/doclet/testDocLintOption/TestDocLintOption.java +++ b/test/langtools/jdk/javadoc/doclet/testDocLintOption/TestDocLintOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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 @@ -53,9 +53,9 @@ public class TestDocLintOption extends JavadocTester { public static void main(String... args) throws Exception { - TestDocLintOption tester = new TestDocLintOption(); + var tester = new TestDocLintOption(); tester.generateSrc(); - tester.runTests(m -> new Object[] { Paths.get(m.getName()) }); + tester.runTests(); } private final ToolBox tb = new ToolBox(); diff --git a/test/langtools/jdk/javadoc/doclet/testDocPaths/TestDocPaths.java b/test/langtools/jdk/javadoc/doclet/testDocPaths/TestDocPaths.java index 6178707bbd7..c4a09c9118b 100644 --- a/test/langtools/jdk/javadoc/doclet/testDocPaths/TestDocPaths.java +++ b/test/langtools/jdk/javadoc/doclet/testDocPaths/TestDocPaths.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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 @@ -37,7 +37,7 @@ public class TestDocPaths extends TestRunner { public static void main(String... args) throws Exception { - TestDocPaths tester = new TestDocPaths(); + var tester = new TestDocPaths(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testDocRootInlineTag/TestDocRootInlineTag.java b/test/langtools/jdk/javadoc/doclet/testDocRootInlineTag/TestDocRootInlineTag.java index 35d28ba3810..04d1e0f14db 100644 --- a/test/langtools/jdk/javadoc/doclet/testDocRootInlineTag/TestDocRootInlineTag.java +++ b/test/langtools/jdk/javadoc/doclet/testDocRootInlineTag/TestDocRootInlineTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -38,7 +38,7 @@ public class TestDocRootInlineTag extends JavadocTester { public static void main(String... args) throws Exception { - TestDocRootInlineTag tester = new TestDocRootInlineTag(); + var tester = new TestDocRootInlineTag(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testDocRootLink/TestDocRootLink.java b/test/langtools/jdk/javadoc/doclet/testDocRootLink/TestDocRootLink.java index b8b69f05ff7..2a534495e56 100644 --- a/test/langtools/jdk/javadoc/doclet/testDocRootLink/TestDocRootLink.java +++ b/test/langtools/jdk/javadoc/doclet/testDocRootLink/TestDocRootLink.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, 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 @@ -35,7 +35,7 @@ public class TestDocRootLink extends JavadocTester { public static void main(String... args) throws Exception { - TestDocRootLink tester = new TestDocRootLink(); + var tester = new TestDocRootLink(); // The test files intentionally contain examples of links that should // or should not be affected by the -Xdocrootparent option, and the diff --git a/test/langtools/jdk/javadoc/doclet/testDupParamWarn/TestDupParamWarn.java b/test/langtools/jdk/javadoc/doclet/testDupParamWarn/TestDupParamWarn.java index dde4a8fc6ad..cd8a425bd86 100644 --- a/test/langtools/jdk/javadoc/doclet/testDupParamWarn/TestDupParamWarn.java +++ b/test/langtools/jdk/javadoc/doclet/testDupParamWarn/TestDupParamWarn.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -37,7 +37,7 @@ public class TestDupParamWarn extends JavadocTester { public static void main(String... args) throws Exception { - JavadocTester tester = new TestDupParamWarn(); + var tester = new TestDupParamWarn(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testEmptyClass/TestEmptyClass.java b/test/langtools/jdk/javadoc/doclet/testEmptyClass/TestEmptyClass.java index b55dfb35a89..c92a9f4162b 100644 --- a/test/langtools/jdk/javadoc/doclet/testEmptyClass/TestEmptyClass.java +++ b/test/langtools/jdk/javadoc/doclet/testEmptyClass/TestEmptyClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, 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 @@ -37,7 +37,7 @@ public class TestEmptyClass extends JavadocTester { public static void main(String... args) throws Exception { - TestEmptyClass tester = new TestEmptyClass(); + var tester = new TestEmptyClass(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testEmptyInheritDoc/TestEmptyInheritDoc.java b/test/langtools/jdk/javadoc/doclet/testEmptyInheritDoc/TestEmptyInheritDoc.java index 49a29c29c4d..c969fcb834d 100644 --- a/test/langtools/jdk/javadoc/doclet/testEmptyInheritDoc/TestEmptyInheritDoc.java +++ b/test/langtools/jdk/javadoc/doclet/testEmptyInheritDoc/TestEmptyInheritDoc.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, 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 @@ -42,7 +42,7 @@ public class TestEmptyInheritDoc extends JavadocTester { public static void main(String... args) throws Exception { - TestEmptyInheritDoc tester = new TestEmptyInheritDoc(); + var tester = new TestEmptyInheritDoc(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testEnclosingClass/TestEnclosingClass.java b/test/langtools/jdk/javadoc/doclet/testEnclosingClass/TestEnclosingClass.java index b1f60eae32b..e744661cc8b 100644 --- a/test/langtools/jdk/javadoc/doclet/testEnclosingClass/TestEnclosingClass.java +++ b/test/langtools/jdk/javadoc/doclet/testEnclosingClass/TestEnclosingClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2022, 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 @@ -36,7 +36,7 @@ public class TestEnclosingClass extends JavadocTester { public static void main(String... args) throws Exception { - TestEnclosingClass tester = new TestEnclosingClass(); + var tester = new TestEnclosingClass(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testEncoding/TestEncoding.java b/test/langtools/jdk/javadoc/doclet/testEncoding/TestEncoding.java index cbd8d26bd2d..ec028c7d8fd 100644 --- a/test/langtools/jdk/javadoc/doclet/testEncoding/TestEncoding.java +++ b/test/langtools/jdk/javadoc/doclet/testEncoding/TestEncoding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -37,7 +37,7 @@ public class TestEncoding extends JavadocTester { public static void main(String... args) throws Exception { - TestEncoding tester = new TestEncoding(); + var tester = new TestEncoding(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testEnumConstructor/TestEnumConstructor.java b/test/langtools/jdk/javadoc/doclet/testEnumConstructor/TestEnumConstructor.java index e6dadfcecdd..225893cb417 100644 --- a/test/langtools/jdk/javadoc/doclet/testEnumConstructor/TestEnumConstructor.java +++ b/test/langtools/jdk/javadoc/doclet/testEnumConstructor/TestEnumConstructor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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 @@ -44,8 +44,8 @@ public class TestEnumConstructor extends JavadocTester { final ToolBox tb; public static void main(String... args) throws Exception { - TestEnumConstructor tester = new TestEnumConstructor(); - tester.runTests(m -> new Object[]{Paths.get(m.getName())}); + var tester = new TestEnumConstructor(); + tester.runTests(); } TestEnumConstructor() { diff --git a/test/langtools/jdk/javadoc/doclet/testExceptionInheritance/TestExceptionInheritance.java b/test/langtools/jdk/javadoc/doclet/testExceptionInheritance/TestExceptionInheritance.java index e61b2cfc7b0..ad5e910a94e 100644 --- a/test/langtools/jdk/javadoc/doclet/testExceptionInheritance/TestExceptionInheritance.java +++ b/test/langtools/jdk/javadoc/doclet/testExceptionInheritance/TestExceptionInheritance.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, 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 @@ -40,8 +40,8 @@ public class TestExceptionInheritance extends JavadocTester { public static void main(String... args) throws Exception { - TestExceptionInheritance tester = new TestExceptionInheritance(); - tester.runTests(m -> new Object[] { Path.of(m.getName()) }); + var tester = new TestExceptionInheritance(); + tester.runTests(); } ToolBox tb = new ToolBox(); diff --git a/test/langtools/jdk/javadoc/doclet/testExternalOverriddenMethod/TestExternalOverriddenMethod.java b/test/langtools/jdk/javadoc/doclet/testExternalOverriddenMethod/TestExternalOverriddenMethod.java index d60c4d40167..889b2edd1b5 100644 --- a/test/langtools/jdk/javadoc/doclet/testExternalOverriddenMethod/TestExternalOverriddenMethod.java +++ b/test/langtools/jdk/javadoc/doclet/testExternalOverriddenMethod/TestExternalOverriddenMethod.java @@ -39,7 +39,7 @@ public class TestExternalOverriddenMethod extends JavadocTester { static final String uri = "http://java.sun.com/j2se/1.4.1/docs/api"; public static void main(String... args) throws Exception { - TestExternalOverriddenMethod tester = new TestExternalOverriddenMethod(); + var tester = new TestExternalOverriddenMethod(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testGeneratedBy/TestGeneratedBy.java b/test/langtools/jdk/javadoc/doclet/testGeneratedBy/TestGeneratedBy.java index 4d7ad533152..4cd8284791b 100644 --- a/test/langtools/jdk/javadoc/doclet/testGeneratedBy/TestGeneratedBy.java +++ b/test/langtools/jdk/javadoc/doclet/testGeneratedBy/TestGeneratedBy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, 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 @@ -36,7 +36,7 @@ public class TestGeneratedBy extends JavadocTester { public static void main(String... args) throws Exception { - TestGeneratedBy tester = new TestGeneratedBy(); + var tester = new TestGeneratedBy(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testGeneratedClasses/TestGeneratedClasses.java b/test/langtools/jdk/javadoc/doclet/testGeneratedClasses/TestGeneratedClasses.java index 9ffbc8baa8b..c412ce49f98 100644 --- a/test/langtools/jdk/javadoc/doclet/testGeneratedClasses/TestGeneratedClasses.java +++ b/test/langtools/jdk/javadoc/doclet/testGeneratedClasses/TestGeneratedClasses.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, 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 @@ -39,8 +39,8 @@ public class TestGeneratedClasses extends JavadocTester { public static void main(String... args) throws Exception { - TestGeneratedClasses tester = new TestGeneratedClasses(); - tester.runTests(m -> new Object[]{Path.of(m.getName())}); + var tester = new TestGeneratedClasses(); + tester.runTests(); } ToolBox tb = new ToolBox(); diff --git a/test/langtools/jdk/javadoc/doclet/testGenericMethodLinkTaglet/TestGenericMethodLinkTaglet.java b/test/langtools/jdk/javadoc/doclet/testGenericMethodLinkTaglet/TestGenericMethodLinkTaglet.java index a6d7e381869..a9a4be1b262 100644 --- a/test/langtools/jdk/javadoc/doclet/testGenericMethodLinkTaglet/TestGenericMethodLinkTaglet.java +++ b/test/langtools/jdk/javadoc/doclet/testGenericMethodLinkTaglet/TestGenericMethodLinkTaglet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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 @@ -45,8 +45,8 @@ public class TestGenericMethodLinkTaglet extends JavadocTester { final ToolBox tb; public static void main(String... args) throws Exception { - TestGenericMethodLinkTaglet tester = new TestGenericMethodLinkTaglet(); - tester.runTests(m -> new Object[]{Paths.get(m.getName())}); + var tester = new TestGenericMethodLinkTaglet(); + tester.runTests(); } TestGenericMethodLinkTaglet() { diff --git a/test/langtools/jdk/javadoc/doclet/testGrandParentTypes/TestGrandParentTypes.java b/test/langtools/jdk/javadoc/doclet/testGrandParentTypes/TestGrandParentTypes.java index 3d20cf8a95b..779f9fbbb81 100644 --- a/test/langtools/jdk/javadoc/doclet/testGrandParentTypes/TestGrandParentTypes.java +++ b/test/langtools/jdk/javadoc/doclet/testGrandParentTypes/TestGrandParentTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, 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 @@ -37,7 +37,7 @@ public class TestGrandParentTypes extends JavadocTester { public static void main(String... args) throws Exception { - TestGrandParentTypes tester = new TestGrandParentTypes(); + var tester = new TestGrandParentTypes(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testGroupName/TestGroupName.java b/test/langtools/jdk/javadoc/doclet/testGroupName/TestGroupName.java index 743fc72e90d..84e4d140d95 100644 --- a/test/langtools/jdk/javadoc/doclet/testGroupName/TestGroupName.java +++ b/test/langtools/jdk/javadoc/doclet/testGroupName/TestGroupName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, 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 @@ -42,8 +42,8 @@ public class TestGroupName extends JavadocTester { public final ToolBox tb; public static void main(String... args) throws Exception { - TestGroupName tester = new TestGroupName(); - tester.runTests(m -> new Object[] { Paths.get(m.getName()) }); + var tester = new TestGroupName(); + tester.runTests(); } public TestGroupName() { diff --git a/test/langtools/jdk/javadoc/doclet/testGroupOption/TestGroupOption.java b/test/langtools/jdk/javadoc/doclet/testGroupOption/TestGroupOption.java index ef8baf55972..3a946f328d6 100644 --- a/test/langtools/jdk/javadoc/doclet/testGroupOption/TestGroupOption.java +++ b/test/langtools/jdk/javadoc/doclet/testGroupOption/TestGroupOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -37,7 +37,7 @@ public class TestGroupOption extends JavadocTester { public static void main(String... args) throws Exception { - TestGroupOption tester = new TestGroupOption(); + var tester = new TestGroupOption(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testHeadTag/TestHeadTag.java b/test/langtools/jdk/javadoc/doclet/testHeadTag/TestHeadTag.java index e6a657d7ef4..547592277c1 100644 --- a/test/langtools/jdk/javadoc/doclet/testHeadTag/TestHeadTag.java +++ b/test/langtools/jdk/javadoc/doclet/testHeadTag/TestHeadTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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 @@ -47,8 +47,8 @@ public class TestHeadTag extends JavadocTester { final String version = System.getProperty("java.specification.version"); public static void main(String... args) throws Exception { - TestHeadTag tester = new TestHeadTag(); - tester.runTests(m -> new Object[]{Paths.get(m.getName())}); + var tester = new TestHeadTag(); + tester.runTests(); } TestHeadTag() { diff --git a/test/langtools/jdk/javadoc/doclet/testHeadings/TestHeadings.java b/test/langtools/jdk/javadoc/doclet/testHeadings/TestHeadings.java index dfa22f8edb0..1e9867fcb65 100644 --- a/test/langtools/jdk/javadoc/doclet/testHeadings/TestHeadings.java +++ b/test/langtools/jdk/javadoc/doclet/testHeadings/TestHeadings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -37,7 +37,7 @@ public class TestHeadings extends JavadocTester { public static void main(String... args) throws Exception { - TestHeadings tester = new TestHeadings(); + var tester = new TestHeadings(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testHelpFile/TestHelpFile.java b/test/langtools/jdk/javadoc/doclet/testHelpFile/TestHelpFile.java index df544cd8110..462bc872161 100644 --- a/test/langtools/jdk/javadoc/doclet/testHelpFile/TestHelpFile.java +++ b/test/langtools/jdk/javadoc/doclet/testHelpFile/TestHelpFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, 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 @@ -38,7 +38,7 @@ public class TestHelpFile extends JavadocTester { public static final int ZERO = 0; public static void main(String... args) throws Exception { - TestHelpFile tester = new TestHelpFile(); + var tester = new TestHelpFile(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testHelpOption/TestHelpOption.java b/test/langtools/jdk/javadoc/doclet/testHelpOption/TestHelpOption.java index 705b5bc7ef8..9991f9507ec 100644 --- a/test/langtools/jdk/javadoc/doclet/testHelpOption/TestHelpOption.java +++ b/test/langtools/jdk/javadoc/doclet/testHelpOption/TestHelpOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -39,7 +39,7 @@ public class TestHelpOption extends JavadocTester { public static void main(String... args) throws Exception { - TestHelpOption tester = new TestHelpOption(); + var tester = new TestHelpOption(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testHelpPage/TestHelpPage.java b/test/langtools/jdk/javadoc/doclet/testHelpPage/TestHelpPage.java index a3ee65ac70d..bdd4c914eec 100644 --- a/test/langtools/jdk/javadoc/doclet/testHelpPage/TestHelpPage.java +++ b/test/langtools/jdk/javadoc/doclet/testHelpPage/TestHelpPage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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 @@ -40,7 +40,7 @@ public class TestHelpPage extends JavadocTester { public static void main(String... args) throws Exception { - TestHelpPage tester = new TestHelpPage(); + var tester = new TestHelpPage(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testHiddenMembers/TestHiddenMembers.java b/test/langtools/jdk/javadoc/doclet/testHiddenMembers/TestHiddenMembers.java index e9a35475df5..b094ab537af 100644 --- a/test/langtools/jdk/javadoc/doclet/testHiddenMembers/TestHiddenMembers.java +++ b/test/langtools/jdk/javadoc/doclet/testHiddenMembers/TestHiddenMembers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -45,7 +45,7 @@ public class TestHiddenMembers extends JavadocTester { }; public static void main(String... args) throws Exception { - TestHiddenMembers tester = new TestHiddenMembers(); + var tester = new TestHiddenMembers(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testHiddenTag/TestHiddenTag.java b/test/langtools/jdk/javadoc/doclet/testHiddenTag/TestHiddenTag.java index a4d1f75ae40..b80efdf9352 100644 --- a/test/langtools/jdk/javadoc/doclet/testHiddenTag/TestHiddenTag.java +++ b/test/langtools/jdk/javadoc/doclet/testHiddenTag/TestHiddenTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, 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 @@ -36,7 +36,7 @@ public class TestHiddenTag extends JavadocTester { public static void main(String... args) throws Exception { - TestHiddenTag tester = new TestHiddenTag(); + var tester = new TestHiddenTag(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java b/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java index 303f7b96966..d281a0cbb9f 100644 --- a/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java +++ b/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java @@ -36,7 +36,7 @@ public class TestHref extends JavadocTester { public static void main(String... args) throws Exception { - TestHref tester = new TestHref(); + var tester = new TestHref(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/TestHrefInDocComment.java b/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/TestHrefInDocComment.java index 5af53e19048..830920159f3 100644 --- a/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/TestHrefInDocComment.java +++ b/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/TestHrefInDocComment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -37,7 +37,7 @@ public class TestHrefInDocComment extends JavadocTester { public static void main(String... args) throws Exception { - TestHrefInDocComment tester = new TestHrefInDocComment(); + var tester = new TestHrefInDocComment(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testHtml4Removal/TestHtml4Removal.java b/test/langtools/jdk/javadoc/doclet/testHtml4Removal/TestHtml4Removal.java index 09329a769bc..8049cb75df8 100644 --- a/test/langtools/jdk/javadoc/doclet/testHtml4Removal/TestHtml4Removal.java +++ b/test/langtools/jdk/javadoc/doclet/testHtml4Removal/TestHtml4Removal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, 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 @@ -44,7 +44,7 @@ public static void main(String... args) throws Exception { Files.write(testFile, List.of("/** Comment. */", "public class C { }")); - TestHtml4Removal tester = new TestHtml4Removal(); + var tester = new TestHtml4Removal(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testHtmlComments/TestHtmlComments.java b/test/langtools/jdk/javadoc/doclet/testHtmlComments/TestHtmlComments.java index 38b8fb9a270..ed2966d1fb7 100644 --- a/test/langtools/jdk/javadoc/doclet/testHtmlComments/TestHtmlComments.java +++ b/test/langtools/jdk/javadoc/doclet/testHtmlComments/TestHtmlComments.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -37,7 +37,7 @@ public class TestHtmlComments extends JavadocTester { public static void main(String... args) throws Exception { - TestHtmlComments tester = new TestHtmlComments(); + var tester = new TestHtmlComments(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java b/test/langtools/jdk/javadoc/doclet/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java index 43d3942aa52..0e41697696c 100644 --- a/test/langtools/jdk/javadoc/doclet/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java +++ b/test/langtools/jdk/javadoc/doclet/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java @@ -41,7 +41,7 @@ public class TestHtmlDefinitionListTag extends JavadocTester { public static void main(String... args) throws Exception { - TestHtmlDefinitionListTag tester = new TestHtmlDefinitionListTag(); + var tester = new TestHtmlDefinitionListTag(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testHtmlDocument/TestHtmlDocument.java b/test/langtools/jdk/javadoc/doclet/testHtmlDocument/TestHtmlDocument.java index f2585c75459..f314276dde1 100644 --- a/test/langtools/jdk/javadoc/doclet/testHtmlDocument/TestHtmlDocument.java +++ b/test/langtools/jdk/javadoc/doclet/testHtmlDocument/TestHtmlDocument.java @@ -48,7 +48,7 @@ public class TestHtmlDocument extends JavadocTester { // Entry point public static void main(String... args) throws Exception { - TestHtmlDocument tester = new TestHtmlDocument(); + var tester = new TestHtmlDocument(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testHtmlLandmarkRegions/TestHtmlLandmarkRegions.java b/test/langtools/jdk/javadoc/doclet/testHtmlLandmarkRegions/TestHtmlLandmarkRegions.java index 1577d6d563f..8a265cef4f1 100644 --- a/test/langtools/jdk/javadoc/doclet/testHtmlLandmarkRegions/TestHtmlLandmarkRegions.java +++ b/test/langtools/jdk/javadoc/doclet/testHtmlLandmarkRegions/TestHtmlLandmarkRegions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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 @@ -51,8 +51,8 @@ public class TestHtmlLandmarkRegions extends JavadocTester { final ToolBox tb; public static void main(String... args) throws Exception { - TestHtmlLandmarkRegions tester = new TestHtmlLandmarkRegions(); - tester.runTests(m -> new Object[]{Paths.get(m.getName())}); + var tester = new TestHtmlLandmarkRegions(); + tester.runTests(); } TestHtmlLandmarkRegions() { diff --git a/test/langtools/jdk/javadoc/doclet/testHtmlStrongTag/TestHtmlStrongTag.java b/test/langtools/jdk/javadoc/doclet/testHtmlStrongTag/TestHtmlStrongTag.java index 74f9a9a210e..4d18c9c351a 100644 --- a/test/langtools/jdk/javadoc/doclet/testHtmlStrongTag/TestHtmlStrongTag.java +++ b/test/langtools/jdk/javadoc/doclet/testHtmlStrongTag/TestHtmlStrongTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, 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 @@ -36,7 +36,7 @@ public class TestHtmlStrongTag extends JavadocTester { public static void main(String... args) throws Exception { - TestHtmlStrongTag tester = new TestHtmlStrongTag(); + var tester = new TestHtmlStrongTag(); tester.runTests(); } diff --git a/test/langtools/jdk/javadoc/doclet/testHtmlTableStyles/TestHtmlTableStyles.java b/test/langtools/jdk/javadoc/doclet/testHtmlTableStyles/TestHtmlTableStyles.java index 32c23d6bf42..2225de2f9c5 100644 --- a/test/langtools/jdk/javadoc/doclet/testHtmlTableStyles/TestHtmlTableStyles.java +++ b/test/langtools/jdk/javadoc/doclet/testHtmlTableStyles/TestHtmlTableStyles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, 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 @@ -36,7 +36,7 @@ public class TestHtmlTableStyles extends JavadocTester { public static void main(String... args) throws Exception { - TestHtmlTableStyles tester = new TestHtmlTableStyles(); + var tester = new TestHtmlTableStyles(); tester.runTests(); } @@ -65,7 +65,7 @@ public void test() {

Constructors
""", """ -
"""); +
"""); checkOutput("pkg1/package-summary.html", true, """ diff --git a/test/langtools/jdk/javadoc/doclet/testHtmlTableTags/TestHtmlTableTags.java b/test/langtools/jdk/javadoc/doclet/testHtmlTableTags/TestHtmlTableTags.java index 0187764a134..d68874238e6 100644 --- a/test/langtools/jdk/javadoc/doclet/testHtmlTableTags/TestHtmlTableTags.java +++ b/test/langtools/jdk/javadoc/doclet/testHtmlTableTags/TestHtmlTableTags.java @@ -42,7 +42,7 @@ public class TestHtmlTableTags extends JavadocTester { public static void main(String... args) throws Exception { - TestHtmlTableTags tester = new TestHtmlTableTags(); + var tester = new TestHtmlTableTags(); tester.runTests(); } @@ -84,24 +84,24 @@ void checkHtmlTableTag() { //Package summary checkOutput("pkg1/package-summary.html", true, """ -
"""); +
"""); checkOutput("pkg2/package-summary.html", true, """ -
"""); +
"""); // Class documentation checkOutput("pkg1/C1.html", true, """
""", """ -
"""); +
"""); checkOutput("pkg2/C2.html", true, """
""", """ -
"""); +
"""); checkOutput("pkg2/C2.ModalExclusionType.html", true, """ diff --git a/test/langtools/jdk/javadoc/doclet/testHtmlTag/TestHtmlTag.java b/test/langtools/jdk/javadoc/doclet/testHtmlTag/TestHtmlTag.java index 0aa51351f8d..083bf94ed4d 100644 --- a/test/langtools/jdk/javadoc/doclet/testHtmlTag/TestHtmlTag.java +++ b/test/langtools/jdk/javadoc/doclet/testHtmlTag/TestHtmlTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2022, 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 @@ -38,7 +38,7 @@ public class TestHtmlTag extends JavadocTester { private static final String defaultLanguage = Locale.getDefault().getLanguage(); public static void main(String... args) throws Exception { - TestHtmlTag tester = new TestHtmlTag(); + var tester = new TestHtmlTag(); tester.runTests(); } @Test diff --git a/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java b/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java index 9637c589a06..5ef39f38b1a 100644 --- a/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java +++ b/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java @@ -37,7 +37,7 @@ public class TestHtmlVersion extends JavadocTester { public static void main(String... args) throws Exception { - TestHtmlVersion tester = new TestHtmlVersion(); + var tester = new TestHtmlVersion(); tester.runTests(); } @@ -97,7 +97,7 @@ void html5Output() {