diff --git a/.gitignore b/.gitignore index 0743489f8ec..b6b4a1a559a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ NashornProfile.txt **/JTreport/** **/JTwork/** /src/utils/LogCompilation/target/ +/src/utils/LogCompilation/logc.jar /.project/ /.settings/ /compile_commands.json diff --git a/make/PreInit.gmk b/make/PreInit.gmk index 3df44308dd9..8152587781c 100644 --- a/make/PreInit.gmk +++ b/make/PreInit.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -66,7 +66,8 @@ CALLED_SPEC_TARGETS := $(filter-out $(ALL_GLOBAL_TARGETS), $(CALLED_TARGETS)) ifeq ($(CALLED_SPEC_TARGETS), ) SKIP_SPEC := true endif -ifeq ($(findstring p, $(MAKEFLAGS))$(findstring q, $(MAKEFLAGS)), pq) +MFLAGS_SINGLE := $(filter-out --%, $(MFLAGS)) +ifeq ($(findstring p, $(MFLAGS_SINGLE))$(findstring q, $(MFLAGS_SINGLE)), pq) SKIP_SPEC := true endif diff --git a/make/autoconf/lib-bundled.m4 b/make/autoconf/lib-bundled.m4 index bc358928af0..7aa5fdf2589 100644 --- a/make/autoconf/lib-bundled.m4 +++ b/make/autoconf/lib-bundled.m4 @@ -267,7 +267,7 @@ AC_DEFUN_ONCE([LIB_SETUP_ZLIB], LIBZ_LIBS="" if test "x$USE_EXTERNAL_LIBZ" = "xfalse"; then LIBZ_CFLAGS="$LIBZ_CFLAGS -I$TOPDIR/src/java.base/share/native/libzip/zlib" - if test "x$OPENJDK_TARGET_OS" = xmacosx; then + if test "x$OPENJDK_TARGET_OS" = xmacosx -o "x$OPENJDK_TARGET_OS" = xaix -o "x$OPENJDK_TARGET_OS" = xlinux; then LIBZ_CFLAGS="$LIBZ_CFLAGS -DHAVE_UNISTD_H=1 -DHAVE_STDARG_H=1" fi else diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index a9ca91d9309..9734c6845ea 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -3403,11 +3403,13 @@ encode %{ } else if (rtype == relocInfo::metadata_type) { __ mov_metadata(dst_reg, (Metadata*)con); } else { - assert(rtype == relocInfo::none, "unexpected reloc type"); + assert(rtype == relocInfo::none || rtype == relocInfo::external_word_type, "unexpected reloc type"); + // load fake address constants using a normal move if (! __ is_valid_AArch64_address(con) || con < (address)(uintptr_t)os::vm_page_size()) { __ mov(dst_reg, con); } else { + // no reloc so just use adrp and add uint64_t offset; __ adrp(dst_reg, con, offset); __ add(dst_reg, dst_reg, offset); @@ -4535,6 +4537,18 @@ operand immP_1() interface(CONST_INTER); %} +// AOT Runtime Constants Address +operand immAOTRuntimeConstantsAddress() +%{ + // Check if the address is in the range of AOT Runtime Constants + predicate(AOTRuntimeConstants::contains((address)(n->get_ptr()))); + match(ConP); + + op_cost(0); + format %{ %} + interface(CONST_INTER); +%} + // Float and Double operands // Double Immediate operand immD() @@ -6898,6 +6912,20 @@ instruct loadConP1(iRegPNoSp dst, immP_1 con) ins_pipe(ialu_imm); %} +instruct loadAOTRCAddress(iRegPNoSp dst, immAOTRuntimeConstantsAddress con) +%{ + match(Set dst con); + + ins_cost(INSN_COST); + format %{ "adr $dst, $con\t# AOT Runtime Constants Address" %} + + ins_encode %{ + __ load_aotrc_address($dst$$Register, (address)$con$$constant); + %} + + ins_pipe(ialu_imm); +%} + // Load Narrow Pointer Constant instruct loadConN(iRegNNoSp dst, immN con) diff --git a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp index c0621cbd5c2..30048a2079d 100644 --- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp @@ -33,6 +33,7 @@ #include "c1/c1_ValueStack.hpp" #include "ci/ciArrayKlass.hpp" #include "ci/ciInstance.hpp" +#include "code/aotCodeCache.hpp" #include "code/compiledIC.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/gc_globals.hpp" @@ -532,6 +533,15 @@ void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_cod case T_LONG: { assert(patch_code == lir_patch_none, "no patching handled here"); +#if INCLUDE_CDS + if (AOTCodeCache::is_on_for_dump()) { + address b = c->as_pointer(); + if (AOTRuntimeConstants::contains(b)) { + __ load_aotrc_address(dest->as_register_lo(), b); + break; + } + } +#endif __ mov(dest->as_register_lo(), (intptr_t)c->as_jlong()); break; } diff --git a/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp index d7884c27a2c..68291720208 100644 --- a/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp @@ -23,6 +23,7 @@ */ #include "asm/macroAssembler.inline.hpp" +#include "code/aotCodeCache.hpp" #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1BarrierSetAssembler.hpp" #include "gc/g1/g1BarrierSetRuntime.hpp" @@ -243,9 +244,25 @@ static void generate_post_barrier(MacroAssembler* masm, assert_different_registers(store_addr, new_val, thread, tmp1, tmp2, noreg, rscratch1); // Does store cross heap regions? - __ eor(tmp1, store_addr, new_val); // tmp1 := store address ^ new value - __ lsr(tmp1, tmp1, G1HeapRegion::LogOfHRGrainBytes); // tmp1 := ((store address ^ new value) >> LogOfHRGrainBytes) - __ cbz(tmp1, done); + #if INCLUDE_CDS + // AOT code needs to load the barrier grain shift from the aot + // runtime constants area in the code cache otherwise we can compile + // it as an immediate operand + if (AOTCodeCache::is_on_for_dump()) { + address grain_shift_address = (address)AOTRuntimeConstants::grain_shift_address(); + __ eor(tmp1, store_addr, new_val); + __ lea(tmp2, ExternalAddress(grain_shift_address)); + __ ldrb(tmp2, tmp2); + __ lsrv(tmp1, tmp1, tmp2); + __ cbz(tmp1, done); + } else +#endif + { + __ eor(tmp1, store_addr, new_val); // tmp1 := store address ^ new value + __ lsr(tmp1, tmp1, G1HeapRegion::LogOfHRGrainBytes); // tmp1 := ((store address ^ new value) >> LogOfHRGrainBytes) + __ cbz(tmp1, done); + } + // Crosses regions, storing null? if (new_val_may_be_null) { __ cbz(new_val, done); diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index 35e90d296c9..3e3e95be07e 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -5754,6 +5754,14 @@ void MacroAssembler::adrp(Register reg1, const Address &dest, uint64_t &byte_off } void MacroAssembler::load_byte_map_base(Register reg) { +#if INCLUDE_CDS + if (AOTCodeCache::is_on_for_dump()) { + address byte_map_base_adr = AOTRuntimeConstants::card_table_base_address(); + lea(reg, ExternalAddress(byte_map_base_adr)); + ldr(reg, Address(reg)); + return; + } +#endif CardTableBarrierSet* ctbs = CardTableBarrierSet::barrier_set(); // Strictly speaking the card table base isn't an address at all, and it might @@ -5761,6 +5769,20 @@ void MacroAssembler::load_byte_map_base(Register reg) { mov(reg, (uint64_t)ctbs->card_table_base_const()); } +void MacroAssembler::load_aotrc_address(Register reg, address a) { +#if INCLUDE_CDS + assert(AOTRuntimeConstants::contains(a), "address out of range for data area"); + if (AOTCodeCache::is_on_for_dump()) { + // all aotrc field addresses should be registered in the AOTCodeCache address table + lea(reg, ExternalAddress(a)); + } else { + mov(reg, (uint64_t)a); + } +#else + ShouldNotReachHere(); +#endif +} + void MacroAssembler::build_frame(int framesize) { assert(framesize >= 2 * wordSize, "framesize must include space for FP/LR"); assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment"); diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp index 7b5af532ca1..fa32f3055b9 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp @@ -1476,6 +1476,9 @@ public: // Load the base of the cardtable byte map into reg. void load_byte_map_base(Register reg); + // Load a constant address in the AOT Runtime Constants area + void load_aotrc_address(Register reg, address a); + // Prolog generator routines to support switch between x86 code and // generated ARM code diff --git a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp index 37ee9451405..d9be0fdcc8d 100644 --- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp @@ -32,6 +32,7 @@ #include "c1/c1_ValueStack.hpp" #include "ci/ciArrayKlass.hpp" #include "ci/ciInstance.hpp" +#include "code/aotCodeCache.hpp" #include "compiler/oopMap.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/gc_globals.hpp" @@ -535,6 +536,15 @@ void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_cod case T_LONG: { assert(patch_code == lir_patch_none, "no patching handled here"); +#if INCLUDE_CDS + if (AOTCodeCache::is_on_for_dump()) { + address b = c->as_pointer(); + if (AOTRuntimeConstants::contains(b)) { + __ load_aotrc_address(dest->as_register_lo(), b); + break; + } + } +#endif __ movptr(dest->as_register_lo(), (intptr_t)c->as_jlong()); break; } diff --git a/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp index 34de9403ccf..b20d7b5cd07 100644 --- a/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp @@ -23,6 +23,7 @@ */ #include "asm/macroAssembler.inline.hpp" +#include "code/aotCodeCache.hpp" #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1BarrierSetAssembler.hpp" #include "gc/g1/g1BarrierSetRuntime.hpp" @@ -268,6 +269,16 @@ void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm, __ bind(done); } +#if INCLUDE_CDS +// return a register that differs from reg1, reg2, reg3 and reg4 + +static Register pick_different_reg(Register reg1, Register reg2 = noreg, Register reg3= noreg, Register reg4 = noreg) { + RegSet available = (RegSet::of(rscratch1, rscratch2, rax, rbx) + rdx - + RegSet::of(reg1, reg2, reg3, reg4)); + return *(available.begin()); +} +#endif // INCLUDE_CDS + static void generate_post_barrier(MacroAssembler* masm, const Register store_addr, const Register new_val, @@ -280,10 +291,32 @@ static void generate_post_barrier(MacroAssembler* masm, Label L_done; // Does store cross heap regions? - __ movptr(tmp1, store_addr); // tmp1 := store address - __ xorptr(tmp1, new_val); // tmp1 := store address ^ new value - __ shrptr(tmp1, G1HeapRegion::LogOfHRGrainBytes); // ((store address ^ new value) >> LogOfHRGrainBytes) == 0? - __ jccb(Assembler::equal, L_done); +#if INCLUDE_CDS + // AOT code needs to load the barrier grain shift from the aot + // runtime constants area in the code cache otherwise we can compile + // it as an immediate operand + + if (AOTCodeCache::is_on_for_dump()) { + address grain_shift_addr = AOTRuntimeConstants::grain_shift_address(); + Register save = pick_different_reg(rcx, tmp1, new_val, store_addr); + __ push(save); + __ movptr(save, store_addr); + __ xorptr(save, new_val); + __ push(rcx); + __ lea(rcx, ExternalAddress(grain_shift_addr)); + __ movl(rcx, Address(rcx, 0)); + __ shrptr(save); + __ pop(rcx); + __ pop(save); + __ jcc(Assembler::equal, L_done); + } else +#endif // INCLUDE_CDS + { + __ movptr(tmp1, store_addr); // tmp1 := store address + __ xorptr(tmp1, new_val); // tmp1 := store address ^ new value + __ shrptr(tmp1, G1HeapRegion::LogOfHRGrainBytes); // ((store address ^ new value) >> LogOfHRGrainBytes) == 0? + __ jccb(Assembler::equal, L_done); + } // Crosses regions, storing null? if (new_val_may_be_null) { diff --git a/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp index 65e6b4e01fc..0ea769dd488 100644 --- a/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp @@ -23,6 +23,7 @@ */ #include "asm/macroAssembler.inline.hpp" +#include "code/aotCodeCache.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/cardTable.hpp" #include "gc/shared/cardTableBarrierSet.hpp" @@ -111,7 +112,15 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl __ shrptr(end, CardTable::card_shift()); __ subptr(end, addr); // end --> cards count - __ mov64(tmp, (intptr_t)ctbs->card_table_base_const()); +#if INCLUDE_CDS + if (AOTCodeCache::is_on_for_dump()) { + __ lea(tmp, ExternalAddress(AOTRuntimeConstants::card_table_base_address())); + __ movq(tmp, Address(tmp, 0)); + } else +#endif + { + __ mov64(tmp, (intptr_t)ctbs->card_table_base_const()); + } __ addptr(addr, tmp); __ BIND(L_loop); __ movb(Address(addr, count, Address::times_1), 0); @@ -121,7 +130,7 @@ __ BIND(L_loop); __ BIND(L_done); } -void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register obj, Address dst) { +void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register obj, Address dst, Register rscratch) { // Does a store check for the oop in register obj. The content of // register obj is destroyed afterwards. CardTableBarrierSet* ctbs = CardTableBarrierSet::barrier_set(); @@ -136,6 +145,13 @@ void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register ob // never need to be relocated. On 64bit however the value may be too // large for a 32bit displacement. intptr_t byte_map_base = (intptr_t)ctbs->card_table_base_const(); +#if INCLUDE_CDS + if (AOTCodeCache::is_on_for_dump()) { + __ lea(rscratch, ExternalAddress(AOTRuntimeConstants::card_table_base_address())); + __ movq(rscratch, Address(rscratch, 0)); + card_addr = Address(rscratch, obj, Address::times_1, 0); + } else +#endif if (__ is_simm32(byte_map_base)) { card_addr = Address(noreg, obj, Address::times_1, byte_map_base); } else { @@ -174,10 +190,10 @@ void CardTableBarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorS if (needs_post_barrier) { // flatten object address if needed if (!precise || (dst.index() == noreg && dst.disp() == 0)) { - store_check(masm, dst.base(), dst); + store_check(masm, dst.base(), dst, tmp2); } else { __ lea(tmp1, dst); - store_check(masm, tmp1, dst); + store_check(masm, tmp1, dst, tmp2); } } } diff --git a/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.hpp b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.hpp index 0a36571c757..201c11062f2 100644 --- a/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.hpp @@ -33,7 +33,7 @@ protected: virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count) {} - void store_check(MacroAssembler* masm, Register obj, Address dst); + void store_check(MacroAssembler* masm, Register obj, Address dst, Register rscratch); virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, Register tmp); diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index 83169df3456..b54f6adc263 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -10034,6 +10034,20 @@ void MacroAssembler::restore_legacy_gprs() { addq(rsp, 16 * wordSize); } +void MacroAssembler::load_aotrc_address(Register reg, address a) { +#if INCLUDE_CDS + assert(AOTRuntimeConstants::contains(a), "address out of range for data area"); + if (AOTCodeCache::is_on_for_dump()) { + // all aotrc field addresses should be registered in the AOTCodeCache address table + lea(reg, ExternalAddress(a)); + } else { + mov64(reg, (uint64_t)a); + } +#else + ShouldNotReachHere(); +#endif +} + void MacroAssembler::setcc(Assembler::Condition comparison, Register dst) { if (VM_Version::supports_apx_f()) { esetzucc(comparison, dst); diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.hpp b/src/hotspot/cpu/x86/macroAssembler_x86.hpp index eb23199ca63..5c049f710e2 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp @@ -2070,6 +2070,7 @@ public: void save_legacy_gprs(); void restore_legacy_gprs(); + void load_aotrc_address(Register reg, address a); void setcc(Assembler::Condition comparison, Register dst); }; diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index aed54fe93d4..0ffa4c2031c 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -5187,6 +5187,18 @@ operand immL_65535() interface(CONST_INTER); %} +// AOT Runtime Constants Address +operand immAOTRuntimeConstantsAddress() +%{ + // Check if the address is in the range of AOT Runtime Constants + predicate(AOTRuntimeConstants::contains((address)(n->get_ptr()))); + match(ConP); + + op_cost(0); + format %{ %} + interface(CONST_INTER); +%} + operand kReg() %{ constraint(ALLOC_IN_RC(vectmask_reg)); @@ -7332,6 +7344,19 @@ instruct loadD(regD dst, memory mem) ins_pipe(pipe_slow); // XXX %} +instruct loadAOTRCAddress(rRegP dst, immAOTRuntimeConstantsAddress con) +%{ + match(Set dst con); + + format %{ "leaq $dst, $con\t# AOT Runtime Constants Address" %} + + ins_encode %{ + __ load_aotrc_address($dst$$Register, (address)$con$$constant); + %} + + ins_pipe(ialu_reg_fat); +%} + // max = java.lang.Math.max(float a, float b) instruct maxF_reg_avx10_2(regF dst, regF a, regF b) %{ predicate(VM_Version::supports_avx10_2()); diff --git a/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp index a20feadcba4..93beb549366 100644 --- a/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp +++ b/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp @@ -27,22 +27,30 @@ #include "runtime/vm_version.hpp" int VM_Version::get_current_sve_vector_length() { - assert(_features & CPU_SVE, "should not call this"); + assert(VM_Version::supports_sve(), "should not call this"); ShouldNotReachHere(); return 0; } int VM_Version::set_and_get_current_sve_vector_length(int length) { - assert(_features & CPU_SVE, "should not call this"); + assert(VM_Version::supports_sve(), "should not call this"); ShouldNotReachHere(); return 0; } void VM_Version::get_os_cpu_info() { - if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)) _features |= CPU_CRC32; - if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE)) _features |= CPU_AES | CPU_SHA1 | CPU_SHA2; - if (IsProcessorFeaturePresent(PF_ARM_VFP_32_REGISTERS_AVAILABLE)) _features |= CPU_ASIMD; + if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)) { + set_feature(CPU_CRC32); + } + if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE)) { + set_feature(CPU_AES); + set_feature(CPU_SHA1); + set_feature(CPU_SHA2); + } + if (IsProcessorFeaturePresent(PF_ARM_VFP_32_REGISTERS_AVAILABLE)) { + set_feature(CPU_ASIMD); + } // No check for CPU_PMULL, CPU_SVE, CPU_SVE2 __int64 dczid_el0 = _ReadStatusReg(0x5807 /* ARM64_DCZID_EL0 */); diff --git a/src/hotspot/share/adlc/main.cpp b/src/hotspot/share/adlc/main.cpp index 4e8a96617e8..8e6ea5bbec9 100644 --- a/src/hotspot/share/adlc/main.cpp +++ b/src/hotspot/share/adlc/main.cpp @@ -213,6 +213,7 @@ int main(int argc, char *argv[]) AD.addInclude(AD._CPP_file, "adfiles", get_basename(AD._VM_file._name)); AD.addInclude(AD._CPP_file, "adfiles", get_basename(AD._HPP_file._name)); AD.addInclude(AD._CPP_file, "memory/allocation.inline.hpp"); + AD.addInclude(AD._CPP_file, "code/aotCodeCache.hpp"); AD.addInclude(AD._CPP_file, "code/codeCache.hpp"); AD.addInclude(AD._CPP_file, "code/compiledIC.hpp"); AD.addInclude(AD._CPP_file, "code/nativeInst.hpp"); @@ -257,6 +258,7 @@ int main(int argc, char *argv[]) AD.addInclude(AD._CPP_PEEPHOLE_file, "adfiles", get_basename(AD._HPP_file._name)); AD.addInclude(AD._CPP_PIPELINE_file, "adfiles", get_basename(AD._HPP_file._name)); AD.addInclude(AD._DFA_file, "adfiles", get_basename(AD._HPP_file._name)); + AD.addInclude(AD._DFA_file, "code/aotCodeCache.hpp"); AD.addInclude(AD._DFA_file, "oops/compressedOops.hpp"); AD.addInclude(AD._DFA_file, "opto/cfgnode.hpp"); // Use PROB_MAX in predicate. AD.addInclude(AD._DFA_file, "opto/intrinsicnode.hpp"); diff --git a/src/hotspot/share/classfile/vmIntrinsics.hpp b/src/hotspot/share/classfile/vmIntrinsics.hpp index 29cb5d737d8..67817682ced 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.hpp +++ b/src/hotspot/share/classfile/vmIntrinsics.hpp @@ -1029,7 +1029,7 @@ class methodHandle; do_intrinsic(_VectorUnaryLibOp, jdk_internal_vm_vector_VectorSupport, vector_unary_lib_op_name, vector_unary_lib_op_sig, F_S) \ do_signature(vector_unary_lib_op_sig,"(J" \ "Ljava/lang/Class;" \ - "Ljava/lang/Class;" \ + "I" \ "I" \ "Ljava/lang/String;" \ "Ljdk/internal/vm/vector/VectorSupport$Vector;" \ @@ -1040,7 +1040,7 @@ class methodHandle; do_intrinsic(_VectorBinaryLibOp, jdk_internal_vm_vector_VectorSupport, vector_binary_lib_op_name, vector_binary_lib_op_sig, F_S) \ do_signature(vector_binary_lib_op_sig,"(J" \ "Ljava/lang/Class;" \ - "Ljava/lang/Class;" \ + "I" \ "I" \ "Ljava/lang/String;" \ "Ljdk/internal/vm/vector/VectorSupport$VectorPayload;" \ diff --git a/src/hotspot/share/code/aotCodeCache.cpp b/src/hotspot/share/code/aotCodeCache.cpp index 32a53691f3f..e5f68afc51d 100644 --- a/src/hotspot/share/code/aotCodeCache.cpp +++ b/src/hotspot/share/code/aotCodeCache.cpp @@ -29,9 +29,11 @@ #include "cds/cds_globals.hpp" #include "cds/cdsConfig.hpp" #include "cds/heapShared.hpp" +#include "ci/ciUtilities.hpp" #include "classfile/javaAssertions.hpp" #include "code/aotCodeCache.hpp" #include "code/codeCache.hpp" +#include "gc/shared/cardTableBarrierSet.hpp" #include "gc/shared/gcConfig.hpp" #include "logging/logStream.hpp" #include "memory/memoryReserver.hpp" @@ -53,6 +55,7 @@ #endif #if INCLUDE_G1GC #include "gc/g1/g1BarrierSetRuntime.hpp" +#include "gc/g1/g1HeapRegion.hpp" #endif #if INCLUDE_SHENANDOAHGC #include "gc/shenandoah/shenandoahRuntime.hpp" @@ -258,6 +261,9 @@ void AOTCodeCache::init2() { return; } + // initialize aot runtime constants as appropriate to this runtime + AOTRuntimeConstants::initialize_from_runtime(); + // initialize the table of external routines so we can save // generated code blobs that reference them AOTCodeAddressTable* table = opened_cache->_table; @@ -1447,6 +1453,12 @@ void AOTCodeAddressTable::init_extrs() { #endif #endif // ZERO + // addresses of fields in AOT runtime constants area + address* p = AOTRuntimeConstants::field_addresses_list(); + while (*p != nullptr) { + SET_ADDRESS(_extrs, *p++); + } + _extrs_complete = true; log_debug(aot, codecache, init)("External addresses recorded"); } @@ -1729,6 +1741,11 @@ int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeB if (addr == (address)-1) { // Static call stub has jump to itself return id; } + // Check card_table_base address first since it can point to any address + BarrierSet* bs = BarrierSet::barrier_set(); + bool is_const_card_table_base = !UseG1GC && !UseShenandoahGC && bs->is_a(BarrierSet::CardTableBarrierSet); + guarantee(!is_const_card_table_base || addr != ci_card_table_address_const(), "sanity"); + // Seach for C string id = id_for_C_string(addr); if (id >= 0) { @@ -1798,6 +1815,44 @@ int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeB return id; } +AOTRuntimeConstants AOTRuntimeConstants::_aot_runtime_constants; + +void AOTRuntimeConstants::initialize_from_runtime() { + BarrierSet* bs = BarrierSet::barrier_set(); + address card_table_base = nullptr; + uint grain_shift = 0; +#if INCLUDE_G1GC + if (bs->is_a(BarrierSet::G1BarrierSet)) { + grain_shift = G1HeapRegion::LogOfHRGrainBytes; + } else +#endif +#if INCLUDE_SHENANDOAHGC + if (bs->is_a(BarrierSet::ShenandoahBarrierSet)) { + grain_shift = 0; + } else +#endif + if (bs->is_a(BarrierSet::CardTableBarrierSet)) { + CardTable::CardValue* base = ci_card_table_address_const(); + assert(base != nullptr, "unexpected byte_map_base"); + card_table_base = base; + CardTableBarrierSet* ctbs = barrier_set_cast(bs); + grain_shift = ctbs->grain_shift(); + } + _aot_runtime_constants._card_table_base = card_table_base; + _aot_runtime_constants._grain_shift = grain_shift; +} + +address AOTRuntimeConstants::_field_addresses_list[] = { + ((address)&_aot_runtime_constants._card_table_base), + ((address)&_aot_runtime_constants._grain_shift), + nullptr +}; + +address AOTRuntimeConstants::card_table_base_address() { + assert(UseSerialGC || UseParallelGC, "Only these GCs have constant card table base"); + return (address)&_aot_runtime_constants._card_table_base; +} + // This is called after initialize() but before init2() // and _cache is not set yet. void AOTCodeCache::print_on(outputStream* st) { diff --git a/src/hotspot/share/code/aotCodeCache.hpp b/src/hotspot/share/code/aotCodeCache.hpp index 45b4a15510d..85f8b47920f 100644 --- a/src/hotspot/share/code/aotCodeCache.hpp +++ b/src/hotspot/share/code/aotCodeCache.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_CODE_AOTCODECACHE_HPP #define SHARE_CODE_AOTCODECACHE_HPP +#include "gc/shared/gc_globals.hpp" #include "runtime/stubInfo.hpp" /* @@ -422,4 +423,36 @@ public: #endif // PRODUCT }; +// code cache internal runtime constants area used by AOT code +class AOTRuntimeConstants { + friend class AOTCodeCache; + private: + address _card_table_base; + uint _grain_shift; + static address _field_addresses_list[]; + static AOTRuntimeConstants _aot_runtime_constants; + // private constructor for unique singleton + AOTRuntimeConstants() { } + // private for use by friend class AOTCodeCache + static void initialize_from_runtime(); + public: +#if INCLUDE_CDS + static bool contains(address adr) { + address base = (address)&_aot_runtime_constants; + address hi = base + sizeof(AOTRuntimeConstants); + return (base <= adr && adr < hi); + } + static address card_table_base_address(); + static address grain_shift_address() { return (address)&_aot_runtime_constants._grain_shift; } + static address* field_addresses_list() { + return _field_addresses_list; + } +#else + static bool contains(address adr) { return false; } + static address card_table_base_address() { return nullptr; } + static address grain_shift_address() { return nullptr; } + static address* field_addresses_list() { return nullptr; } +#endif +}; + #endif // SHARE_CODE_AOTCODECACHE_HPP diff --git a/src/hotspot/share/gc/g1/g1BarrierSet.hpp b/src/hotspot/share/gc/g1/g1BarrierSet.hpp index 406096acf10..c5c7058471c 100644 --- a/src/hotspot/share/gc/g1/g1BarrierSet.hpp +++ b/src/hotspot/share/gc/g1/g1BarrierSet.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_GC_G1_G1BARRIERSET_HPP #define SHARE_GC_G1_G1BARRIERSET_HPP +#include "gc/g1/g1HeapRegion.hpp" #include "gc/g1/g1SATBMarkQueueSet.hpp" #include "gc/shared/bufferNode.hpp" #include "gc/shared/cardTable.hpp" @@ -116,6 +117,8 @@ class G1BarrierSet: public CardTableBarrierSet { virtual void print_on(outputStream* st) const; + virtual uint grain_shift() { return G1HeapRegion::LogOfHRGrainBytes; } + // Callbacks for runtime accesses. template class AccessBarrier: public CardTableBarrierSet::AccessBarrier { diff --git a/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp b/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp index 914358760aa..86b74aa5736 100644 --- a/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp +++ b/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp @@ -22,6 +22,7 @@ * */ +#include "code/aotCodeCache.hpp" #include "gc/shared/c1/cardTableBarrierSetC1.hpp" #include "gc/shared/cardTable.hpp" #include "gc/shared/cardTableBarrierSet.hpp" @@ -123,6 +124,7 @@ void CardTableBarrierSetC1::post_barrier(LIRAccess& access, LIR_Opr addr, LIR_Op assert(addr->is_register(), "must be a register at this point"); #ifdef CARDTABLEBARRIERSET_POST_BARRIER_HELPER + assert(!AOTCodeCache::is_on(), "this path is not implemented"); gen->CardTableBarrierSet_post_barrier_helper(addr, card_table_base); #else LIR_Opr tmp = gen->new_pointer_register(); @@ -135,6 +137,17 @@ void CardTableBarrierSetC1::post_barrier(LIRAccess& access, LIR_Opr addr, LIR_Op } LIR_Address* card_addr; +#if INCLUDE_CDS + if (AOTCodeCache::is_on_for_dump()) { + // load the card table address from the AOT Runtime Constants area + LIR_Opr byte_map_base_adr = LIR_OprFact::intptrConst(AOTRuntimeConstants::card_table_base_address()); + LIR_Opr byte_map_base_reg = gen->new_pointer_register(); + __ move(byte_map_base_adr, byte_map_base_reg); + LIR_Address* byte_map_base_indirect = new LIR_Address(byte_map_base_reg, 0, T_LONG); + __ move(byte_map_base_indirect, byte_map_base_reg); + card_addr = new LIR_Address(tmp, byte_map_base_reg, T_BYTE); + } else +#endif if (gen->can_inline_as_constant(card_table_base)) { card_addr = new LIR_Address(tmp, card_table_base->as_jint(), T_BYTE); } else { diff --git a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp index 42af77ebdf4..f7445ff254f 100644 --- a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp +++ b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp @@ -23,6 +23,7 @@ */ #include "ci/ciUtilities.hpp" +#include "code/aotCodeCache.hpp" #include "gc/shared/c2/cardTableBarrierSetC2.hpp" #include "gc/shared/cardTable.hpp" #include "gc/shared/cardTableBarrierSet.hpp" @@ -114,13 +115,20 @@ Node* CardTableBarrierSetC2::atomic_xchg_at_resolved(C2AtomicParseAccess& access return result; } -Node* CardTableBarrierSetC2::byte_map_base_node(GraphKit* kit) const { +Node* CardTableBarrierSetC2::byte_map_base_node(IdealKit* kit) const { // Get base of card map +#if INCLUDE_CDS + if (AOTCodeCache::is_on_for_dump()) { + // load the card table address from the AOT Runtime Constants area + Node* byte_map_base_adr = kit->makecon(TypeRawPtr::make(AOTRuntimeConstants::card_table_base_address())); + return kit->load_aot_const(byte_map_base_adr, TypeRawPtr::NOTNULL); + } +#endif CardTable::CardValue* card_table_base = ci_card_table_address_const(); if (card_table_base != nullptr) { return kit->makecon(TypeRawPtr::make((address)card_table_base)); } else { - return kit->null(); + return kit->makecon(Type::get_zero_type(T_ADDRESS)); } } @@ -168,7 +176,7 @@ void CardTableBarrierSetC2::post_barrier(GraphKit* kit, Node* card_offset = __ URShiftX(cast, __ ConI(CardTable::card_shift())); // Combine card table base and card offset - Node* card_adr = __ AddP(__ top(), byte_map_base_node(kit), card_offset); + Node* card_adr = __ AddP(__ top(), byte_map_base_node(&ideal), card_offset); // Get the alias_index for raw card-mark memory int adr_type = Compile::AliasIdxRaw; diff --git a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.hpp b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.hpp index 84876808f0d..8f5bae8c6dd 100644 --- a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.hpp +++ b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.hpp @@ -43,7 +43,7 @@ protected: Node* new_val, const Type* value_type) const; virtual Node* atomic_xchg_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const; - Node* byte_map_base_node(GraphKit* kit) const; + Node* byte_map_base_node(IdealKit* kit) const; public: virtual void eliminate_gc_barrier(PhaseMacroExpand* macro, Node* node) const; diff --git a/src/hotspot/share/gc/shared/cardTableBarrierSet.hpp b/src/hotspot/share/gc/shared/cardTableBarrierSet.hpp index 3a9b46d9df8..5d355318b21 100644 --- a/src/hotspot/share/gc/shared/cardTableBarrierSet.hpp +++ b/src/hotspot/share/gc/shared/cardTableBarrierSet.hpp @@ -103,6 +103,10 @@ public: virtual void print_on(outputStream* st) const; + // The AOT code cache manager needs to know the region grain size + // shift for some barrier sets. + virtual uint grain_shift() { return 0; } + template class AccessBarrier: public BarrierSet::AccessBarrier { typedef BarrierSet::AccessBarrier Raw; diff --git a/src/hotspot/share/gc/shared/plab.hpp b/src/hotspot/share/gc/shared/plab.hpp index 5200f022633..d893a720e2a 100644 --- a/src/hotspot/share/gc/shared/plab.hpp +++ b/src/hotspot/share/gc/shared/plab.hpp @@ -147,14 +147,14 @@ public: // PLAB book-keeping. class PLABStats : public CHeapObj { -protected: - const char* _description; // Identifying string. - Atomic _allocated; // Total allocated Atomic _wasted; // of which wasted (internal fragmentation) Atomic _undo_wasted; // of which wasted on undo (is not used for calculation of PLAB size) Atomic _unused; // Unused in last buffer +protected: + const char* _description; // Identifying string. + virtual void reset() { _allocated.store_relaxed(0); _wasted.store_relaxed(0); @@ -164,11 +164,11 @@ protected: public: PLABStats(const char* description) : - _description(description), _allocated(0), _wasted(0), _undo_wasted(0), - _unused(0) + _unused(0), + _description(description) { } virtual ~PLABStats() { } diff --git a/src/hotspot/share/gc/shared/space.cpp b/src/hotspot/share/gc/shared/space.cpp index 84ba21527fd..093fa4432e2 100644 --- a/src/hotspot/share/gc/shared/space.cpp +++ b/src/hotspot/share/gc/shared/space.cpp @@ -51,7 +51,7 @@ void ContiguousSpace::initialize(MemRegion mr, set_bottom(bottom); set_end(end); if (clear_space) { - clear(SpaceDecorator::DontMangle); + set_top(bottom); } if (ZapUnusedHeapArea) { mangle_unused_area(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp index c6e6108fda8..2be5722f7f9 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp @@ -41,9 +41,9 @@ bool ShenandoahBarrierSetNMethod::nmethod_entry_barrier(nmethod* nm) { return true; } - ShenandoahReentrantLock* lock = ShenandoahNMethod::lock_for_nmethod(nm); + ShenandoahNMethodLock* lock = ShenandoahNMethod::lock_for_nmethod(nm); assert(lock != nullptr, "Must be"); - ShenandoahReentrantLocker locker(lock); + ShenandoahNMethodLocker locker(lock); if (!is_armed(nm)) { // Some other thread managed to complete while we were diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp index 07d339eb32e..64e135e9a4e 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp @@ -136,13 +136,13 @@ public: assert(!nm_data->is_unregistered(), "Should not see unregistered entry"); if (nm->is_unloading()) { - ShenandoahReentrantLocker locker(nm_data->lock()); + ShenandoahNMethodLocker locker(nm_data->lock()); nm->unlink(); return; } { - ShenandoahReentrantLocker locker(nm_data->lock()); + ShenandoahNMethodLocker locker(nm_data->lock()); // Heal oops if (_bs->is_armed(nm)) { @@ -154,7 +154,7 @@ public: } // Clear compiled ICs and exception caches - ShenandoahReentrantLocker locker(nm_data->ic_lock()); + ShenandoahNMethodLocker locker(nm_data->ic_lock()); nm->unload_nmethod_caches(_unloading_occurred); } }; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp index 364279deafe..5206a0558e8 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp @@ -1023,7 +1023,7 @@ public: void do_nmethod(nmethod* n) { ShenandoahNMethod* data = ShenandoahNMethod::gc_data(n); - ShenandoahReentrantLocker locker(data->lock()); + ShenandoahNMethodLocker locker(data->lock()); // Setup EvacOOM scope below reentrant lock to avoid deadlock with // nmethod_entry_barrier ShenandoahEvacOOMScope oom; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp index 91c6024d522..d55a06d5713 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp @@ -32,8 +32,8 @@ #include "gc/shenandoah/shenandoahSimpleBitMap.hpp" #include "logging/logStream.hpp" -typedef ShenandoahLock ShenandoahRebuildLock; -typedef ShenandoahLocker ShenandoahRebuildLocker; +typedef ShenandoahLock ShenandoahRebuildLock; +typedef ShenandoahLocker ShenandoahRebuildLocker; // Each ShenandoahHeapRegion is associated with a ShenandoahFreeSetPartitionId. enum class ShenandoahFreeSetPartitionId : uint8_t { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 9dd837b90d2..d78bdae6a51 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -2834,3 +2834,13 @@ void ShenandoahHeap::log_heap_status(const char* msg) const { global_generation()->log_status(msg); } } + +ShenandoahHeapLocker::ShenandoahHeapLocker(ShenandoahHeapLock* lock, bool allow_block_for_safepoint) : _lock(lock) { +#ifdef ASSERT + ShenandoahFreeSet* free_set = ShenandoahHeap::heap()->free_set(); + // free_set is nullptr only at pre-initialized state + assert(free_set == nullptr || !free_set->rebuild_lock()->owned_by_self(), "Dead lock, can't acquire heap lock while holding free-set rebuild lock"); + assert(_lock != nullptr, "Must not"); +#endif + _lock->lock(allow_block_for_safepoint); +} diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index 4a4499667ff..85ad339469d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -117,9 +117,23 @@ public: virtual bool is_thread_safe() { return false; } }; -typedef ShenandoahLock ShenandoahHeapLock; -typedef ShenandoahLocker ShenandoahHeapLocker; -typedef Stack ShenandoahScanObjectStack; +typedef ShenandoahLock ShenandoahHeapLock; +// ShenandoahHeapLocker implements locker to assure mutually exclusive access to the global heap data structures. +// Asserts in the implementation detect potential deadlock usage with regards the rebuild lock that is present +// in ShenandoahFreeSet. Whenever both locks are acquired, this lock should be acquired before the +// ShenandoahFreeSet rebuild lock. +class ShenandoahHeapLocker : public StackObj { +private: + ShenandoahHeapLock* _lock; +public: + ShenandoahHeapLocker(ShenandoahHeapLock* lock, bool allow_block_for_safepoint = false); + + ~ShenandoahHeapLocker() { + _lock->unlock(); + } +}; + +typedef Stack ShenandoahScanObjectStack; // Shenandoah GC is low-pause concurrent GC that uses a load reference barrier // for concurent evacuation and a snapshot-at-the-beginning write barrier for diff --git a/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp b/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp index 7eec0b9af64..7e317f53424 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp @@ -93,7 +93,7 @@ ShenandoahSimpleLock::ShenandoahSimpleLock() { assert(os::mutex_init_done(), "Too early!"); } -void ShenandoahSimpleLock::lock() { +void ShenandoahSimpleLock::lock(bool allow_block_for_safepoint) { _lock.lock(); } @@ -101,28 +101,31 @@ void ShenandoahSimpleLock::unlock() { _lock.unlock(); } -ShenandoahReentrantLock::ShenandoahReentrantLock() : - ShenandoahSimpleLock(), _owner(nullptr), _count(0) { - assert(os::mutex_init_done(), "Too early!"); +template +ShenandoahReentrantLock::ShenandoahReentrantLock() : + Lock(), _owner(nullptr), _count(0) { } -ShenandoahReentrantLock::~ShenandoahReentrantLock() { +template +ShenandoahReentrantLock::~ShenandoahReentrantLock() { assert(_count == 0, "Unbalance"); } -void ShenandoahReentrantLock::lock() { +template +void ShenandoahReentrantLock::lock(bool allow_block_for_safepoint) { Thread* const thread = Thread::current(); Thread* const owner = _owner.load_relaxed(); if (owner != thread) { - ShenandoahSimpleLock::lock(); + Lock::lock(allow_block_for_safepoint); _owner.store_relaxed(thread); } _count++; } -void ShenandoahReentrantLock::unlock() { +template +void ShenandoahReentrantLock::unlock() { assert(owned_by_self(), "Invalid owner"); assert(_count > 0, "Invalid count"); @@ -130,12 +133,17 @@ void ShenandoahReentrantLock::unlock() { if (_count == 0) { _owner.store_relaxed((Thread*)nullptr); - ShenandoahSimpleLock::unlock(); + Lock::unlock(); } } -bool ShenandoahReentrantLock::owned_by_self() const { +template +bool ShenandoahReentrantLock::owned_by_self() const { Thread* const thread = Thread::current(); Thread* const owner = _owner.load_relaxed(); return owner == thread; } + +// Explicit template instantiation +template class ShenandoahReentrantLock; +template class ShenandoahReentrantLock; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahLock.hpp b/src/hotspot/share/gc/shenandoah/shenandoahLock.hpp index 2e44810cd5d..7c91df191e5 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahLock.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahLock.hpp @@ -31,7 +31,7 @@ #include "runtime/javaThread.hpp" #include "runtime/safepoint.hpp" -class ShenandoahLock { +class ShenandoahLock { private: enum LockState { unlocked = 0, locked = 1 }; @@ -48,7 +48,7 @@ private: public: ShenandoahLock() : _state(unlocked), _owner(nullptr) {}; - void lock(bool allow_block_for_safepoint) { + void lock(bool allow_block_for_safepoint = false) { assert(_owner.load_relaxed() != Thread::current(), "reentrant locking attempt, would deadlock"); if ((allow_block_for_safepoint && SafepointSynchronize::is_synchronizing()) || @@ -83,34 +83,19 @@ public: } }; -class ShenandoahLocker : public StackObj { -private: - ShenandoahLock* const _lock; -public: - ShenandoahLocker(ShenandoahLock* lock, bool allow_block_for_safepoint = false) : _lock(lock) { - if (_lock != nullptr) { - _lock->lock(allow_block_for_safepoint); - } - } - - ~ShenandoahLocker() { - if (_lock != nullptr) { - _lock->unlock(); - } - } -}; - +// Simple lock using PlatformMonitor class ShenandoahSimpleLock { private: PlatformMonitor _lock; // native lock public: ShenandoahSimpleLock(); - - virtual void lock(); - virtual void unlock(); + void lock(bool allow_block_for_safepoint = false); + void unlock(); }; -class ShenandoahReentrantLock : public ShenandoahSimpleLock { +// templated reentrant lock +template +class ShenandoahReentrantLock : public Lock { private: Atomic _owner; uint64_t _count; @@ -119,30 +104,25 @@ public: ShenandoahReentrantLock(); ~ShenandoahReentrantLock(); - virtual void lock(); - virtual void unlock(); + void lock(bool allow_block_for_safepoint = false); + void unlock(); // If the lock already owned by this thread bool owned_by_self() const ; }; -class ShenandoahReentrantLocker : public StackObj { -private: - ShenandoahReentrantLock* const _lock; - +// template based ShenandoahLocker +template +class ShenandoahLocker : public StackObj { + Lock* const _lock; public: - ShenandoahReentrantLocker(ShenandoahReentrantLock* lock) : - _lock(lock) { - if (_lock != nullptr) { - _lock->lock(); - } + ShenandoahLocker(Lock* lock, bool allow_block_for_safepoint = false) : _lock(lock) { + assert(_lock != nullptr, "Must not"); + _lock->lock(allow_block_for_safepoint); } - ~ShenandoahReentrantLocker() { - if (_lock != nullptr) { - assert(_lock->owned_by_self(), "Must be owner"); - _lock->unlock(); - } + ~ShenandoahLocker() { + _lock->unlock(); } }; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp index facaefd4b62..594ad614d90 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp @@ -241,7 +241,7 @@ void ShenandoahNMethodTable::register_nmethod(nmethod* nm) { assert(nm == data->nm(), "Must be same nmethod"); // Prevent updating a nmethod while concurrent iteration is in progress. wait_until_concurrent_iteration_done(); - ShenandoahReentrantLocker data_locker(data->lock()); + ShenandoahNMethodLocker data_locker(data->lock()); data->update(); } else { // For a new nmethod, we can safely append it to the list, because diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp index 77faf6c0dcb..2686b4f4985 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp @@ -33,6 +33,10 @@ #include "runtime/atomic.hpp" #include "utilities/growableArray.hpp" +// Use ShenandoahReentrantLock as ShenandoahNMethodLock +typedef ShenandoahReentrantLock ShenandoahNMethodLock; +typedef ShenandoahLocker ShenandoahNMethodLocker; + // ShenandoahNMethod tuple records the internal locations of oop slots within reclocation stream in // the nmethod. This allows us to quickly scan the oops without doing the nmethod-internal scans, // that sometimes involves parsing the machine code. Note it does not record the oops themselves, @@ -44,16 +48,16 @@ private: int _oops_count; bool _has_non_immed_oops; bool _unregistered; - ShenandoahReentrantLock _lock; - ShenandoahReentrantLock _ic_lock; + ShenandoahNMethodLock _lock; + ShenandoahNMethodLock _ic_lock; public: ShenandoahNMethod(nmethod *nm, GrowableArray& oops, bool has_non_immed_oops); ~ShenandoahNMethod(); inline nmethod* nm() const; - inline ShenandoahReentrantLock* lock(); - inline ShenandoahReentrantLock* ic_lock(); + inline ShenandoahNMethodLock* lock(); + inline ShenandoahNMethodLock* ic_lock(); inline void oops_do(OopClosure* oops, bool fix_relocations = false); // Update oops when the nmethod is re-registered void update(); @@ -61,8 +65,8 @@ public: inline bool is_unregistered() const; static ShenandoahNMethod* for_nmethod(nmethod* nm); - static inline ShenandoahReentrantLock* lock_for_nmethod(nmethod* nm); - static inline ShenandoahReentrantLock* ic_lock_for_nmethod(nmethod* nm); + static inline ShenandoahNMethodLock* lock_for_nmethod(nmethod* nm); + static inline ShenandoahNMethodLock* ic_lock_for_nmethod(nmethod* nm); static void heal_nmethod(nmethod* nm); static inline void heal_nmethod_metadata(ShenandoahNMethod* nmethod_data); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp index 6758298675b..ef9e347b821 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp @@ -35,11 +35,11 @@ nmethod* ShenandoahNMethod::nm() const { return _nm; } -ShenandoahReentrantLock* ShenandoahNMethod::lock() { +ShenandoahNMethodLock* ShenandoahNMethod::lock() { return &_lock; } -ShenandoahReentrantLock* ShenandoahNMethod::ic_lock() { +ShenandoahNMethodLock* ShenandoahNMethod::ic_lock() { return &_ic_lock; } @@ -85,11 +85,11 @@ void ShenandoahNMethod::attach_gc_data(nmethod* nm, ShenandoahNMethod* gc_data) nm->set_gc_data(gc_data); } -ShenandoahReentrantLock* ShenandoahNMethod::lock_for_nmethod(nmethod* nm) { +ShenandoahNMethodLock* ShenandoahNMethod::lock_for_nmethod(nmethod* nm) { return gc_data(nm)->lock(); } -ShenandoahReentrantLock* ShenandoahNMethod::ic_lock_for_nmethod(nmethod* nm) { +ShenandoahNMethodLock* ShenandoahNMethod::ic_lock_for_nmethod(nmethod* nm) { return gc_data(nm)->ic_lock(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahOldGeneration.cpp b/src/hotspot/share/gc/shenandoah/shenandoahOldGeneration.cpp index d5e34d02b13..4fda65b4030 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahOldGeneration.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahOldGeneration.cpp @@ -583,7 +583,7 @@ void ShenandoahOldGeneration::handle_failed_evacuation() { void ShenandoahOldGeneration::handle_failed_promotion(Thread* thread, size_t size) { _promotion_failure_count.add_then_fetch(1UL); - _promotion_failure_words.and_then_fetch(size); + _promotion_failure_words.add_then_fetch(size); LogTarget(Debug, gc, plab) lt; LogStream ls(lt); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp index b248fab7958..ac7fe1f9a3a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp @@ -80,7 +80,7 @@ public: virtual bool has_dead_oop(nmethod* nm) const { assert(ShenandoahHeap::heap()->is_concurrent_weak_root_in_progress(), "Only for this phase"); ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm); - ShenandoahReentrantLocker locker(data->lock()); + ShenandoahNMethodLocker locker(data->lock()); ShenandoahIsUnloadingOopClosure cl; data->oops_do(&cl); return cl.is_unloading(); @@ -90,14 +90,14 @@ public: class ShenandoahCompiledICProtectionBehaviour : public CompiledICProtectionBehaviour { public: virtual bool lock(nmethod* nm) { - ShenandoahReentrantLock* const lock = ShenandoahNMethod::ic_lock_for_nmethod(nm); + ShenandoahNMethodLock* const lock = ShenandoahNMethod::ic_lock_for_nmethod(nm); assert(lock != nullptr, "Not yet registered?"); lock->lock(); return true; } virtual void unlock(nmethod* nm) { - ShenandoahReentrantLock* const lock = ShenandoahNMethod::ic_lock_for_nmethod(nm); + ShenandoahNMethodLock* const lock = ShenandoahNMethod::ic_lock_for_nmethod(nm); assert(lock != nullptr, "Not yet registered?"); lock->unlock(); } @@ -107,7 +107,7 @@ public: return true; } - ShenandoahReentrantLock* const lock = ShenandoahNMethod::ic_lock_for_nmethod(nm); + ShenandoahNMethodLock* const lock = ShenandoahNMethod::ic_lock_for_nmethod(nm); assert(lock != nullptr, "Not yet registered?"); return lock->owned_by_self(); } diff --git a/src/hotspot/share/interpreter/interpreterRuntime.cpp b/src/hotspot/share/interpreter/interpreterRuntime.cpp index ca7174389cf..e3cf5d589c2 100644 --- a/src/hotspot/share/interpreter/interpreterRuntime.cpp +++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp @@ -711,9 +711,7 @@ void InterpreterRuntime::resolve_get_put(Bytecodes::Code bytecode, int field_ind } ResolvedFieldEntry* entry = pool->resolved_field_entry_at(field_index); - entry->set_flags(info.access_flags().is_final(), info.access_flags().is_volatile()); - entry->fill_in(info.field_holder(), info.offset(), - checked_cast(info.index()), checked_cast(state), + entry->fill_in(info, checked_cast(state), static_cast(get_code), static_cast(put_code)); } @@ -1189,10 +1187,9 @@ JRT_LEAF(void, InterpreterRuntime::at_unwind(JavaThread* current)) JRT_END JRT_ENTRY(void, InterpreterRuntime::post_field_access(JavaThread* current, oopDesc* obj, - ResolvedFieldEntry *entry)) + ResolvedFieldEntry* entry)) // check the access_flags for the field in the klass - InstanceKlass* ik = entry->field_holder(); int index = entry->field_index(); if (!ik->field_status(index).is_access_watched()) return; @@ -1212,11 +1209,10 @@ JRT_ENTRY(void, InterpreterRuntime::post_field_access(JavaThread* current, oopDe JRT_END JRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread* current, oopDesc* obj, - ResolvedFieldEntry *entry, jvalue *value)) - - InstanceKlass* ik = entry->field_holder(); + ResolvedFieldEntry* entry, jvalue* value)) // check the access_flags for the field in the klass + InstanceKlass* ik = entry->field_holder(); int index = entry->field_index(); // bail out if field modifications are not watched if (!ik->field_status(index).is_modification_watched()) return; diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp index 640b2f2460f..456333efad0 100644 --- a/src/hotspot/share/oops/constantPool.cpp +++ b/src/hotspot/share/oops/constantPool.cpp @@ -310,8 +310,9 @@ void ConstantPool::iterate_archivable_resolved_references(Function function) { if (method_entries != nullptr) { for (int i = 0; i < method_entries->length(); i++) { ResolvedMethodEntry* rme = method_entries->adr_at(i); + const char* rejection_reason = nullptr; if (rme->is_resolved(Bytecodes::_invokehandle) && rme->has_appendix() && - cache()->can_archive_resolved_method(this, rme)) { + cache()->can_archive_resolved_method(this, rme, rejection_reason)) { int rr_index = rme->resolved_references_index(); assert(resolved_reference_at(rr_index) != nullptr, "must exist"); function(rr_index); diff --git a/src/hotspot/share/oops/cpCache.cpp b/src/hotspot/share/oops/cpCache.cpp index 75cdcb5310a..34d7aa10299 100644 --- a/src/hotspot/share/oops/cpCache.cpp +++ b/src/hotspot/share/oops/cpCache.cpp @@ -450,12 +450,15 @@ void ConstantPoolCache::remove_resolved_field_entries_if_non_deterministic() { Symbol* klass_name = cp->klass_name_at(klass_cp_index); Symbol* name = cp->uncached_name_ref_at(cp_index); Symbol* signature = cp->uncached_signature_ref_at(cp_index); - log.print("%s field CP entry [%3d]: %s => %s.%s:%s%s", - (archived ? "archived" : "reverted"), - cp_index, - cp->pool_holder()->name()->as_C_string(), - klass_name->as_C_string(), name->as_C_string(), signature->as_C_string(), - rfi->is_resolved(Bytecodes::_getstatic) || rfi->is_resolved(Bytecodes::_putstatic) ? " *** static" : ""); + if (resolved) { + log.print("%s field CP entry [%3d]: %s => %s.%s:%s%s%s", + (archived ? "archived" : "reverted"), + cp_index, + cp->pool_holder()->name()->as_C_string(), + klass_name->as_C_string(), name->as_C_string(), signature->as_C_string(), + rfi->is_resolved(Bytecodes::_getstatic) || rfi->is_resolved(Bytecodes::_putstatic) ? " *** static" : "", + (archived ? "" : " (resolution is not deterministic)")); + } } ArchiveBuilder::alloc_stats()->record_field_cp_entry(archived, resolved && !archived); } @@ -474,32 +477,40 @@ void ConstantPoolCache::remove_resolved_method_entries_if_non_deterministic() { rme->is_resolved(Bytecodes::_invokehandle) || (rme->is_resolved(Bytecodes::_invokestatic) && VM_Version::supports_fast_class_init_checks()); + const char* rejection_reason = nullptr; if (resolved && !CDSConfig::is_dumping_preimage_static_archive() - && can_archive_resolved_method(src_cp, rme)) { + && can_archive_resolved_method(src_cp, rme, rejection_reason)) { rme->mark_and_relocate(src_cp); archived = true; } else { rme->remove_unshareable_info(); } - LogStreamHandle(Trace, aot, resolve) log; - if (log.is_enabled()) { + LogTarget(Trace, aot, resolve) lt; + if (lt.is_enabled()) { ResourceMark rm; int klass_cp_index = cp->uncached_klass_ref_index_at(cp_index); Symbol* klass_name = cp->klass_name_at(klass_cp_index); Symbol* name = cp->uncached_name_ref_at(cp_index); Symbol* signature = cp->uncached_signature_ref_at(cp_index); - log.print("%s%s method CP entry [%3d]: %s %s.%s:%s", + LogStream ls(lt); + if (resolved) { + ls.print("%s%s method CP entry [%3d]: %s %s.%s:%s", (archived ? "archived" : "reverted"), (rme->is_resolved(Bytecodes::_invokeinterface) ? " interface" : ""), cp_index, cp->pool_holder()->name()->as_C_string(), klass_name->as_C_string(), name->as_C_string(), signature->as_C_string()); + if (rejection_reason != nullptr) { + ls.print(" %s", rejection_reason); + } + } if (archived) { Klass* resolved_klass = cp->resolved_klass_at(klass_cp_index); - log.print(" => %s%s", + ls.print(" => %s%s", resolved_klass->name()->as_C_string(), (rme->is_resolved(Bytecodes::_invokestatic) ? " *** static" : "")); } + ls.cr(); } ArchiveBuilder::alloc_stats()->record_method_cp_entry(archived, resolved && !archived); } @@ -528,42 +539,50 @@ void ConstantPoolCache::remove_resolved_indy_entries_if_non_deterministic() { Symbol* bsm_name = cp->uncached_name_ref_at(bsm_ref); Symbol* bsm_signature = cp->uncached_signature_ref_at(bsm_ref); Symbol* bsm_klass = cp->klass_name_at(cp->uncached_klass_ref_index_at(bsm_ref)); - log.print("%s indy CP entry [%3d]: %s (%d)", - (archived ? "archived" : "reverted"), - cp_index, cp->pool_holder()->name()->as_C_string(), i); - log.print(" %s %s.%s:%s", (archived ? "=>" : " "), bsm_klass->as_C_string(), - bsm_name->as_C_string(), bsm_signature->as_C_string()); + if (resolved) { + log.print("%s indy CP entry [%3d]: %s (%d)", + (archived ? "archived" : "reverted"), + cp_index, cp->pool_holder()->name()->as_C_string(), i); + log.print(" %s %s.%s:%s%s", (archived ? "=>" : " "), bsm_klass->as_C_string(), + bsm_name->as_C_string(), bsm_signature->as_C_string(), + (archived ? "" : " (resolution is not deterministic)")); + } } ArchiveBuilder::alloc_stats()->record_indy_cp_entry(archived, resolved && !archived); } } -bool ConstantPoolCache::can_archive_resolved_method(ConstantPool* src_cp, ResolvedMethodEntry* method_entry) { - LogStreamHandle(Trace, aot, resolve) log; +bool ConstantPoolCache::can_archive_resolved_method(ConstantPool* src_cp, ResolvedMethodEntry* method_entry, const char*& rejection_reason) { InstanceKlass* pool_holder = constant_pool()->pool_holder(); if (pool_holder->defined_by_other_loaders()) { // Archiving resolved cp entries for classes from non-builtin loaders // is not yet supported. + rejection_reason = "(pool holder comes from a non-builtin loader)"; return false; } if (CDSConfig::is_dumping_dynamic_archive()) { // InstanceKlass::methods() has been resorted. We need to // update the vtable_index in method_entry (not implemented) + rejection_reason = "(InstanceKlass::methods() has been resorted)"; return false; } if (!method_entry->is_resolved(Bytecodes::_invokevirtual)) { if (method_entry->method() == nullptr) { + rejection_reason = "(method entry is not resolved)"; return false; } if (method_entry->method()->is_continuation_native_intrinsic()) { + rejection_reason = "(corresponding stub is generated on demand during method resolution)"; return false; // FIXME: corresponding stub is generated on demand during method resolution (see LinkResolver::resolve_static_call). } if (method_entry->is_resolved(Bytecodes::_invokehandle) && !CDSConfig::is_dumping_method_handles()) { + rejection_reason = "(not dumping method handles)"; return false; } if (method_entry->method()->is_method_handle_intrinsic() && !CDSConfig::is_dumping_method_handles()) { + rejection_reason = "(not dumping intrinsic method handles)"; return false; } } @@ -572,6 +591,7 @@ bool ConstantPoolCache::can_archive_resolved_method(ConstantPool* src_cp, Resolv assert(src_cp->tag_at(cp_index).is_method() || src_cp->tag_at(cp_index).is_interface_method(), "sanity"); if (!AOTConstantPoolResolver::is_resolution_deterministic(src_cp, cp_index)) { + rejection_reason = "(resolution is not deterministic)"; return false; } return true; diff --git a/src/hotspot/share/oops/cpCache.hpp b/src/hotspot/share/oops/cpCache.hpp index e9e4f9a40e5..f698f50d3a8 100644 --- a/src/hotspot/share/oops/cpCache.hpp +++ b/src/hotspot/share/oops/cpCache.hpp @@ -196,7 +196,7 @@ class ConstantPoolCache: public MetaspaceObj { #endif public: - static int size() { return align_metadata_size(sizeof(ConstantPoolCache) / wordSize); } + static int size() { return align_metadata_size(sizeof_auto(ConstantPoolCache) / wordSize); } private: // Helpers @@ -226,7 +226,7 @@ class ConstantPoolCache: public MetaspaceObj { void remove_resolved_field_entries_if_non_deterministic(); void remove_resolved_indy_entries_if_non_deterministic(); void remove_resolved_method_entries_if_non_deterministic(); - bool can_archive_resolved_method(ConstantPool* src_cp, ResolvedMethodEntry* method_entry); + bool can_archive_resolved_method(ConstantPool* src_cp, ResolvedMethodEntry* method_entry, const char*& rejection_reason); #endif // RedefineClasses support diff --git a/src/hotspot/share/oops/resolvedFieldEntry.cpp b/src/hotspot/share/oops/resolvedFieldEntry.cpp index 83f1a6919a6..49e9115ca9a 100644 --- a/src/hotspot/share/oops/resolvedFieldEntry.cpp +++ b/src/hotspot/share/oops/resolvedFieldEntry.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * 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,12 @@ #include "cds/archiveBuilder.hpp" #include "cppstdlib/type_traits.hpp" +#include "oops/instanceKlass.hpp" +#include "oops/instanceOop.hpp" #include "oops/resolvedFieldEntry.hpp" +#include "runtime/fieldDescriptor.inline.hpp" +#include "utilities/checkedCast.hpp" +#include "utilities/globalDefinitions.hpp" static_assert(std::is_trivially_copyable_v); @@ -34,6 +39,19 @@ class ResolvedFieldEntryWithExtra : public ResolvedFieldEntry { }; static_assert(sizeof(ResolvedFieldEntryWithExtra) > sizeof(ResolvedFieldEntry)); +void ResolvedFieldEntry::fill_in(const fieldDescriptor& info, u1 tos_state, u1 get_code, u1 put_code) { + set_flags(info.access_flags().is_final(), info.access_flags().is_volatile()); + _field_holder = info.field_holder(); + _field_offset = info.offset(); + _field_index = checked_cast(info.index()); + _tos_state = tos_state; + + // These must be set after the other fields + set_bytecode(&_get_code, get_code); + set_bytecode(&_put_code, put_code); + assert_is_valid(); +} + void ResolvedFieldEntry::print_on(outputStream* st) const { st->print_cr("Field Entry:"); @@ -52,6 +70,20 @@ void ResolvedFieldEntry::print_on(outputStream* st) const { st->print_cr(" - Put Bytecode: %s", Bytecodes::name((Bytecodes::Code)put_code())); } +#ifdef ASSERT +void ResolvedFieldEntry::assert_is_valid() const { + assert(field_holder()->is_instance_klass(), "should be instanceKlass"); + assert(field_offset() >= instanceOopDesc::base_offset_in_bytes(), + "field offset out of range %d >= %d", field_offset(), instanceOopDesc::base_offset_in_bytes()); + assert(as_BasicType((TosState)tos_state()) != T_ILLEGAL, "tos_state is ILLEGAL"); + assert(_flags < (1 << (max_flag_shift + 1)), "flags are too large %d", _flags); + assert((get_code() == 0 || get_code() == Bytecodes::_getstatic || get_code() == Bytecodes::_getfield), + "invalid get bytecode %d", get_code()); + assert((put_code() == 0 || put_code() == Bytecodes::_putstatic || put_code() == Bytecodes::_putfield), + "invalid put bytecode %d", put_code()); +} +#endif + #if INCLUDE_CDS void ResolvedFieldEntry::remove_unshareable_info() { *this = ResolvedFieldEntry(_cpool_index); diff --git a/src/hotspot/share/oops/resolvedFieldEntry.hpp b/src/hotspot/share/oops/resolvedFieldEntry.hpp index 77ad4815730..bdd9999dd63 100644 --- a/src/hotspot/share/oops/resolvedFieldEntry.hpp +++ b/src/hotspot/share/oops/resolvedFieldEntry.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +26,6 @@ #define SHARE_OOPS_RESOLVEDFIELDENTRY_HPP #include "interpreter/bytecodes.hpp" -#include "oops/instanceKlass.hpp" #include "runtime/atomicAccess.hpp" #include "utilities/checkedCast.hpp" #include "utilities/sizes.hpp" @@ -46,7 +45,8 @@ // The explicit paddings are necessary for generating deterministic CDS archives. They prevent // the C++ compiler from potentially inserting random values in unused gaps. -//class InstanceKlass; +class InstanceKlass; + class ResolvedFieldEntry { friend class VMStructs; @@ -84,6 +84,7 @@ public: enum { is_volatile_shift = 0, is_final_shift = 1, // unused + max_flag_shift = is_final_shift }; // Getters @@ -113,6 +114,7 @@ public: // Printing void print_on(outputStream* st) const; + private: void set_flags(bool is_final_flag, bool is_volatile_flag) { int new_flags = (is_final_flag << is_final_shift) | static_cast(is_volatile_flag); _flags = checked_cast(new_flags); @@ -129,17 +131,12 @@ public: AtomicAccess::release_store(code, new_code); } - // Populate the strucutre with resolution information - void fill_in(InstanceKlass* klass, int offset, u2 index, u1 tos_state, u1 b1, u1 b2) { - _field_holder = klass; - _field_offset = offset; - _field_index = index; - _tos_state = tos_state; + // Debug help + void assert_is_valid() const NOT_DEBUG_RETURN; - // These must be set after the other fields - set_bytecode(&_get_code, b1); - set_bytecode(&_put_code, b2); - } + public: + // Populate the strucutre with resolution information + void fill_in(const fieldDescriptor& info, u1 tos_state, u1 get_code, u1 put_code); // CDS #if INCLUDE_CDS @@ -155,7 +152,6 @@ public: static ByteSize put_code_offset() { return byte_offset_of(ResolvedFieldEntry, _put_code); } static ByteSize type_offset() { return byte_offset_of(ResolvedFieldEntry, _tos_state); } static ByteSize flags_offset() { return byte_offset_of(ResolvedFieldEntry, _flags); } - }; #endif //SHARE_OOPS_RESOLVEDFIELDENTRY_HPP diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp index 084b137f313..c969abb85bb 100644 --- a/src/hotspot/share/opto/graphKit.cpp +++ b/src/hotspot/share/opto/graphKit.cpp @@ -1177,7 +1177,21 @@ bool GraphKit::compute_stack_effects(int& inputs, int& depth) { //------------------------------basic_plus_adr--------------------------------- Node* GraphKit::basic_plus_adr(Node* base, Node* ptr, Node* offset) { // short-circuit a common case - if (offset == intcon(0)) return ptr; + if (offset == MakeConX(0)) { + return ptr; + } +#ifdef ASSERT + // Both 32-bit and 64-bit zeros should have been handled by the previous `if` + // statement, so if we see either 32-bit or 64-bit zeros here, then we have a + // problem. + if (offset->is_Con()) { + const Type* t = offset->bottom_type(); + bool is_zero_int = t->isa_int() && t->is_int()->get_con() == 0; + bool is_zero_long = t->isa_long() && t->is_long()->get_con() == 0; + assert(!is_zero_int && !is_zero_long, + "Unexpected zero offset - should have matched MakeConX(0)"); + } +#endif return _gvn.transform( new AddPNode(base, ptr, offset) ); } diff --git a/src/hotspot/share/opto/idealKit.cpp b/src/hotspot/share/opto/idealKit.cpp index dd7e9ae52b7..fbb61bfdf72 100644 --- a/src/hotspot/share/opto/idealKit.cpp +++ b/src/hotspot/share/opto/idealKit.cpp @@ -360,6 +360,17 @@ Node* IdealKit::load(Node* ctl, return transform(ld); } +// Load AOT runtime constant +Node* IdealKit::load_aot_const(Node* adr, const Type* t) { + BasicType bt = t->basic_type(); + const TypePtr* adr_type = nullptr; // debug-mode-only argument + DEBUG_ONLY(adr_type = C->get_adr_type(Compile::AliasIdxRaw)); + Node* ctl = (Node*)C->root(); // Raw memory access needs control + Node* ld = LoadNode::make(_gvn, ctl, C->immutable_memory(), adr, adr_type, t, bt, MemNode::unordered, + LoadNode::DependsOnlyOnTest, false, false, false, false, 0); + return transform(ld); +} + Node* IdealKit::store(Node* ctl, Node* adr, Node *val, BasicType bt, int adr_idx, MemNode::MemOrd mo, bool require_atomic_access, diff --git a/src/hotspot/share/opto/idealKit.hpp b/src/hotspot/share/opto/idealKit.hpp index 280f61fd9a9..518c3b92136 100644 --- a/src/hotspot/share/opto/idealKit.hpp +++ b/src/hotspot/share/opto/idealKit.hpp @@ -224,6 +224,9 @@ class IdealKit: public StackObj { MemNode::MemOrd mo = MemNode::unordered, LoadNode::ControlDependency control_dependency = LoadNode::DependsOnlyOnTest); + // Load AOT runtime constant + Node* load_aot_const(Node* adr, const Type* t); + // Return the new StoreXNode Node* store(Node* ctl, Node* adr, diff --git a/src/hotspot/share/opto/subnode.hpp b/src/hotspot/share/opto/subnode.hpp index a90661c49ee..54cb1d20cd0 100644 --- a/src/hotspot/share/opto/subnode.hpp +++ b/src/hotspot/share/opto/subnode.hpp @@ -564,6 +564,9 @@ public: const Type* bottom_type() const { return Type::HALF_FLOAT; } virtual uint ideal_reg() const { return Op_RegF; } virtual const Type* Value(PhaseGVN* phase) const; + +private: + virtual bool depends_only_on_test_impl() const { return false; } }; diff --git a/src/hotspot/share/opto/type.cpp b/src/hotspot/share/opto/type.cpp index c637737eef9..1a0872ee0e6 100644 --- a/src/hotspot/share/opto/type.cpp +++ b/src/hotspot/share/opto/type.cpp @@ -97,7 +97,7 @@ const Type::TypeInfo Type::_type_info[Type::lastype] = { { Bad, T_ILLEGAL, "vectorz:", false, Op_VecZ, relocInfo::none }, // VectorZ #endif { Bad, T_ADDRESS, "anyptr:", false, Op_RegP, relocInfo::none }, // AnyPtr - { Bad, T_ADDRESS, "rawptr:", false, Op_RegP, relocInfo::none }, // RawPtr + { Bad, T_ADDRESS, "rawptr:", false, Op_RegP, relocInfo::external_word_type }, // RawPtr { Bad, T_OBJECT, "oop:", true, Op_RegP, relocInfo::oop_type }, // OopPtr { Bad, T_OBJECT, "inst:", true, Op_RegP, relocInfo::oop_type }, // InstPtr { Bad, T_OBJECT, "ary:", true, Op_RegP, relocInfo::oop_type }, // AryPtr diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 2b3a2966c27..423e1a5a1f4 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -3641,7 +3641,9 @@ JVM_ENTRY(jobjectArray, JVM_GetVmArguments(JNIEnv *env)) int index = 0; for (int j = 0; j < num_flags; j++, index++) { - Handle h = java_lang_String::create_from_platform_dependent_str(vm_flags[j], CHECK_NULL); + stringStream prefixed; + prefixed.print("-XX:%s", vm_flags[j]); + Handle h = java_lang_String::create_from_platform_dependent_str(prefixed.base(), CHECK_NULL); result_h->obj_at_put(index, h()); } for (int i = 0; i < num_args; i++, index++) { diff --git a/src/hotspot/share/prims/jvmtiEnvBase.cpp b/src/hotspot/share/prims/jvmtiEnvBase.cpp index 4894a4dd21a..401bb4dfdb8 100644 --- a/src/hotspot/share/prims/jvmtiEnvBase.cpp +++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2491,7 +2491,7 @@ SetOrClearFramePopClosure::do_thread(Thread *target) { _result = JVMTI_ERROR_NO_MORE_FRAMES; return; } - assert(_state->get_thread_or_saved() == java_thread, "Must be"); + assert(_state->get_thread() == java_thread, "Must be"); RegisterMap reg_map(java_thread, RegisterMap::UpdateMap::include, diff --git a/src/hotspot/share/prims/jvmtiEnvThreadState.cpp b/src/hotspot/share/prims/jvmtiEnvThreadState.cpp index 571c4ca5528..303923076b1 100644 --- a/src/hotspot/share/prims/jvmtiEnvThreadState.cpp +++ b/src/hotspot/share/prims/jvmtiEnvThreadState.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -151,11 +151,6 @@ bool JvmtiEnvThreadState::is_virtual() { return _state->is_virtual(); } -// Use _thread_saved if cthread is detached from JavaThread (_thread == nullptr). -JavaThread* JvmtiEnvThreadState::get_thread_or_saved() { - return _state->get_thread_or_saved(); -} - JavaThread* JvmtiEnvThreadState::get_thread() { return _state->get_thread(); } @@ -344,7 +339,7 @@ void JvmtiEnvThreadState::reset_current_location(jvmtiEvent event_type, bool ena if (enabled) { // If enabling breakpoint, no need to reset. // Can't do anything if empty stack. - JavaThread* thread = get_thread_or_saved(); + JavaThread* thread = get_thread(); if (event_type == JVMTI_EVENT_SINGLE_STEP && ((thread == nullptr && is_virtual()) || thread->has_last_Java_frame())) { diff --git a/src/hotspot/share/prims/jvmtiEnvThreadState.hpp b/src/hotspot/share/prims/jvmtiEnvThreadState.hpp index a2ab25a59dd..16b369e0857 100644 --- a/src/hotspot/share/prims/jvmtiEnvThreadState.hpp +++ b/src/hotspot/share/prims/jvmtiEnvThreadState.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -170,8 +170,6 @@ public: inline JvmtiThreadState* jvmti_thread_state() { return _state; } - // use _thread_saved if cthread is detached from JavaThread - JavaThread *get_thread_or_saved(); JavaThread *get_thread(); inline JvmtiEnv *get_env() { return _env; } diff --git a/src/hotspot/share/prims/jvmtiEventController.cpp b/src/hotspot/share/prims/jvmtiEventController.cpp index 9df3bbb4b3e..cb44b833c48 100644 --- a/src/hotspot/share/prims/jvmtiEventController.cpp +++ b/src/hotspot/share/prims/jvmtiEventController.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -217,6 +217,10 @@ class EnterInterpOnlyModeClosure : public HandshakeClosure { assert(state != nullptr, "sanity check"); assert(state->get_thread() == jt, "handshake unsafe conditions"); + assert(jt->jvmti_thread_state() == state, "sanity check"); + assert(!jt->is_interp_only_mode(), "sanity check"); + assert(!state->is_interp_only_mode(), "sanity check"); + if (!state->is_pending_interp_only_mode()) { _completed = true; return; // The pending flag has been already cleared, so bail out. @@ -361,7 +365,8 @@ void VM_ChangeSingleStep::doit() { void JvmtiEventControllerPrivate::enter_interp_only_mode(JvmtiThreadState *state) { EC_TRACE(("[%s] # Entering interpreter only mode", - JvmtiTrace::safe_get_thread_name(state->get_thread_or_saved()))); + JvmtiTrace::safe_get_thread_name(state->get_thread()))); + JavaThread *target = state->get_thread(); Thread *current = Thread::current(); @@ -371,8 +376,13 @@ void JvmtiEventControllerPrivate::enter_interp_only_mode(JvmtiThreadState *state } // This flag will be cleared in EnterInterpOnlyModeClosure handshake. state->set_pending_interp_only_mode(true); - if (target == nullptr) { // an unmounted virtual thread - return; // EnterInterpOnlyModeClosure will be executed right after mount. + + // There are two cases when entering interp_only_mode is postponed: + // 1. Unmounted virtual thread - EnterInterpOnlyModeClosure::do_thread will be executed at mount; + // 2. Carrier thread with mounted virtual thread - EnterInterpOnlyModeClosure::do_thread will be executed at unmount. + if (target == nullptr || // an unmounted virtual thread + JvmtiEnvBase::is_thread_carrying_vthread(target, state->get_thread_oop())) { // a vthread carrying thread + return; // EnterInterpOnlyModeClosure will be executed right after mount or unmount. } EnterInterpOnlyModeClosure hs(state); if (target->is_handshake_safe_for(current)) { @@ -388,7 +398,8 @@ void JvmtiEventControllerPrivate::enter_interp_only_mode(JvmtiThreadState *state void JvmtiEventControllerPrivate::leave_interp_only_mode(JvmtiThreadState *state) { EC_TRACE(("[%s] # Leaving interpreter only mode", - JvmtiTrace::safe_get_thread_name(state->get_thread_or_saved()))); + JvmtiTrace::safe_get_thread_name(state->get_thread()))); + if (state->is_pending_interp_only_mode()) { state->set_pending_interp_only_mode(false); // Just clear the pending flag. assert(!state->is_interp_only_mode(), "sanity check"); @@ -409,7 +420,7 @@ JvmtiEventControllerPrivate::trace_changed(JvmtiThreadState *state, jlong now_en if (changed & bit) { // it changed, print it log_trace(jvmti)("[%s] # %s event %s", - JvmtiTrace::safe_get_thread_name(state->get_thread_or_saved()), + JvmtiTrace::safe_get_thread_name(state->get_thread()), (now_enabled & bit)? "Enabling" : "Disabling", JvmtiTrace::event_name((jvmtiEvent)ei)); } } @@ -932,7 +943,7 @@ JvmtiEventControllerPrivate::set_user_enabled(JvmtiEnvBase *env, JavaThread *thr void JvmtiEventControllerPrivate::set_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) { EC_TRACE(("[%s] # set frame pop - frame=%d", - JvmtiTrace::safe_get_thread_name(ets->get_thread_or_saved()), + JvmtiTrace::safe_get_thread_name(ets->get_thread()), fpop.frame_number() )); ets->get_frame_pops()->set(fpop); @@ -943,7 +954,7 @@ JvmtiEventControllerPrivate::set_frame_pop(JvmtiEnvThreadState *ets, JvmtiFrameP void JvmtiEventControllerPrivate::clear_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) { EC_TRACE(("[%s] # clear frame pop - frame=%d", - JvmtiTrace::safe_get_thread_name(ets->get_thread_or_saved()), + JvmtiTrace::safe_get_thread_name(ets->get_thread()), fpop.frame_number() )); ets->get_frame_pops()->clear(fpop); @@ -953,7 +964,7 @@ JvmtiEventControllerPrivate::clear_frame_pop(JvmtiEnvThreadState *ets, JvmtiFram void JvmtiEventControllerPrivate::clear_all_frame_pops(JvmtiEnvThreadState *ets) { EC_TRACE(("[%s] # clear all frame pops", - JvmtiTrace::safe_get_thread_name(ets->get_thread_or_saved()) + JvmtiTrace::safe_get_thread_name(ets->get_thread()) )); ets->get_frame_pops()->clear_all(); @@ -965,7 +976,7 @@ JvmtiEventControllerPrivate::clear_to_frame_pop(JvmtiEnvThreadState *ets, JvmtiF int cleared_cnt = ets->get_frame_pops()->clear_to(fpop); EC_TRACE(("[%s] # clear to frame pop - frame=%d, count=%d", - JvmtiTrace::safe_get_thread_name(ets->get_thread_or_saved()), + JvmtiTrace::safe_get_thread_name(ets->get_thread()), fpop.frame_number(), cleared_cnt )); diff --git a/src/hotspot/share/prims/jvmtiThreadState.cpp b/src/hotspot/share/prims/jvmtiThreadState.cpp index d7accfd9a0a..32bf2c4e98e 100644 --- a/src/hotspot/share/prims/jvmtiThreadState.cpp +++ b/src/hotspot/share/prims/jvmtiThreadState.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * 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,6 @@ JvmtiThreadState::JvmtiThreadState(JavaThread* thread, oop thread_oop) : _thread_event_enable() { assert(JvmtiThreadState_lock->is_locked(), "sanity check"); _thread = thread; - _thread_saved = nullptr; _exception_state = ES_CLEARED; _hide_single_stepping = false; _pending_interp_only_mode = false; @@ -118,11 +117,11 @@ JvmtiThreadState::JvmtiThreadState(JavaThread* thread, oop thread_oop) if (thread != nullptr) { if (thread_oop == nullptr || thread->jvmti_vthread() == nullptr || thread->jvmti_vthread() == thread_oop) { - // The JavaThread for carrier or mounted virtual thread case. + // The JavaThread for an active carrier or a mounted virtual thread case. // Set this only if thread_oop is current thread->jvmti_vthread(). thread->set_jvmti_thread_state(this); + assert(!thread->is_interp_only_mode(), "sanity check"); } - thread->set_interp_only_mode(false); } } @@ -135,7 +134,10 @@ JvmtiThreadState::~JvmtiThreadState() { } // clear this as the state for the thread + assert(get_thread() != nullptr, "sanity check"); + assert(get_thread()->jvmti_thread_state() == this, "sanity check"); get_thread()->set_jvmti_thread_state(nullptr); + get_thread()->set_interp_only_mode(false); // zap our env thread states { @@ -323,6 +325,9 @@ void JvmtiThreadState::enter_interp_only_mode() { assert(_thread != nullptr, "sanity check"); assert(JvmtiThreadState_lock->is_locked(), "sanity check"); assert(!is_interp_only_mode(), "entering interp only when in interp only mode"); + assert(_thread->jvmti_vthread() == nullptr || _thread->jvmti_vthread() == get_thread_oop(), "sanity check"); + assert(_thread->jvmti_thread_state() == this, "sanity check"); + _saved_interp_only_mode = true; _thread->set_interp_only_mode(true); invalidate_cur_stack_depth(); } @@ -330,10 +335,9 @@ void JvmtiThreadState::enter_interp_only_mode() { void JvmtiThreadState::leave_interp_only_mode() { assert(JvmtiThreadState_lock->is_locked(), "sanity check"); assert(is_interp_only_mode(), "leaving interp only when not in interp only mode"); - if (_thread == nullptr) { - // Unmounted virtual thread updates the saved value. - _saved_interp_only_mode = false; - } else { + _saved_interp_only_mode = false; + if (_thread != nullptr && _thread->jvmti_thread_state() == this) { + assert(_thread->jvmti_vthread() == nullptr || _thread->jvmti_vthread() == get_thread_oop(), "sanity check"); _thread->set_interp_only_mode(false); } } @@ -341,7 +345,7 @@ void JvmtiThreadState::leave_interp_only_mode() { // Helper routine used in several places int JvmtiThreadState::count_frames() { - JavaThread* thread = get_thread_or_saved(); + JavaThread* thread = get_thread(); javaVFrame *jvf; ResourceMark rm; if (thread == nullptr) { @@ -578,11 +582,8 @@ void JvmtiThreadState::update_thread_oop_during_vm_start() { } } +// For virtual threads only. void JvmtiThreadState::set_thread(JavaThread* thread) { - _thread_saved = nullptr; // Common case. - if (!_is_virtual && thread == nullptr) { - // Save JavaThread* if carrier thread is being detached. - _thread_saved = _thread; - } + assert(is_virtual(), "sanity check"); _thread = thread; } diff --git a/src/hotspot/share/prims/jvmtiThreadState.hpp b/src/hotspot/share/prims/jvmtiThreadState.hpp index 866d8828c4c..fa77518a8b6 100644 --- a/src/hotspot/share/prims/jvmtiThreadState.hpp +++ b/src/hotspot/share/prims/jvmtiThreadState.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -123,8 +123,11 @@ class JvmtiVTSuspender : AllStatic { class JvmtiThreadState : public CHeapObj { private: friend class JvmtiEnv; + // The _thread field is a link to the JavaThread associated with JvmtiThreadState. + // A platform (including carrier) thread should always have a stable link to its JavaThread. + // The _thread field of a virtual thread should point to the JavaThread when + // virtual thread is mounted. It should be set to null when it is unmounted. JavaThread *_thread; - JavaThread *_thread_saved; OopHandle _thread_oop_h; // Jvmti Events that cannot be posted in their current context. JvmtiDeferredEventQueue* _jvmti_event_queue; @@ -219,7 +222,7 @@ class JvmtiThreadState : public CHeapObj { // Used by the interpreter for fullspeed debugging support bool is_interp_only_mode() { - return _thread == nullptr ? _saved_interp_only_mode : _thread->is_interp_only_mode(); + return _saved_interp_only_mode; } void enter_interp_only_mode(); void leave_interp_only_mode(); @@ -248,8 +251,10 @@ class JvmtiThreadState : public CHeapObj { int count_frames(); - inline JavaThread *get_thread() { return _thread; } - inline JavaThread *get_thread_or_saved(); // return _thread_saved if _thread is null + inline JavaThread *get_thread() { + assert(is_virtual() || _thread != nullptr, "sanity check"); + return _thread; + } // Needed for virtual threads as they can migrate to different JavaThread's. // Also used for carrier threads to clear/restore _thread. diff --git a/src/hotspot/share/prims/jvmtiThreadState.inline.hpp b/src/hotspot/share/prims/jvmtiThreadState.inline.hpp index 831a2369a7e..aa81463a696 100644 --- a/src/hotspot/share/prims/jvmtiThreadState.inline.hpp +++ b/src/hotspot/share/prims/jvmtiThreadState.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -130,22 +130,21 @@ inline JvmtiThreadState* JvmtiThreadState::state_for(JavaThread *thread, Handle return state; } -inline JavaThread* JvmtiThreadState::get_thread_or_saved() { - // Use _thread_saved if cthread is detached from JavaThread (_thread == null). - return (_thread == nullptr && !is_virtual()) ? _thread_saved : _thread; -} - inline void JvmtiThreadState::set_should_post_on_exceptions(bool val) { - get_thread_or_saved()->set_should_post_on_exceptions_flag(val ? JNI_TRUE : JNI_FALSE); + get_thread()->set_should_post_on_exceptions_flag(val ? JNI_TRUE : JNI_FALSE); } inline void JvmtiThreadState::unbind_from(JvmtiThreadState* state, JavaThread* thread) { if (state == nullptr) { + assert(!thread->is_interp_only_mode(), "sanity check"); return; } - // Save thread's interp_only_mode. - state->_saved_interp_only_mode = thread->is_interp_only_mode(); - state->set_thread(nullptr); // Make sure stale _thread value is never used. + assert(thread->jvmti_thread_state() == state, "sanity check"); + assert(state->get_thread() == thread, "sanity check"); + assert(thread->is_interp_only_mode() == state->_saved_interp_only_mode, "sanity check"); + if (state->is_virtual()) { // clean _thread link for virtual threads only + state->set_thread(nullptr); // make sure stale _thread value is never used + } } inline void JvmtiThreadState::bind_to(JvmtiThreadState* state, JavaThread* thread) { @@ -158,7 +157,7 @@ inline void JvmtiThreadState::bind_to(JvmtiThreadState* state, JavaThread* threa // Bind JavaThread to JvmtiThreadState. thread->set_jvmti_thread_state(state); - if (state != nullptr) { + if (state != nullptr && state->is_virtual()) { // Bind to JavaThread. state->set_thread(thread); } diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp index ea4f6f99ae6..9560d863a2c 100644 --- a/src/hotspot/share/utilities/globalDefinitions.hpp +++ b/src/hotspot/share/utilities/globalDefinitions.hpp @@ -168,6 +168,29 @@ class oopDesc; #define SIZE_FORMAT_X_0 "0x%08" PRIxPTR #endif // _LP64 + +template +constexpr auto sizeof_auto_impl() { + if constexpr (N <= std::numeric_limits::max()) return uint8_t(N); + else if constexpr (N <= std::numeric_limits::max()) return uint16_t(N); + else if constexpr (N <= std::numeric_limits::max()) return uint32_t(N); + else return uint64_t(N); +} + +// Yields the size (in bytes) of the operand, using the smallest +// unsigned type that can represent the size value. The operand may be +// an expression, which is an unevaluated operand, or it may be a +// type. All of the restrictions for sizeof operands apply to the +// operand. The result is a constant expression. +// +// Example of correct usage of sizeof/sizeof_auto: +// // this will wrap using sizeof_auto, use sizeof to ensure computation using size_t +// size_t size = std::numeric_limits::max() * sizeof(uint16_t); +// // implicit narrowing conversion or compiler warning/error using stricter compiler flags when using sizeof +// int count = 42 / sizeof_auto(uint16_t); + +#define sizeof_auto(...) sizeof_auto_impl() + // Convert pointer to intptr_t, for use in printing pointers. inline intptr_t p2i(const volatile void* p) { return (intptr_t) p; diff --git a/src/java.base/share/classes/java/lang/runtime/ObjectMethods.java b/src/java.base/share/classes/java/lang/runtime/ObjectMethods.java index 18aa6f29f1f..e4b2886404f 100644 --- a/src/java.base/share/classes/java/lang/runtime/ObjectMethods.java +++ b/src/java.base/share/classes/java/lang/runtime/ObjectMethods.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -363,9 +363,9 @@ public final class ObjectMethods { * @return the method handle */ private static MethodHandle makeToString(MethodHandles.Lookup lookup, - Class receiverClass, - MethodHandle[] getters, - List names) { + Class receiverClass, + MethodHandle[] getters, + List names) { assert getters.length == names.size(); if (getters.length == 0) { // special case @@ -516,8 +516,8 @@ public final class ObjectMethods { requireNonNull(type); requireNonNull(recordClass); requireNonNull(names); - requireNonNull(getters); - Arrays.stream(getters).forEach(Objects::requireNonNull); + List getterList = List.of(getters); // deep null check + MethodType methodType; if (type instanceof MethodType mt) methodType = mt; @@ -526,7 +526,14 @@ public final class ObjectMethods { if (!MethodHandle.class.equals(type)) throw new IllegalArgumentException(type.toString()); } - List getterList = List.of(getters); + + for (MethodHandle getter : getterList) { + var getterType = getter.type(); + if (getterType.parameterCount() != 1 || getterType.returnType() == void.class || getterType.parameterType(0) != recordClass) { + throw new IllegalArgumentException("Illegal getter type %s for recordClass %s".formatted(getterType, recordClass.getTypeName())); + } + } + MethodHandle handle = switch (methodName) { case "equals" -> { if (methodType != null && !methodType.equals(MethodType.methodType(boolean.class, recordClass, Object.class))) @@ -541,7 +548,7 @@ public final class ObjectMethods { case "toString" -> { if (methodType != null && !methodType.equals(MethodType.methodType(String.class, recordClass))) throw new IllegalArgumentException("Bad method type: " + methodType); - List nameList = "".equals(names) ? List.of() : List.of(names.split(";")); + List nameList = names.isEmpty() ? List.of() : List.of(names.split(";")); if (nameList.size() != getterList.size()) throw new IllegalArgumentException("Name list and accessor list do not match"); yield makeToString(lookup, recordClass, getters, nameList); 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 43a3b37b7d0..140d76c8c91 100644 --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -1719,8 +1719,10 @@ public class ZipFile implements ZipConstants, Closeable { this.cen = null; return; // only END header present } - if (end.cenlen > end.endpos) + // Validate END header + if (end.cenlen > end.endpos) { zerror("invalid END header (bad central directory size)"); + } long cenpos = end.endpos - end.cenlen; // position of CEN table // Get position of first local file (LOC) header, taking into // account that there may be a stub prefixed to the ZIP file. @@ -1728,18 +1730,22 @@ public class ZipFile implements ZipConstants, Closeable { if (locpos < 0) { zerror("invalid END header (bad central directory offset)"); } - // read in the CEN if (end.cenlen > MAX_CEN_SIZE) { zerror("invalid END header (central directory size too large)"); } if (end.centot < 0 || end.centot > end.cenlen / CENHDR) { zerror("invalid END header (total entries count too large)"); } - cen = this.cen = new byte[(int)end.cenlen]; - if (readFullyAt(cen, 0, cen.length, cenpos) != end.cenlen) { + // Validation ensures these are <= Integer.MAX_VALUE + int cenlen = Math.toIntExact(end.cenlen); + int centot = Math.toIntExact(end.centot); + + // read in the CEN + cen = this.cen = new byte[cenlen]; + if (readFullyAt(cen, 0, cen.length, cenpos) != cenlen) { zerror("read CEN tables failed"); } - this.total = Math.toIntExact(end.centot); + this.total = centot; } else { cen = this.cen; this.total = knownTotal; diff --git a/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java b/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java index de7a5e44b91..c220455e80b 100644 --- a/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java +++ b/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -599,8 +599,8 @@ public class ArraysSupport { if (length > 3) { if (a[aFromIndex] != b[bFromIndex]) return 0; - long aOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE); - long bOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE); + long aOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + ((long) aFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE); + long bOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + ((long) bFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE); i = vectorizedMismatch( a, aOffset, b, bOffset, @@ -648,8 +648,8 @@ public class ArraysSupport { if (length > 3) { if (a[aFromIndex] != b[bFromIndex]) return 0; - long aOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE); - long bOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE); + long aOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + ((long) aFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE); + long bOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + ((long) bFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE); i = vectorizedMismatch( a, aOffset, b, bOffset, @@ -697,8 +697,8 @@ public class ArraysSupport { if (length > 1) { if (a[aFromIndex] != b[bFromIndex]) return 0; - long aOffset = Unsafe.ARRAY_INT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_INT_INDEX_SCALE); - long bOffset = Unsafe.ARRAY_INT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_INT_INDEX_SCALE); + long aOffset = Unsafe.ARRAY_INT_BASE_OFFSET + ((long) aFromIndex << LOG2_ARRAY_INT_INDEX_SCALE); + long bOffset = Unsafe.ARRAY_INT_BASE_OFFSET + ((long) bFromIndex << LOG2_ARRAY_INT_INDEX_SCALE); i = vectorizedMismatch( a, aOffset, b, bOffset, @@ -729,8 +729,8 @@ public class ArraysSupport { int i = 0; if (length > 1) { if (Float.floatToRawIntBits(a[aFromIndex]) == Float.floatToRawIntBits(b[bFromIndex])) { - long aOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE); - long bOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE); + long aOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + ((long) aFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE); + long bOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + ((long) bFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE); i = vectorizedMismatch( a, aOffset, b, bOffset, @@ -787,8 +787,8 @@ public class ArraysSupport { } if (a[aFromIndex] != b[bFromIndex]) return 0; - long aOffset = Unsafe.ARRAY_LONG_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_LONG_INDEX_SCALE); - long bOffset = Unsafe.ARRAY_LONG_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_LONG_INDEX_SCALE); + long aOffset = Unsafe.ARRAY_LONG_BASE_OFFSET + ((long) aFromIndex << LOG2_ARRAY_LONG_INDEX_SCALE); + long bOffset = Unsafe.ARRAY_LONG_BASE_OFFSET + ((long) bFromIndex << LOG2_ARRAY_LONG_INDEX_SCALE); int i = vectorizedMismatch( a, aOffset, b, bOffset, @@ -813,8 +813,8 @@ public class ArraysSupport { } int i = 0; if (Double.doubleToRawLongBits(a[aFromIndex]) == Double.doubleToRawLongBits(b[bFromIndex])) { - long aOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_DOUBLE_INDEX_SCALE); - long bOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_DOUBLE_INDEX_SCALE); + long aOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET + ((long) aFromIndex << LOG2_ARRAY_DOUBLE_INDEX_SCALE); + long bOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET + ((long) bFromIndex << LOG2_ARRAY_DOUBLE_INDEX_SCALE); i = vectorizedMismatch( a, aOffset, b, bOffset, diff --git a/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java b/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java index 03f95222a52..23a787971c0 100644 --- a/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java +++ b/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java @@ -336,7 +336,7 @@ public class VectorSupport { @IntrinsicCandidate public static , E> - V libraryUnaryOp(long addr, Class vClass, Class eClass, int length, String debugName, + V libraryUnaryOp(long addr, Class vClass, int laneType, int length, String debugName, V v, UnaryOperation defaultImpl) { assert isNonCapturingLambda(defaultImpl) : defaultImpl; @@ -374,7 +374,7 @@ public class VectorSupport { @IntrinsicCandidate public static - V libraryBinaryOp(long addr, Class vClass, Class eClass, int length, String debugName, + V libraryBinaryOp(long addr, Class vClass, int laneType, int length, String debugName, V v1, V v2, BinaryOperation defaultImpl) { assert isNonCapturingLambda(defaultImpl) : defaultImpl; diff --git a/src/java.desktop/macosx/classes/sun/font/CStrike.java b/src/java.desktop/macosx/classes/sun/font/CStrike.java index bffb76fb1ad..f7fa00070ff 100644 --- a/src/java.desktop/macosx/classes/sun/font/CStrike.java +++ b/src/java.desktop/macosx/classes/sun/font/CStrike.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -174,7 +174,19 @@ public final class CStrike extends PhysicalStrike { @Override Point2D.Float getGlyphMetrics(final int glyphCode) { - return new Point2D.Float(getGlyphAdvance(glyphCode), 0.0f); + Point2D.Float metrics = new Point2D.Float(); + long glyphPtr = getGlyphImagePtr(glyphCode); + if (glyphPtr != 0L) { + metrics.x = StrikeCache.getGlyphXAdvance(glyphPtr); + metrics.y = StrikeCache.getGlyphYAdvance(glyphPtr); + /* advance is currently in device space, need to convert back + * into user space. + * This must not include the translation component. */ + if (invDevTx != null) { + invDevTx.deltaTransform(metrics, metrics); + } + } + return metrics; } @Override diff --git a/src/java.desktop/share/classes/java/awt/ModalEventFilter.java b/src/java.desktop/share/classes/java/awt/ModalEventFilter.java index 7941be89743..93956c34fc5 100644 --- a/src/java.desktop/share/classes/java/awt/ModalEventFilter.java +++ b/src/java.desktop/share/classes/java/awt/ModalEventFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2026, Oracle and/or its affiliates. All rights reserved. * 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,6 @@ package java.awt; import java.awt.event.*; -import sun.awt.AppContext; - abstract class ModalEventFilter implements EventFilter { protected Dialog modalDialog; @@ -129,20 +127,14 @@ abstract class ModalEventFilter implements EventFilter { private static class ToolkitModalEventFilter extends ModalEventFilter { - private AppContext appContext; - ToolkitModalEventFilter(Dialog modalDialog) { super(modalDialog); - appContext = modalDialog.appContext; } protected FilterAction acceptWindow(Window w) { if (w.isModalExcluded(Dialog.ModalExclusionType.TOOLKIT_EXCLUDE)) { return FilterAction.ACCEPT; } - if (w.appContext != appContext) { - return FilterAction.REJECT; - } while (w != null) { if (w == modalDialog) { return FilterAction.ACCEPT_IMMEDIATELY; @@ -155,27 +147,21 @@ abstract class ModalEventFilter implements EventFilter { private static class ApplicationModalEventFilter extends ModalEventFilter { - private AppContext appContext; - ApplicationModalEventFilter(Dialog modalDialog) { super(modalDialog); - appContext = modalDialog.appContext; } protected FilterAction acceptWindow(Window w) { if (w.isModalExcluded(Dialog.ModalExclusionType.APPLICATION_EXCLUDE)) { return FilterAction.ACCEPT; } - if (w.appContext == appContext) { - while (w != null) { - if (w == modalDialog) { - return FilterAction.ACCEPT_IMMEDIATELY; - } - w = w.getOwner(); + while (w != null) { + if (w == modalDialog) { + return FilterAction.ACCEPT_IMMEDIATELY; } - return FilterAction.REJECT; + w = w.getOwner(); } - return FilterAction.ACCEPT; + return FilterAction.REJECT; } } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/Chromaticity.java b/src/java.desktop/share/classes/javax/print/attribute/standard/Chromaticity.java index 0481060f73f..25dbb7ddaca 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/Chromaticity.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/Chromaticity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -114,6 +114,7 @@ public final class Chromaticity extends EnumSyntax /** * Returns the string table for class {@code Chromaticity}. */ + @Override protected String[] getStringTable() { return myStringTable; } @@ -121,6 +122,7 @@ public final class Chromaticity extends EnumSyntax /** * Returns the enumeration value table for class {@code Chromaticity}. */ + @Override protected EnumSyntax[] getEnumValueTable() { return myEnumValueTable; } @@ -135,6 +137,7 @@ public final class Chromaticity extends EnumSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return Chromaticity.class; } @@ -148,6 +151,7 @@ public final class Chromaticity extends EnumSyntax * * @return attribute category name */ + @Override public final String getName() { return "chromaticity"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/ColorSupported.java b/src/java.desktop/share/classes/javax/print/attribute/standard/ColorSupported.java index 6affb3e28dc..8ce2c5eef7c 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/ColorSupported.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/ColorSupported.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * 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,6 +104,7 @@ public final class ColorSupported extends EnumSyntax /** * Returns the string table for class {@code ColorSupported}. */ + @Override protected String[] getStringTable() { return myStringTable; } @@ -111,6 +112,7 @@ public final class ColorSupported extends EnumSyntax /** * Returns the enumeration value table for class {@code ColorSupported}. */ + @Override protected EnumSyntax[] getEnumValueTable() { return myEnumValueTable; } @@ -125,6 +127,7 @@ public final class ColorSupported extends EnumSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return ColorSupported.class; } @@ -138,6 +141,7 @@ public final class ColorSupported extends EnumSyntax * * @return attribute category name */ + @Override public final String getName() { return "color-supported"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/Compression.java b/src/java.desktop/share/classes/javax/print/attribute/standard/Compression.java index b1e7f1e89fc..9eeab5d9688 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/Compression.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/Compression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -106,6 +106,7 @@ public class Compression extends EnumSyntax implements DocAttribute { /** * Returns the string table for class {@code Compression}. */ + @Override protected String[] getStringTable() { return myStringTable.clone(); } @@ -113,6 +114,7 @@ public class Compression extends EnumSyntax implements DocAttribute { /** * Returns the enumeration value table for class {@code Compression}. */ + @Override protected EnumSyntax[] getEnumValueTable() { return (EnumSyntax[])myEnumValueTable.clone(); } @@ -127,6 +129,7 @@ public class Compression extends EnumSyntax implements DocAttribute { * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return Compression.class; } @@ -140,6 +143,7 @@ public class Compression extends EnumSyntax implements DocAttribute { * * @return attribute category name */ + @Override public final String getName() { return "compression"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/Copies.java b/src/java.desktop/share/classes/javax/print/attribute/standard/Copies.java index 33a98c035be..6292cc4c8c2 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/Copies.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/Copies.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * 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,6 +97,7 @@ public final class Copies extends IntegerSyntax * @return {@code true} if {@code object} is equivalent to this copies * attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return super.equals (object) && object instanceof Copies; } @@ -110,6 +111,7 @@ public final class Copies extends IntegerSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return Copies.class; } @@ -122,6 +124,7 @@ public final class Copies extends IntegerSyntax * * @return attribute category name */ + @Override public final String getName() { return "copies"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/CopiesSupported.java b/src/java.desktop/share/classes/javax/print/attribute/standard/CopiesSupported.java index e7b411d8e55..3c2cf4bb550 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/CopiesSupported.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/CopiesSupported.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,6 +105,7 @@ public final class CopiesSupported extends SetOfIntegerSyntax * @return {@code true} if {@code object} is equivalent to this copies * supported attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return super.equals (object) && object instanceof CopiesSupported; } @@ -119,6 +120,7 @@ public final class CopiesSupported extends SetOfIntegerSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return CopiesSupported.class; } @@ -132,6 +134,7 @@ public final class CopiesSupported extends SetOfIntegerSyntax * * @return attribute category name */ + @Override public final String getName() { return "copies-supported"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/DateTimeAtCompleted.java b/src/java.desktop/share/classes/javax/print/attribute/standard/DateTimeAtCompleted.java index 4e0a3b27259..a7a31dacd8d 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/DateTimeAtCompleted.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/DateTimeAtCompleted.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,6 +88,7 @@ public final class DateTimeAtCompleted extends DateTimeSyntax * @return {@code true} if {@code object} is equivalent to this date-time at * completed attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return(super.equals (object) && object instanceof DateTimeAtCompleted); @@ -105,6 +106,7 @@ public final class DateTimeAtCompleted extends DateTimeSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return DateTimeAtCompleted.class; } @@ -118,6 +120,7 @@ public final class DateTimeAtCompleted extends DateTimeSyntax * * @return attribute category name */ + @Override public final String getName() { return "date-time-at-completed"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/DateTimeAtCreation.java b/src/java.desktop/share/classes/javax/print/attribute/standard/DateTimeAtCreation.java index fc09f0672c2..53b85b7cf5c 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/DateTimeAtCreation.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/DateTimeAtCreation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,6 +88,7 @@ public final class DateTimeAtCreation extends DateTimeSyntax * @return {@code true} if {@code object} is equivalent to this date-time at * creation attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return(super.equals (object) && object instanceof DateTimeAtCreation); @@ -103,6 +104,7 @@ public final class DateTimeAtCreation extends DateTimeSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return DateTimeAtCreation.class; } @@ -116,6 +118,7 @@ public final class DateTimeAtCreation extends DateTimeSyntax * * @return attribute category name */ + @Override public final String getName() { return "date-time-at-creation"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/DateTimeAtProcessing.java b/src/java.desktop/share/classes/javax/print/attribute/standard/DateTimeAtProcessing.java index 8b1f3efdc0f..310f3f756c7 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/DateTimeAtProcessing.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/DateTimeAtProcessing.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -89,6 +89,7 @@ public final class DateTimeAtProcessing extends DateTimeSyntax * @return {@code true} if {@code object} is equivalent to this date-time at * processing attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return(super.equals (object) && object instanceof DateTimeAtProcessing); @@ -104,6 +105,7 @@ public final class DateTimeAtProcessing extends DateTimeSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return DateTimeAtProcessing.class; } @@ -117,6 +119,7 @@ public final class DateTimeAtProcessing extends DateTimeSyntax * * @return attribute category name */ + @Override public final String getName() { return "date-time-at-processing"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/Destination.java b/src/java.desktop/share/classes/javax/print/attribute/standard/Destination.java index bc1d240c9c1..655a314b136 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/Destination.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/Destination.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -89,6 +89,7 @@ public final class Destination extends URISyntax * @return {@code true} if {@code object} is equivalent to this destination * attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return (super.equals(object) && object instanceof Destination); @@ -104,6 +105,7 @@ public final class Destination extends URISyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return Destination.class; } @@ -117,6 +119,7 @@ public final class Destination extends URISyntax * * @return attribute category name */ + @Override public final String getName() { return "spool-data-destination"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java b/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java index 593e656cf6b..01a410d075b 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ public final class DialogOwner implements PrintRequestAttribute { private static class Accessor extends DialogOwnerAccessor { + @Override public long getOwnerID(DialogOwner owner) { return owner.getID(); } @@ -133,6 +134,7 @@ public final class DialogOwner implements PrintRequestAttribute { * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return DialogOwner.class; } @@ -145,6 +147,7 @@ public final class DialogOwner implements PrintRequestAttribute { * {@code "dialog-owner"}. * */ + @Override public final String getName() { return "dialog-owner"; diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/DialogTypeSelection.java b/src/java.desktop/share/classes/javax/print/attribute/standard/DialogTypeSelection.java index ae3195d0280..2cf003060b1 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/DialogTypeSelection.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/DialogTypeSelection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * 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,6 +98,7 @@ public final class DialogTypeSelection extends EnumSyntax /** * Returns the string table for class {@code DialogTypeSelection}. */ + @Override protected String[] getStringTable() { return myStringTable; } @@ -106,6 +107,7 @@ public final class DialogTypeSelection extends EnumSyntax * Returns the enumeration value table for class * {@code DialogTypeSelection}. */ + @Override protected EnumSyntax[] getEnumValueTable() { return myEnumValueTable; } @@ -120,6 +122,7 @@ public final class DialogTypeSelection extends EnumSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return DialogTypeSelection.class; } @@ -133,6 +136,7 @@ public final class DialogTypeSelection extends EnumSyntax * * @return attribute category name */ + @Override public final String getName() { return "dialog-type-selection"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/DocumentName.java b/src/java.desktop/share/classes/javax/print/attribute/standard/DocumentName.java index eb2bd7a870d..bd1f574e4ba 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/DocumentName.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/DocumentName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * 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,6 +86,7 @@ public final class DocumentName extends TextSyntax implements DocAttribute { * @return {@code true} if {@code object} is equivalent to this document * name attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return (super.equals (object) && object instanceof DocumentName); } @@ -100,6 +101,7 @@ public final class DocumentName extends TextSyntax implements DocAttribute { * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return DocumentName.class; } @@ -113,6 +115,7 @@ public final class DocumentName extends TextSyntax implements DocAttribute { * * @return attribute category name */ + @Override public final String getName() { return "document-name"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/Fidelity.java b/src/java.desktop/share/classes/javax/print/attribute/standard/Fidelity.java index b0e4b70c87c..8c8941c76c4 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/Fidelity.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/Fidelity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -101,6 +101,7 @@ public final class Fidelity extends EnumSyntax /** * Returns the string table for class {@code Fidelity}. */ + @Override protected String[] getStringTable() { return myStringTable; } @@ -108,6 +109,7 @@ public final class Fidelity extends EnumSyntax /** * Returns the enumeration value table for class {@code Fidelity}. */ + @Override protected EnumSyntax[] getEnumValueTable() { return myEnumValueTable; } @@ -122,6 +124,7 @@ public final class Fidelity extends EnumSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return Fidelity.class; } @@ -135,6 +138,7 @@ public final class Fidelity extends EnumSyntax * * @return attribute category name */ + @Override public final String getName() { return "ipp-attribute-fidelity"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/Finishings.java b/src/java.desktop/share/classes/javax/print/attribute/standard/Finishings.java index 46d520ecb48..7d9d042b3e7 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/Finishings.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/Finishings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -344,6 +344,7 @@ public class Finishings extends EnumSyntax /** * Returns the string table for class {@code Finishings}. */ + @Override protected String[] getStringTable() { return myStringTable.clone(); } @@ -351,6 +352,7 @@ public class Finishings extends EnumSyntax /** * Returns the enumeration value table for class {@code Finishings}. */ + @Override protected EnumSyntax[] getEnumValueTable() { return (EnumSyntax[])myEnumValueTable.clone(); } @@ -358,6 +360,7 @@ public class Finishings extends EnumSyntax /** * Returns the lowest integer value used by class {@code Finishings}. */ + @Override protected int getOffset() { return 3; } @@ -372,6 +375,7 @@ public class Finishings extends EnumSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return Finishings.class; } @@ -385,6 +389,7 @@ public class Finishings extends EnumSyntax * * @return attribute category name */ + @Override public final String getName() { return "finishings"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobHoldUntil.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobHoldUntil.java index d4e2c2625df..2b9ede6940f 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobHoldUntil.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobHoldUntil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -123,6 +123,7 @@ public final class JobHoldUntil extends DateTimeSyntax * @return {@code true} if {@code object} is equivalent to this job hold * until attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return (super.equals(object) && object instanceof JobHoldUntil); } @@ -137,6 +138,7 @@ public final class JobHoldUntil extends DateTimeSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobHoldUntil.class; } @@ -150,6 +152,7 @@ public final class JobHoldUntil extends DateTimeSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-hold-until"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobImpressions.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobImpressions.java index ed9600838be..70d7c7e5e46 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobImpressions.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobImpressions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -110,6 +110,7 @@ public final class JobImpressions extends IntegerSyntax * @return {@code true} if {@code object} is equivalent to this job * impressions attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return super.equals (object) && object instanceof JobImpressions; } @@ -124,6 +125,7 @@ public final class JobImpressions extends IntegerSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobImpressions.class; } @@ -137,6 +139,7 @@ public final class JobImpressions extends IntegerSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-impressions"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobImpressionsCompleted.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobImpressionsCompleted.java index 4974f9e13c9..e6fdeb93d05 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobImpressionsCompleted.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobImpressionsCompleted.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,6 +94,7 @@ public final class JobImpressionsCompleted extends IntegerSyntax * @return {@code true} if {@code object} is equivalent to this job * impressions completed attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return(super.equals (object) && object instanceof JobImpressionsCompleted); @@ -109,6 +110,7 @@ public final class JobImpressionsCompleted extends IntegerSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobImpressionsCompleted.class; } @@ -122,6 +124,7 @@ public final class JobImpressionsCompleted extends IntegerSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-impressions-completed"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobImpressionsSupported.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobImpressionsSupported.java index 131b19f5ad2..82b3049b8bd 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobImpressionsSupported.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobImpressionsSupported.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,6 +94,7 @@ public final class JobImpressionsSupported extends SetOfIntegerSyntax * @return {@code true} if {@code object} is equivalent to this job * impressions supported attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return (super.equals (object) && object instanceof JobImpressionsSupported); @@ -109,6 +110,7 @@ public final class JobImpressionsSupported extends SetOfIntegerSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobImpressionsSupported.class; } @@ -122,6 +124,7 @@ public final class JobImpressionsSupported extends SetOfIntegerSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-impressions-supported"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctets.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctets.java index 454a30a3a28..acd04fab21d 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctets.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctets.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -159,6 +159,7 @@ public final class JobKOctets extends IntegerSyntax * @return {@code true} if {@code object} is equivalent to this job K octets * attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return super.equals(object) && object instanceof JobKOctets; } @@ -173,6 +174,7 @@ public final class JobKOctets extends IntegerSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobKOctets.class; } @@ -186,6 +188,7 @@ public final class JobKOctets extends IntegerSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-k-octets"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctetsProcessed.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctetsProcessed.java index 9acc44f5777..efd9cac2441 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctetsProcessed.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctetsProcessed.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * 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,6 +104,7 @@ public final class JobKOctetsProcessed extends IntegerSyntax * @return {@code true} if {@code object} is equivalent to this job K octets * processed attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return(super.equals (object) && object instanceof JobKOctetsProcessed); @@ -119,6 +120,7 @@ public final class JobKOctetsProcessed extends IntegerSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobKOctetsProcessed.class; } @@ -132,6 +134,7 @@ public final class JobKOctetsProcessed extends IntegerSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-k-octets-processed"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctetsSupported.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctetsSupported.java index 032d172d6e2..221328caeb8 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctetsSupported.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobKOctetsSupported.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,6 +93,7 @@ public final class JobKOctetsSupported extends SetOfIntegerSyntax * @return {@code true} if {@code object} is equivalent to this job K octets * supported attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return (super.equals (object) && object instanceof JobKOctetsSupported); @@ -108,6 +109,7 @@ public final class JobKOctetsSupported extends SetOfIntegerSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobKOctetsSupported.class; } @@ -121,6 +123,7 @@ public final class JobKOctetsSupported extends SetOfIntegerSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-k-octets-supported"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobMediaSheets.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobMediaSheets.java index a3720748f68..181bda79826 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobMediaSheets.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobMediaSheets.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -101,6 +101,7 @@ public class JobMediaSheets extends IntegerSyntax * @return {@code true} if {@code object} is equivalent to this job media * sheets attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return super.equals(object) && object instanceof JobMediaSheets; } @@ -115,6 +116,7 @@ public class JobMediaSheets extends IntegerSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobMediaSheets.class; } @@ -128,6 +130,7 @@ public class JobMediaSheets extends IntegerSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-media-sheets"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobMediaSheetsCompleted.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobMediaSheetsCompleted.java index e6f1eb9b4d8..fea87dc8ebd 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobMediaSheetsCompleted.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobMediaSheetsCompleted.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,6 +94,7 @@ public final class JobMediaSheetsCompleted extends IntegerSyntax * @return {@code true} if {@code object} is equivalent to this job media * sheets completed attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return (super.equals (object) && object instanceof JobMediaSheetsCompleted); @@ -109,6 +110,7 @@ public final class JobMediaSheetsCompleted extends IntegerSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobMediaSheetsCompleted.class; } @@ -122,6 +124,7 @@ public final class JobMediaSheetsCompleted extends IntegerSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-media-sheets-completed"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobMediaSheetsSupported.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobMediaSheetsSupported.java index a942f277175..8feeafef18a 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobMediaSheetsSupported.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobMediaSheetsSupported.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,6 +94,7 @@ public final class JobMediaSheetsSupported extends SetOfIntegerSyntax * @return {@code true} if {@code object} is equivalent to this job media * sheets supported attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return (super.equals (object) && object instanceof JobMediaSheetsSupported); @@ -109,6 +110,7 @@ public final class JobMediaSheetsSupported extends SetOfIntegerSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobMediaSheetsSupported.class; } @@ -122,6 +124,7 @@ public final class JobMediaSheetsSupported extends SetOfIntegerSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-media-sheets-supported"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobMessageFromOperator.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobMessageFromOperator.java index cd944103d23..796fe37774c 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobMessageFromOperator.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobMessageFromOperator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,6 +94,7 @@ public final class JobMessageFromOperator extends TextSyntax * @return {@code true} if {@code object} is equivalent to this job message * from operator attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return (super.equals (object) && object instanceof JobMessageFromOperator); @@ -109,6 +110,7 @@ public final class JobMessageFromOperator extends TextSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobMessageFromOperator.class; } @@ -122,6 +124,7 @@ public final class JobMessageFromOperator extends TextSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-message-from-operator"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobName.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobName.java index cceabd8b8f0..4fa9eaee6fd 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobName.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * 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,6 +92,7 @@ public final class JobName extends TextSyntax * @return {@code true} if {@code object} is equivalent to this job name * attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return (super.equals(object) && object instanceof JobName); } @@ -105,6 +106,7 @@ public final class JobName extends TextSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobName.class; } @@ -117,6 +119,7 @@ public final class JobName extends TextSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-name"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobOriginatingUserName.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobOriginatingUserName.java index d8dfd56a920..eda27d142f9 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobOriginatingUserName.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobOriginatingUserName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -91,6 +91,7 @@ public final class JobOriginatingUserName extends TextSyntax * @return {@code true} if {@code object} is equivalent to this job * originating user name attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return (super.equals (object) && object instanceof JobOriginatingUserName); @@ -106,6 +107,7 @@ public final class JobOriginatingUserName extends TextSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobOriginatingUserName.class; } @@ -119,6 +121,7 @@ public final class JobOriginatingUserName extends TextSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-originating-user-name"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobPriority.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobPriority.java index 7c77a504673..5ca9990ec13 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobPriority.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobPriority.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,6 +94,7 @@ public final class JobPriority extends IntegerSyntax * @return {@code true} if {@code object} is equivalent to this job priority * attribute, {@code false} otherwise */ + @Override public boolean equals(Object object) { return (super.equals (object) && object instanceof JobPriority); } @@ -108,6 +109,7 @@ public final class JobPriority extends IntegerSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobPriority.class; } @@ -121,6 +123,7 @@ public final class JobPriority extends IntegerSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-priority"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobPrioritySupported.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobPrioritySupported.java index 6df729a9813..422d823bff7 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobPrioritySupported.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobPrioritySupported.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * 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,6 +86,7 @@ public final class JobPrioritySupported extends IntegerSyntax * @return {@code true} if {@code object} is equivalent to this job priority * supported attribute, {@code false} otherwise */ + @Override public boolean equals (Object object) { return (super.equals(object) && @@ -102,6 +103,7 @@ public final class JobPrioritySupported extends IntegerSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobPrioritySupported.class; } @@ -115,6 +117,7 @@ public final class JobPrioritySupported extends IntegerSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-priority-supported"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobSheets.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobSheets.java index 130b8eb27a3..59a31096d2a 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobSheets.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobSheets.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -101,6 +101,7 @@ public class JobSheets extends EnumSyntax /** * Returns the string table for class {@code JobSheets}. */ + @Override protected String[] getStringTable() { return myStringTable.clone(); } @@ -108,6 +109,7 @@ public class JobSheets extends EnumSyntax /** * Returns the enumeration value table for class {@code JobSheets}. */ + @Override protected EnumSyntax[] getEnumValueTable() { return (EnumSyntax[])myEnumValueTable.clone(); } @@ -122,6 +124,7 @@ public class JobSheets extends EnumSyntax * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobSheets.class; } @@ -135,6 +138,7 @@ public class JobSheets extends EnumSyntax * * @return attribute category name */ + @Override public final String getName() { return "job-sheets"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobState.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobState.java index 13499a9b2a7..0b0ba9d3276 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobState.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -206,6 +206,7 @@ public class JobState extends EnumSyntax implements PrintJobAttribute { /** * Returns the string table for class {@code JobState}. */ + @Override protected String[] getStringTable() { return myStringTable; } @@ -213,6 +214,7 @@ public class JobState extends EnumSyntax implements PrintJobAttribute { /** * Returns the enumeration value table for class {@code JobState}. */ + @Override protected EnumSyntax[] getEnumValueTable() { return myEnumValueTable; } @@ -227,6 +229,7 @@ public class JobState extends EnumSyntax implements PrintJobAttribute { * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobState.class; } @@ -240,6 +243,7 @@ public class JobState extends EnumSyntax implements PrintJobAttribute { * * @return attribute category name */ + @Override public final String getName() { return "job-state"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobStateReason.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobStateReason.java index 2f8526cb7b1..aba72ec9c1a 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobStateReason.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobStateReason.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -436,6 +436,7 @@ public class JobStateReason extends EnumSyntax implements Attribute { /** * Returns the string table for class {@code JobStateReason}. */ + @Override protected String[] getStringTable() { return myStringTable.clone(); } @@ -443,6 +444,7 @@ public class JobStateReason extends EnumSyntax implements Attribute { /** * Returns the enumeration value table for class {@code JobStateReason}. */ + @Override protected EnumSyntax[] getEnumValueTable() { return (EnumSyntax[])myEnumValueTable.clone(); } @@ -457,6 +459,7 @@ public class JobStateReason extends EnumSyntax implements Attribute { * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobStateReason.class; } @@ -470,6 +473,7 @@ public class JobStateReason extends EnumSyntax implements Attribute { * * @return attribute category name */ + @Override public final String getName() { return "job-state-reason"; } diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/JobStateReasons.java b/src/java.desktop/share/classes/javax/print/attribute/standard/JobStateReasons.java index 22b438c02eb..4e3e66d0ea8 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/JobStateReasons.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/JobStateReasons.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -140,6 +140,7 @@ public final class JobStateReasons * class {@link JobStateReason JobStateReason} * @since 1.5 */ + @Override public boolean add(JobStateReason o) { if (o == null) { throw new NullPointerException(); @@ -157,6 +158,7 @@ public final class JobStateReasons * @return printing attribute class (category), an instance of class * {@link Class java.lang.Class} */ + @Override public final Class getCategory() { return JobStateReasons.class; } @@ -170,6 +172,7 @@ public final class JobStateReasons * * @return attribute category name */ + @Override public final String getName() { return "job-state-reasons"; } diff --git a/src/java.desktop/share/classes/javax/swing/ImageIcon.java b/src/java.desktop/share/classes/javax/swing/ImageIcon.java index ee6c08ebb15..707a1766eee 100644 --- a/src/java.desktop/share/classes/javax/swing/ImageIcon.java +++ b/src/java.desktop/share/classes/javax/swing/ImageIcon.java @@ -53,8 +53,6 @@ import javax.accessibility.AccessibleRole; import javax.accessibility.AccessibleState; import javax.accessibility.AccessibleStateSet; -import sun.awt.AWTAccessor; - /** * An implementation of the Icon interface that paints Icons * from Images. Images that are created from a URL, filename or byte array diff --git a/src/java.desktop/share/classes/javax/swing/JComponent.java b/src/java.desktop/share/classes/javax/swing/JComponent.java index f515115bade..6351522ab49 100644 --- a/src/java.desktop/share/classes/javax/swing/JComponent.java +++ b/src/java.desktop/share/classes/javax/swing/JComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -4885,8 +4885,7 @@ public abstract class JComponent extends Container implements Serializable, * @see RepaintManager#addDirtyRegion */ public void repaint(long tm, int x, int y, int width, int height) { - RepaintManager.currentManager(SunToolkit.targetToAppContext(this)) - .addDirtyRegion(this, x, y, width, height); + RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height); } diff --git a/src/java.desktop/share/classes/javax/swing/RepaintManager.java b/src/java.desktop/share/classes/javax/swing/RepaintManager.java index dcc755cb4bc..db8b13afa22 100644 --- a/src/java.desktop/share/classes/javax/swing/RepaintManager.java +++ b/src/java.desktop/share/classes/javax/swing/RepaintManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * 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,8 +119,6 @@ public class RepaintManager */ private PaintManager paintManager; - private static final Object repaintManagerKey = RepaintManager.class; - // Whether or not a VolatileImage should be used for double-buffered painting static boolean volatileImageBufferEnabled = true; /** @@ -236,8 +234,10 @@ public class RepaintManager } } + private static RepaintManager repaintManager; + /** - * Return the RepaintManager for the calling thread given a Component. + * Return the RepaintManager given a Component. * * @param c a Component -- unused in the default implementation, but could * be used by an overridden version to return a different RepaintManager @@ -249,21 +249,15 @@ public class RepaintManager // component is ever used to determine the current // RepaintManager, DisplayChangedRunnable will need to be modified // accordingly. - return currentManager(AppContext.getAppContext()); - } - /** - * Returns the RepaintManager for the specified AppContext. If - * a RepaintManager has not been created for the specified - * AppContext this will return null. - */ - static RepaintManager currentManager(AppContext appContext) { - RepaintManager rm = (RepaintManager)appContext.get(repaintManagerKey); - if (rm == null) { - rm = new RepaintManager(BUFFER_STRATEGY_TYPE); - appContext.put(repaintManagerKey, rm); + synchronized (RepaintManager.class) { + RepaintManager rm = repaintManager; + if (rm == null) { + rm = new RepaintManager(BUFFER_STRATEGY_TYPE); + repaintManager = rm; + } + return rm; } - return rm; } /** @@ -282,16 +276,12 @@ public class RepaintManager /** - * Set the RepaintManager that should be used for the calling - * thread. aRepaintManager will become the current RepaintManager - * for the calling thread's thread group. + * Set the RepaintManager. * @param aRepaintManager the RepaintManager object to use */ public static void setCurrentManager(RepaintManager aRepaintManager) { - if (aRepaintManager != null) { - SwingUtilities.appContextPut(repaintManagerKey, aRepaintManager); - } else { - SwingUtilities.appContextRemove(repaintManagerKey); + synchronized (RepaintManager.class) { + repaintManager = aRepaintManager; } } @@ -373,7 +363,7 @@ public class RepaintManager // Queue a Runnable to invoke paintDirtyRegions and // validateInvalidComponents. - scheduleProcessingRunnable(SunToolkit.targetToAppContext(invalidComponent)); + scheduleProcessingRunnable(); } @@ -460,7 +450,7 @@ public class RepaintManager // Queue a Runnable to invoke paintDirtyRegions and // validateInvalidComponents. - scheduleProcessingRunnable(SunToolkit.targetToAppContext(c)); + scheduleProcessingRunnable(); } /** @@ -530,8 +520,7 @@ public class RepaintManager // This is called from the toolkit thread when a native expose is // received. // - void nativeAddDirtyRegion(AppContext appContext, Container c, - int x, int y, int w, int h) { + void nativeAddDirtyRegion(Container c, int x, int y, int w, int h) { if (w > 0 && h > 0) { synchronized(this) { Rectangle dirty = hwDirtyComponents.get(c); @@ -543,7 +532,7 @@ public class RepaintManager x, y, w, h, dirty)); } } - scheduleProcessingRunnable(appContext); + scheduleProcessingRunnable(); } } @@ -551,8 +540,7 @@ public class RepaintManager // This is called from the toolkit thread when awt needs to run a // Runnable before we paint. // - void nativeQueueSurfaceDataRunnable(AppContext appContext, - final Component c, final Runnable r) + void nativeQueueSurfaceDataRunnable(final Component c, final Runnable r) { synchronized(this) { if (runnableList == null) { @@ -560,7 +548,7 @@ public class RepaintManager } runnableList.add(r); } - scheduleProcessingRunnable(appContext); + scheduleProcessingRunnable(); } /** @@ -1411,11 +1399,11 @@ public class RepaintManager return paintManager; } - private void scheduleProcessingRunnable(AppContext context) { + private void scheduleProcessingRunnable() { if (processingRunnable.markPending()) { Toolkit tk = Toolkit.getDefaultToolkit(); if (tk instanceof SunToolkit) { - SunToolkit.getSystemEventQueueImplPP(context). + SunToolkit.getSystemEventQueueImplPP(). postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), processingRunnable)); } else { @@ -1733,8 +1721,7 @@ public class RepaintManager /** * Listener installed to detect display changes. When display changes, * schedules a callback to notify all RepaintManagers of the display - * changes. Only one DisplayChangedHandler is ever installed. The - * singleton instance will schedule notification for all AppContexts. + * changes. Only one DisplayChangedHandler is ever installed. */ private static final class DisplayChangedHandler implements DisplayChangedListener { diff --git a/src/java.desktop/share/classes/javax/swing/SwingPaintEventDispatcher.java b/src/java.desktop/share/classes/javax/swing/SwingPaintEventDispatcher.java index 4a7b0821a3d..8c904f7d00c 100644 --- a/src/java.desktop/share/classes/javax/swing/SwingPaintEventDispatcher.java +++ b/src/java.desktop/share/classes/javax/swing/SwingPaintEventDispatcher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +28,6 @@ import java.awt.Component; import java.awt.Container; import java.awt.Rectangle; import java.awt.event.PaintEvent; -import sun.awt.AppContext; import sun.awt.SunToolkit; import sun.awt.event.IgnorePaintEvent; @@ -52,12 +51,10 @@ class SwingPaintEventDispatcher extends sun.awt.PaintEventDispatcher { public PaintEvent createPaintEvent(Component component, int x, int y, int w, int h) { if (component instanceof RootPaneContainer) { - AppContext appContext = SunToolkit.targetToAppContext(component); - RepaintManager rm = RepaintManager.currentManager(appContext); + RepaintManager rm = RepaintManager.currentManager(component); if (!SHOW_FROM_DOUBLE_BUFFER || !rm.show((Container)component, x, y, w, h)) { - rm.nativeAddDirtyRegion(appContext, (Container)component, - x, y, w, h); + rm.nativeAddDirtyRegion((Container)component, x, y, w, h); } // For backward compatibility generate an empty paint // event. Not doing this broke parts of Netbeans. @@ -65,10 +62,8 @@ class SwingPaintEventDispatcher extends sun.awt.PaintEventDispatcher { new Rectangle(x, y, w, h)); } else if (component instanceof SwingHeavyWeight) { - AppContext appContext = SunToolkit.targetToAppContext(component); - RepaintManager rm = RepaintManager.currentManager(appContext); - rm.nativeAddDirtyRegion(appContext, (Container)component, - x, y, w, h); + RepaintManager rm = RepaintManager.currentManager(component); + rm.nativeAddDirtyRegion((Container)component, x, y, w, h); return new IgnorePaintEvent(component, PaintEvent.PAINT, new Rectangle(x, y, w, h)); } @@ -81,9 +76,7 @@ class SwingPaintEventDispatcher extends sun.awt.PaintEventDispatcher { public boolean queueSurfaceDataReplacing(Component c, Runnable r) { if (c instanceof RootPaneContainer) { - AppContext appContext = SunToolkit.targetToAppContext(c); - RepaintManager.currentManager(appContext). - nativeQueueSurfaceDataRunnable(appContext, c, r); + RepaintManager.currentManager(c).nativeQueueSurfaceDataRunnable(c, r); return true; } return super.queueSurfaceDataReplacing(c, r); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTitlePane.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTitlePane.java index ae8b379a579..4ed6734df1f 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTitlePane.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTitlePane.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -437,6 +437,7 @@ class MetalTitlePane extends JComponent { */ private JMenu createMenu() { JMenu menu = new JMenu(""); + menu.setPreferredSize(new Dimension(IMAGE_WIDTH, IMAGE_HEIGHT)); if (getWindowDecorationStyle() == JRootPane.FRAME) { addMenuItems(menu); } diff --git a/src/java.desktop/share/classes/sun/awt/SunToolkit.java b/src/java.desktop/share/classes/sun/awt/SunToolkit.java index 10fb62e2fdc..e97b654486f 100644 --- a/src/java.desktop/share/classes/sun/awt/SunToolkit.java +++ b/src/java.desktop/share/classes/sun/awt/SunToolkit.java @@ -1034,8 +1034,7 @@ public abstract class SunToolkit extends Toolkit return getSystemEventQueueImplPP(); } - // Package private implementation - static EventQueue getSystemEventQueueImplPP() { + public static EventQueue getSystemEventQueueImplPP() { return getSystemEventQueueImplPP(AppContext.getAppContext()); } diff --git a/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java b/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java index 917378389a4..986b79edde9 100644 --- a/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java +++ b/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -314,10 +314,10 @@ class FetcherInfo { static final int MAX_NUM_FETCHERS = 4; static final FetcherInfo FETCHER_INFO = new FetcherInfo(); - Thread[] fetchers; + final Thread[] fetchers; int numFetchers; int numWaiting; - Vector waitList; + final Vector waitList; private FetcherInfo() { fetchers = new Thread[MAX_NUM_FETCHERS]; diff --git a/src/java.desktop/share/classes/sun/font/GlyphLayout.java b/src/java.desktop/share/classes/sun/font/GlyphLayout.java index df42cce344e..5bff127f143 100644 --- a/src/java.desktop/share/classes/sun/font/GlyphLayout.java +++ b/src/java.desktop/share/classes/sun/font/GlyphLayout.java @@ -76,7 +76,7 @@ import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Point2D; import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; +import java.util.WeakHashMap; import static java.lang.Character.*; @@ -125,18 +125,12 @@ public final class GlyphLayout { } private static final class SDCache { - public Font key_font; - public FontRenderContext key_frc; - public AffineTransform dtx; public AffineTransform gtx; public Point2D.Float delta; public FontStrikeDesc sd; private SDCache(Font font, FontRenderContext frc) { - key_font = font; - key_frc = frc; - // !!! add getVectorTransform and hasVectorTransform to frc? then // we could just skip this work... @@ -177,7 +171,7 @@ public final class GlyphLayout { private static final Point2D.Float ZERO_DELTA = new Point2D.Float(); private static - SoftReference> cacheRef; + SoftReference> cacheRef; private static final class SDKey { private final Font font; @@ -232,7 +226,7 @@ public final class GlyphLayout { } SDKey key = new SDKey(font, frc); // garbage, yuck... - ConcurrentHashMap cache = null; + WeakHashMap cache = null; SDCache res = null; if (cacheRef != null) { cache = cacheRef.get(); @@ -243,13 +237,17 @@ public final class GlyphLayout { if (res == null) { res = new SDCache(font, frc); if (cache == null) { - cache = new ConcurrentHashMap(10); + cache = new WeakHashMap(10); cacheRef = new - SoftReference>(cache); - } else if (cache.size() >= 512) { - cache.clear(); + SoftReference>(cache); + } else if (cache.size() >= 128) { + synchronized (SDCache.class) { + cache.clear(); + } + } + synchronized (SDCache.class) { + cache.put(key, res); } - cache.put(key, res); } return res; } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/quic/PeerConnectionId.java b/src/java.net.http/share/classes/jdk/internal/net/http/quic/PeerConnectionId.java index 0c6f946d1a2..b822480c2a5 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/quic/PeerConnectionId.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/quic/PeerConnectionId.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * 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,8 +72,13 @@ public final class PeerConnectionId extends QuicConnectionId { } private static ByteBuffer cloneBuffer(ByteBuffer src) { + // we make a copy of the bytes and create a new + // ByteBuffer here because we do not want to retain + // the memory that was allocated for the original + // ByteBuffer, which could ba a slice of a larger + // buffer, such as the whole datagram payload. final byte[] idBytes = new byte[src.remaining()]; - src.get(idBytes); + src.get(src.position(), idBytes); return ByteBuffer.wrap(idBytes); } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicConnectionImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicConnectionImpl.java index edb94d5929a..41b814a551c 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicConnectionImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicConnectionImpl.java @@ -703,7 +703,9 @@ public class QuicConnectionImpl extends QuicConnection implements QuicPacketRece return; } if (debug.on()) { - debug.log("scheduleForDecryption: %d bytes", received); + debug.log("scheduleForDecryption: %s bytes [idbytes: %s(%s,%s)]", + received, datagram.destConnId().getClass().getSimpleName(), + datagram.destConnId().position(), datagram.destConnId().limit()); } endpoint.buffer(received); incoming.add(datagram); @@ -1847,6 +1849,10 @@ public class QuicConnectionImpl extends QuicConnection implements QuicPacketRece header.destinationId().toHexString(), Utils.asHexString(destConnId)); } + assert packetIndex > 1 : + "first long packet CID does not match itself %s(%s,%s)" + .formatted(destConnId.getClass().getSimpleName(), + destConnId.position(), destConnId.limit()); return; } var peekedVersion = header.version(); @@ -1918,6 +1924,10 @@ public class QuicConnectionImpl extends QuicConnection implements QuicPacketRece " wrong connection id (%s vs %s)", packetIndex, Utils.asHexString(cid), Utils.asHexString(destConnId)); } + assert packetIndex > 1 : "first short packet CID does not match itself %s(%s,%s)" + .formatted(destConnId.getClass().getSimpleName(), + destConnId.position(), destConnId.limit()); + return; } @@ -1934,6 +1944,9 @@ public class QuicConnectionImpl extends QuicConnection implements QuicPacketRece if (debug.on()) { debug.log("Failed to process incoming packet", t); } + if (t instanceof AssertionError) { + this.terminator.terminate(TerminationCause.forException(t)); + } } } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java index 519122b4d28..5e7c97dc56d 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java @@ -724,7 +724,7 @@ public abstract class DoubleVector extends AbstractVector { @ForceInline final DoubleVector unaryMathOp(VectorOperators.Unary op) { - return VectorMathLibrary.unaryMathOp(op, opCode(op), species(), DoubleVector::unaryOperations, + return VectorMathLibrary.unaryMathOp(op, opCode(op), vspecies(), DoubleVector::unaryOperations, this); } @@ -851,7 +851,7 @@ public abstract class DoubleVector extends AbstractVector { @ForceInline final DoubleVector binaryMathOp(VectorOperators.Binary op, DoubleVector that) { - return VectorMathLibrary.binaryMathOp(op, opCode(op), species(), DoubleVector::binaryOperations, + return VectorMathLibrary.binaryMathOp(op, opCode(op), vspecies(), DoubleVector::binaryOperations, this, that); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java index 9950abf696d..5862a295fa3 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java @@ -724,7 +724,7 @@ public abstract class FloatVector extends AbstractVector { @ForceInline final FloatVector unaryMathOp(VectorOperators.Unary op) { - return VectorMathLibrary.unaryMathOp(op, opCode(op), species(), FloatVector::unaryOperations, + return VectorMathLibrary.unaryMathOp(op, opCode(op), vspecies(), FloatVector::unaryOperations, this); } @@ -851,7 +851,7 @@ public abstract class FloatVector extends AbstractVector { @ForceInline final FloatVector binaryMathOp(VectorOperators.Binary op, FloatVector that) { - return VectorMathLibrary.binaryMathOp(op, opCode(op), species(), FloatVector::binaryOperations, + return VectorMathLibrary.binaryMathOp(op, opCode(op), vspecies(), FloatVector::binaryOperations, this, that); } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMathLibrary.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMathLibrary.java index 4898cb70884..1c1cfcc78c7 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMathLibrary.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMathLibrary.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -283,7 +283,7 @@ import static jdk.internal.vm.vector.Utils.debug; @ForceInline /*package-private*/ static > - V unaryMathOp(Unary op, int opc, VectorSpecies vspecies, + V unaryMathOp(Unary op, int opc, AbstractSpecies vspecies, IntFunction> implSupplier, V v) { var entry = lookup(op, opc, vspecies, implSupplier); @@ -293,7 +293,7 @@ import static jdk.internal.vm.vector.Utils.debug; @SuppressWarnings({"unchecked"}) Class vt = (Class)vspecies.vectorType(); return VectorSupport.libraryUnaryOp( - entry.entry.address(), vt, vspecies.elementType(), vspecies.length(), entry.name, + entry.entry.address(), vt, vspecies.laneTypeOrdinal(), vspecies.length(), entry.name, v, entry.impl); } else { @@ -304,7 +304,7 @@ import static jdk.internal.vm.vector.Utils.debug; @ForceInline /*package-private*/ static > - V binaryMathOp(Binary op, int opc, VectorSpecies vspecies, + V binaryMathOp(Binary op, int opc, AbstractSpecies vspecies, IntFunction> implSupplier, V v1, V v2) { var entry = lookup(op, opc, vspecies, implSupplier); @@ -314,7 +314,7 @@ import static jdk.internal.vm.vector.Utils.debug; @SuppressWarnings({"unchecked"}) Class vt = (Class)vspecies.vectorType(); return VectorSupport.libraryBinaryOp( - entry.entry.address(), vt, vspecies.elementType(), vspecies.length(), entry.name, + entry.entry.address(), vt, vspecies.laneTypeOrdinal(), vspecies.length(), entry.name, v1, v2, entry.impl); } else { diff --git a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java index b3db11eb1fe..3223ff9dccd 100644 --- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java +++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java @@ -105,6 +105,9 @@ class ZipFileSystem extends FileSystem { private static final String COMPRESSION_METHOD_DEFLATED = "DEFLATED"; // Value specified for compressionMethod property to not compress Zip entries private static final String COMPRESSION_METHOD_STORED = "STORED"; + // CEN size is limited to the maximum array size in the JDK + // See ArraysSupport.SOFT_MAX_ARRAY_LENGTH; + private static final int MAX_CEN_SIZE = Integer.MAX_VALUE - 8; private final ZipFileSystemProvider provider; private final Path zfpath; @@ -1353,7 +1356,7 @@ class ZipFileSystem extends FileSystem { // to use the end64 values end.cenlen = cenlen64; end.cenoff = cenoff64; - end.centot = (int)centot64; // assume total < 2g + end.centot = centot64; end.endpos = end64pos; return end; } @@ -1575,23 +1578,34 @@ class ZipFileSystem extends FileSystem { buildNodeTree(); return null; // only END header present } - if (end.cenlen > end.endpos) - throw new ZipException("invalid END header (bad central directory size)"); + // Validate END header + if (end.cenlen > end.endpos) { + zerror("invalid END header (bad central directory size)"); + } long cenpos = end.endpos - end.cenlen; // position of CEN table - // Get position of first local file (LOC) header, taking into - // account that there may be a stub prefixed to the zip file. + // account that there may be a stub prefixed to the ZIP file. locpos = cenpos - end.cenoff; - if (locpos < 0) - throw new ZipException("invalid END header (bad central directory offset)"); + if (locpos < 0) { + zerror("invalid END header (bad central directory offset)"); + } + if (end.cenlen > MAX_CEN_SIZE) { + zerror("invalid END header (central directory size too large)"); + } + if (end.centot < 0 || end.centot > end.cenlen / CENHDR) { + zerror("invalid END header (total entries count too large)"); + } + // Validation ensures these are <= Integer.MAX_VALUE + int cenlen = Math.toIntExact(end.cenlen); + int centot = Math.toIntExact(end.centot); // read in the CEN - byte[] cen = new byte[(int)(end.cenlen)]; - if (readNBytesAt(cen, 0, cen.length, cenpos) != end.cenlen) { - throw new ZipException("read CEN tables failed"); + byte[] cen = new byte[cenlen]; + if (readNBytesAt(cen, 0, cen.length, cenpos) != cenlen) { + zerror("read CEN tables failed"); } // Iterate through the entries in the central directory - inodes = LinkedHashMap.newLinkedHashMap(end.centot + 1); + inodes = LinkedHashMap.newLinkedHashMap(centot + 1); int pos = 0; int limit = cen.length; while (pos < limit) { @@ -2666,7 +2680,7 @@ class ZipFileSystem extends FileSystem { // int disknum; // int sdisknum; // int endsub; - int centot; // 4 bytes + long centot; // 4 bytes long cenlen; // 4 bytes long cenoff; // 4 bytes // int comlen; // comment length @@ -2689,7 +2703,7 @@ class ZipFileSystem extends FileSystem { xoff = ZIP64_MINVAL; hasZip64 = true; } - int count = centot; + int count = Math.toIntExact(centot); if (count >= ZIP64_MINVAL32) { count = ZIP64_MINVAL32; hasZip64 = true; diff --git a/test/hotspot/gtest/utilities/test_globalDefinitions.cpp b/test/hotspot/gtest/utilities/test_globalDefinitions.cpp index f24d74ea529..6636efbba8e 100644 --- a/test/hotspot/gtest/utilities/test_globalDefinitions.cpp +++ b/test/hotspot/gtest/utilities/test_globalDefinitions.cpp @@ -321,3 +321,38 @@ TEST(globalDefinitions, jlong_from) { val = jlong_from(0xABCD, 0xEFEF); EXPECT_EQ(val, CONST64(0x0000ABCD0000EFEF)); } + +struct NoCopy { + int x; + NONCOPYABLE(NoCopy); +}; + +TEST(globalDefinitions, sizeof_auto) { + char x = 5; + char& y = x; + char* z = &x; + EXPECT_EQ(sizeof_auto(x), sizeof(x)); + EXPECT_EQ(sizeof_auto(y), sizeof(y)); + EXPECT_EQ(sizeof_auto(z), sizeof(z)); + + NoCopy nc{0}; + sizeof_auto(nc); + + static_assert(sizeof_auto(char[1LL]) == 1); + static_assert(sizeof_auto(char[std::numeric_limits::max() + 1LL]) == std::numeric_limits::max() + 1LL); + static_assert(sizeof_auto(char[std::numeric_limits::max() + 1LL]) == std::numeric_limits::max() + 1LL); +#if defined(_LP64) && !defined(_WINDOWS) + // char array sometimes limited to 2 gig length on 32 bit platforms (signed), disabled for Windows because of compiler error C2148. + static_assert(sizeof_auto(char[std::numeric_limits::max() + 1LL]) == std::numeric_limits::max() + 1LL); +#endif + + static_assert(sizeof(sizeof_auto(char[std::numeric_limits::max()])) == sizeof(uint8_t)); + static_assert(sizeof(sizeof_auto(char[std::numeric_limits::max() + 1LL])) == sizeof(uint16_t)); + static_assert(sizeof(sizeof_auto(char[std::numeric_limits::max()])) == sizeof(uint16_t)); + static_assert(sizeof(sizeof_auto(char[std::numeric_limits::max() + 1LL])) == sizeof(uint32_t)); +#if defined(_LP64) && !defined(_WINDOWS) + // char array sometimes limited to 2 gig length on 32 bit platforms (signed), disabled for Windows because of compiler error C2148. + static_assert(sizeof(sizeof_auto(char[std::numeric_limits::max()])) == sizeof(uint32_t)); + static_assert(sizeof(sizeof_auto(char[std::numeric_limits::max() + 1LL])) == sizeof(uint64_t)); +#endif +} diff --git a/test/hotspot/jtreg/compiler/c2/TestDependsOnTestSqrtHFAssertion.java b/test/hotspot/jtreg/compiler/c2/TestDependsOnTestSqrtHFAssertion.java new file mode 100644 index 00000000000..5ad9a927097 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestDependsOnTestSqrtHFAssertion.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8378897 + * @summary assertion failure due to missing depends_only_on_test_impl definition in SqrtHFNode + * @library /test/lib / + * @modules jdk.incubator.vector + * @requires vm.debug & vm.compiler2.enabled + * @run main/othervm --add-modules=jdk.incubator.vector compiler.c2.TestDependsOnTestSqrtHFAssertion + */ + +package compiler.c2; + +import jdk.incubator.vector.*; + +public class TestDependsOnTestSqrtHFAssertion { + public static int x1 = 10; + + public static int x2 = 20; + + public static int y = 30; + + public static int micro(int x1, int x2, int y, int ctr) { + int res = 0; + for (int i = 0; i < ctr; i++) { + if (y != 0) { + if (x1 > 0) { + if (x2 > 0) { + if (y != 0) { + res += (int)Float16.float16ToRawShortBits(Float16.sqrt(Float16.shortBitsToFloat16((short)(x1/y)))); + res += (int)Float16.float16ToRawShortBits(Float16.sqrt(Float16.shortBitsToFloat16((short)(x2/y)))); + } + } + } + } + } + return res; + } + + public static void main(String [] args) { + int res = 0; + for (int i = 0 ; i < 100000; i++) { + res += micro(x1, x2, y, i); + } + IO.println("PASS" + res); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index c31ce198644..3508c06ad0a 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -1488,6 +1488,12 @@ public class IRNode { beforeMatchingNameRegex(VECTOR_MASK_FIRST_TRUE, "VectorMaskFirstTrue"); } + // Can only be used if libjsvml or libsleef is available + public static final String CALL_LEAF_VECTOR = PREFIX + "CALL_LEAF_VECTOR" + POSTFIX; + static { + beforeMatchingNameRegex(CALL_LEAF_VECTOR, "CallLeafVector"); + } + // Can only be used if avx512_vnni is available. public static final String MUL_ADD_VS2VI_VNNI = PREFIX + "MUL_ADD_VS2VI_VNNI" + POSTFIX; static { diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestCompatibleUseDefTypeSize.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestCompatibleUseDefTypeSize.java index 7399a1ec411..873533aaba8 100644 --- a/test/hotspot/jtreg/compiler/loopopts/superword/TestCompatibleUseDefTypeSize.java +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestCompatibleUseDefTypeSize.java @@ -514,7 +514,7 @@ public class TestCompatibleUseDefTypeSize { // Narrowing @Test - @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true" }, + @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true", "rvv", "true" }, applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = { IRNode.VECTOR_CAST_I2S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", ">0" }) public Object[] testIntToShort(int[] ints, short[] res) { @@ -527,7 +527,7 @@ public class TestCompatibleUseDefTypeSize { @Test - @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true" }, + @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true", "rvv", "true" }, applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = { IRNode.VECTOR_CAST_I2S, IRNode.VECTOR_SIZE + "min(max_int, max_char)", ">0" }) public Object[] testIntToChar(int[] ints, char[] res) { @@ -539,7 +539,7 @@ public class TestCompatibleUseDefTypeSize { } @Test - @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true" }, + @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true", "rvv", "true" }, applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = { IRNode.VECTOR_CAST_I2B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", ">0" }) public Object[] testIntToByte(int[] ints, byte[] res) { @@ -551,7 +551,7 @@ public class TestCompatibleUseDefTypeSize { } @Test - @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true" }, + @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true", "rvv", "true" }, applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = { IRNode.VECTOR_CAST_S2B, IRNode.VECTOR_SIZE + "min(max_short, max_byte)", ">0" }) public Object[] testShortToByte(short[] shorts, byte[] res) { @@ -575,7 +575,7 @@ public class TestCompatibleUseDefTypeSize { } @Test - @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true" }, + @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true", "rvv", "true" }, applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = { IRNode.VECTOR_CAST_L2S, IRNode.VECTOR_SIZE + "min(max_long, max_short)", ">0" }) public Object[] testLongToShort(long[] longs, short[] res) { @@ -587,7 +587,7 @@ public class TestCompatibleUseDefTypeSize { } @Test - @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true" }, + @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true", "rvv", "true" }, applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = { IRNode.VECTOR_CAST_L2S, IRNode.VECTOR_SIZE + "min(max_long, max_char)", ">0" }) public Object[] testLongToChar(long[] longs, char[] res) { @@ -599,7 +599,7 @@ public class TestCompatibleUseDefTypeSize { } @Test - @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true" }, + @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true", "rvv", "true" }, applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = { IRNode.VECTOR_CAST_L2I, IRNode.VECTOR_SIZE + "min(max_long, max_int)", ">0" }) public Object[] testLongToInt(long[] longs, int[] res) { @@ -611,7 +611,7 @@ public class TestCompatibleUseDefTypeSize { } @Test - @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true" }, + @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true", "rvv", "true" }, applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = { IRNode.STORE_VECTOR, ">0" }) public Object[] testShortToChar(short[] shorts, char[] res) { @@ -625,7 +625,7 @@ public class TestCompatibleUseDefTypeSize { // Widening @Test - @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true" }, + @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true", "rvv", "true" }, applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = { IRNode.VECTOR_CAST_S2I, IRNode.VECTOR_SIZE + "min(max_short, max_int)", ">0" }) public Object[] testShortToInt(short[] shorts, int[] res) { @@ -637,7 +637,7 @@ public class TestCompatibleUseDefTypeSize { } @Test - @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true" }, + @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true", "rvv", "true" }, applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = { IRNode.VECTOR_CAST_B2I, IRNode.VECTOR_SIZE + "min(max_byte, max_int)", ">0" }) public Object[] testByteToInt(byte[] bytes, int[] res) { @@ -649,7 +649,7 @@ public class TestCompatibleUseDefTypeSize { } @Test - @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true" }, + @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true", "rvv", "true" }, applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = { IRNode.VECTOR_CAST_B2S, IRNode.VECTOR_SIZE + "min(max_byte, max_short)", ">0" }) public Object[] testByteToShort(byte[] bytes, short[] res) { @@ -661,7 +661,7 @@ public class TestCompatibleUseDefTypeSize { } @Test - @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true" }, + @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true", "rvv", "true" }, applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = { IRNode.VECTOR_CAST_B2S, IRNode.VECTOR_SIZE + "min(max_byte, max_char)", ">0" }) public Object[] testByteToChar(byte[] bytes, char[] res) { @@ -685,7 +685,7 @@ public class TestCompatibleUseDefTypeSize { } @Test - @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true" }, + @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true", "rvv", "true" }, applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = { IRNode.VECTOR_CAST_S2L, IRNode.VECTOR_SIZE + "min(max_short, max_long)", ">0" }) public Object[] testShortToLong(short[] shorts, long[] res) { @@ -697,7 +697,7 @@ public class TestCompatibleUseDefTypeSize { } @Test - @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true" }, + @IR(applyIfCPUFeatureOr = { "avx", "true", "asimd", "true", "rvv", "true" }, applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = { IRNode.VECTOR_CAST_I2L, IRNode.VECTOR_SIZE + "min(max_int, max_long)", ">0" }) public Object[] testIntToLong(int[] ints, long[] res) { diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestReductions.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestReductions.java index e0f44bcdb3b..9d674950499 100644 --- a/test/hotspot/jtreg/compiler/loopopts/superword/TestReductions.java +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestReductions.java @@ -458,7 +458,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0", IRNode.AND_REDUCTION_V, "> 0", IRNode.AND_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_B, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -475,7 +475,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0", IRNode.OR_REDUCTION_V, "> 0", IRNode.OR_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_B, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -492,7 +492,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0", IRNode.XOR_REDUCTION_V, "> 0", IRNode.XOR_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_B, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -531,7 +531,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0", IRNode.MIN_REDUCTION_V, "> 0", IRNode.MIN_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_B, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -548,7 +548,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0", IRNode.MAX_REDUCTION_V, "> 0", IRNode.MAX_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_B, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -566,7 +566,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0", IRNode.AND_REDUCTION_V, "> 0", IRNode.AND_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_B, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -583,7 +583,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0", IRNode.OR_REDUCTION_V, "> 0", IRNode.OR_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_B, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -600,7 +600,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0", IRNode.XOR_REDUCTION_V, "> 0", IRNode.XOR_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_B, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -639,7 +639,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0", IRNode.MIN_REDUCTION_V, "> 0", IRNode.MIN_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_B, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -656,7 +656,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0", IRNode.MAX_REDUCTION_V, "> 0", IRNode.MAX_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_B, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -674,7 +674,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0", IRNode.AND_REDUCTION_V, "> 0", IRNode.AND_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_B, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -691,7 +691,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0", IRNode.OR_REDUCTION_V, "> 0", IRNode.OR_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_B, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -708,7 +708,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0", IRNode.XOR_REDUCTION_V, "> 0", IRNode.XOR_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_B, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -747,7 +747,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0", IRNode.MIN_REDUCTION_V, "> 0", IRNode.MIN_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_B, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -764,7 +764,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0", IRNode.MAX_REDUCTION_V, "> 0", IRNode.MAX_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_B, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -1016,7 +1016,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0", IRNode.AND_REDUCTION_V, "> 0", IRNode.AND_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_S, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -1033,7 +1033,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0", IRNode.OR_REDUCTION_V, "> 0", IRNode.OR_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_S, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -1050,7 +1050,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0", IRNode.XOR_REDUCTION_V, "> 0", IRNode.XOR_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_S, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -1089,7 +1089,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0", IRNode.MIN_REDUCTION_V, "> 0", IRNode.MIN_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_S, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -1106,7 +1106,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0", IRNode.MAX_REDUCTION_V, "> 0", IRNode.MAX_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_S, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -1124,7 +1124,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0", IRNode.AND_REDUCTION_V, "> 0", IRNode.AND_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_S, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -1141,7 +1141,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0", IRNode.OR_REDUCTION_V, "> 0", IRNode.OR_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_S, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -1158,7 +1158,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0", IRNode.XOR_REDUCTION_V, "> 0", IRNode.XOR_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_S, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -1197,7 +1197,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0", IRNode.MIN_REDUCTION_V, "> 0", IRNode.MIN_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_S, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -1214,7 +1214,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0", IRNode.MAX_REDUCTION_V, "> 0", IRNode.MAX_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_S, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -1232,7 +1232,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0", IRNode.AND_REDUCTION_V, "> 0", IRNode.AND_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_S, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -1249,7 +1249,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0", IRNode.OR_REDUCTION_V, "> 0", IRNode.OR_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_S, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -1266,7 +1266,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0", IRNode.XOR_REDUCTION_V, "> 0", IRNode.XOR_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_S, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -1305,7 +1305,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0", IRNode.MIN_REDUCTION_V, "> 0", IRNode.MIN_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_S, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) @@ -1322,7 +1322,7 @@ public class TestReductions { @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0", IRNode.MAX_REDUCTION_V, "> 0", IRNode.MAX_VI, "> 0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}, + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}, applyIf = {"AutoVectorizationOverrideProfitability", "> 0"}) @IR(failOn = IRNode.LOAD_VECTOR_S, applyIf = {"AutoVectorizationOverrideProfitability", "= 0"}) diff --git a/test/hotspot/jtreg/compiler/vectorapi/TestVectorLibraryUnaryOpAndBinaryOp.java b/test/hotspot/jtreg/compiler/vectorapi/TestVectorLibraryUnaryOpAndBinaryOp.java new file mode 100644 index 00000000000..f7837e1abfa --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/TestVectorLibraryUnaryOpAndBinaryOp.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2026, NTT DATA + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.vectorapi; + +import compiler.lib.ir_framework.*; +import jdk.incubator.vector.*; + +/** + * @test + * @bug 8378312 + * @library /test/lib / + * @summary VectorAPI: libraryUnaryOp and libraryBinaryOp should be intrinsified. + * @modules jdk.incubator.vector + * + * @run driver compiler.vectorapi.TestVectorLibraryUnaryOpAndBinaryOp + */ + +public class TestVectorLibraryUnaryOpAndBinaryOp { + + @Test + @IR(counts = { IRNode.CALL_LEAF_VECTOR, "= 1" }, applyIfCPUFeatureOr = { "asimd", "true", "avx", "true" }) + public static void testUnary() { + var vec = FloatVector.broadcast(FloatVector.SPECIES_128, 3.14f); + vec.lanewise(VectorOperators.COS); + } + + @Test + @IR(counts = { IRNode.CALL_LEAF_VECTOR, "= 1" }, applyIfCPUFeatureOr = { "asimd", "true", "avx", "true" }) + public static void testBinary() { + var vec = FloatVector.broadcast(FloatVector.SPECIES_128, 2.0f); + vec.lanewise(VectorOperators.HYPOT, 1.0f); + } + + public static void main(String[] args) { + TestFramework testFramework = new TestFramework(); + testFramework.addFlags("--add-modules=jdk.incubator.vector") + .start(); + } + +} diff --git a/test/hotspot/jtreg/compiler/vectorization/TestSubwordTruncation.java b/test/hotspot/jtreg/compiler/vectorization/TestSubwordTruncation.java index 29331cc1845..2f6296e41d2 100644 --- a/test/hotspot/jtreg/compiler/vectorization/TestSubwordTruncation.java +++ b/test/hotspot/jtreg/compiler/vectorization/TestSubwordTruncation.java @@ -74,7 +74,7 @@ public class TestSubwordTruncation { @Test @IR(counts = { IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0" }, - applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true" }) + applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true", "zvbb", "true" }) @Arguments(setup = "setupShortArray") public Object[] testShortLeadingZeros(short[] in) { short[] res = new short[SIZE]; @@ -100,7 +100,7 @@ public class TestSubwordTruncation { @Test @IR(counts = { IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0" }, - applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true" }) + applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true", "zvbb", "true" }) @Arguments(setup = "setupShortArray") public Object[] testShortTrailingZeros(short[] in) { short[] res = new short[SIZE]; @@ -126,7 +126,7 @@ public class TestSubwordTruncation { @Test @IR(counts = { IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0" }, - applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true" }) + applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true", "zvbb", "true" }) @Arguments(setup = "setupShortArray") public Object[] testShortReverse(short[] in) { short[] res = new short[SIZE]; @@ -152,7 +152,7 @@ public class TestSubwordTruncation { @Test @IR(counts = { IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_int, max_short)", "> 0" }, - applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true" }) + applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true", "zvbb", "true" }) @Arguments(setup = "setupShortArray") public Object[] testShortBitCount(short[] in) { short[] res = new short[SIZE]; @@ -282,7 +282,7 @@ public class TestSubwordTruncation { @Test @IR(counts = { IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0" }, - applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true" }) + applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true", "zvbb", "true" }) @Arguments(setup = "setupByteArray") public Object[] testByteLeadingZeros(byte[] in) { byte[] res = new byte[SIZE]; @@ -308,7 +308,7 @@ public class TestSubwordTruncation { @Test @IR(counts = { IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0" }, - applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true" }) + applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true", "zvbb", "true" }) @Arguments(setup = "setupByteArray") public Object[] testByteTrailingZeros(byte[] in) { byte[] res = new byte[SIZE]; @@ -334,7 +334,7 @@ public class TestSubwordTruncation { @Test @IR(counts = { IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0" }, - applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true" }) + applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true", "zvbb", "true" }) @Arguments(setup = "setupByteArray") public Object[] testByteReverse(byte[] in) { byte[] res = new byte[SIZE]; @@ -411,7 +411,7 @@ public class TestSubwordTruncation { @Test @IR(counts = { IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_int, max_byte)", "> 0" }, - applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true" }) + applyIfCPUFeatureOr = { "avx2", "true", "asimd", "true", "zvbb", "true" }) @Arguments(setup = "setupByteArray") public Object[] testByteBitCount(byte[] in) { byte[] res = new byte[SIZE]; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/TestZGCWithCDS.java b/test/hotspot/jtreg/runtime/cds/appcds/TestZGCWithCDS.java index 7c0b5896a98..eb42bb9f93d 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/TestZGCWithCDS.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/TestZGCWithCDS.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ */ /* - * @test + * @test id=COH * @bug 8232069 * @requires vm.cds * @requires vm.bits == 64 @@ -31,7 +31,32 @@ * @requires vm.gc == null * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds * @compile test-classes/Hello.java - * @run driver TestZGCWithCDS + * @comment Only run if COH is unset or enabled. + * @requires vm.opt.UseCompactObjectHeaders != "false" + * @comment Driver sets compressed oops/class pointers, jtreg overrides will cause problems. + Only run the test if the flags are not set via the command line. + * @requires vm.opt.UseCompressedOops == null + * @requires vm.opt.UseCompressedClassPointers == null + * @run driver TestZGCWithCDS true + */ + +/* + * @test id=NO-COH + * @bug 8232069 + * @requires vm.cds + * @requires vm.bits == 64 + * @requires vm.gc.Z + * @requires vm.gc.Serial + * @requires vm.gc == null + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds + * @compile test-classes/Hello.java + * @comment Only run if COH is unset or disabled. + * @requires vm.opt.UseCompactObjectHeaders != "true" + * @comment Driver sets compressed oops/class pointers, jtreg overrides will cause problems. + Only run the test if the flags are not set via the command line. + * @requires vm.opt.UseCompressedOops == null + * @requires vm.opt.UseCompressedClassPointers == null + * @run driver TestZGCWithCDS false */ import jdk.test.lib.Platform; @@ -42,7 +67,8 @@ public class TestZGCWithCDS { public final static String UNABLE_TO_USE_ARCHIVE = "Unable to use shared archive."; public final static String ERR_MSG = "The saved state of UseCompressedOops and UseCompressedClassPointers is different from runtime, CDS will be disabled."; public static void main(String... args) throws Exception { - String compactHeaders = "-XX:+UseCompactObjectHeaders"; + boolean compactHeadersOn = Boolean.valueOf(args[0]); + String compactHeaders = "-XX:" + (compactHeadersOn ? "+" : "-") + "UseCompactObjectHeaders"; String helloJar = JarBuilder.build("hello", "Hello"); System.out.println("0. Dump with ZGC"); OutputAnalyzer out = TestCommon diff --git a/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java index 4586b94b519..1089e849a90 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java @@ -64,6 +64,7 @@ public class AOTLinkedVarHandles { OutputAnalyzer dumpOut = CDSTestUtils.createArchiveAndCheck(opts); dumpOut.shouldMatch(s + "java/lang/invoke/VarHandle.compareAndExchangeAcquire:\\(\\[DIDI\\)D =>"); dumpOut.shouldMatch(s + "java/lang/invoke/VarHandle.get:\\(\\[DI\\)D => "); + dumpOut.shouldNotContain("rejected .* CP entry.*"); CDSOptions runOpts = (new CDSOptions()) .setUseVersion(false) diff --git a/test/jdk/java/awt/Dialog/CloseDialog/CloseDialogTest.java b/test/jdk/java/awt/Dialog/CloseDialog/CloseDialogTest.java deleted file mode 100644 index 1201e5c835c..00000000000 --- a/test/jdk/java/awt/Dialog/CloseDialog/CloseDialogTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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.Dialog; -import java.awt.Frame; -import java.io.*; -import javax.swing.*; -import sun.awt.SunToolkit; -import java.util.concurrent.atomic.AtomicReference; - -/** - * @test - * @key headful - * @bug 8043705 - * @summary Can't exit color chooser dialog when running in non-default AppContext - * @modules java.desktop/sun.awt - * @run main CloseDialogTest - */ - -public class CloseDialogTest { - - private static volatile Frame frame; - private static volatile Dialog dialog; - private static volatile InputStream testErrorStream; - private static final PrintStream systemErrStream = System.err; - private static final AtomicReference caughtException - = new AtomicReference<>(); - - public static void main(String[] args) throws Exception { - - // redirect System err - PipedOutputStream errorOutputStream = new PipedOutputStream(); - testErrorStream = new PipedInputStream(errorOutputStream); - System.setErr(new PrintStream(errorOutputStream)); - - ThreadGroup swingTG = new ThreadGroup(getRootThreadGroup(), "SwingTG"); - try { - new Thread(swingTG, () -> { - SunToolkit.createNewAppContext(); - SwingUtilities.invokeLater(() -> { - frame = new Frame(); - frame.setSize(300, 300); - frame.setVisible(true); - - dialog = new Dialog(frame); - dialog.setSize(200, 200); - dialog.setModal(true); - dialog.setVisible(true); - }); - }).start(); - - Thread.sleep(400); - - Thread disposeThread = new Thread(swingTG, () -> - SwingUtilities.invokeLater(() -> { - try { - while (dialog == null || !dialog.isVisible()) { - Thread.sleep(100); - } - dialog.setVisible(false); - dialog.dispose(); - frame.dispose(); - } catch (Exception e) { - caughtException.set(e); - } - })); - disposeThread.start(); - disposeThread.join(); - Thread.sleep(500); - - // read System err - final char[] buffer = new char[2048]; - System.err.print("END"); - System.setErr(systemErrStream); - try (Reader in = new InputStreamReader(testErrorStream, "UTF-8")) { - int size = in.read(buffer, 0, buffer.length); - String errorString = new String(buffer, 0, size); - if (!errorString.startsWith("END")) { - System.err.println(errorString. - substring(0, errorString.length() - 4)); - throw new RuntimeException("Error output is not empty!"); - } - } - } finally { - if (caughtException.get() != null) { - throw new RuntimeException("Failed. Caught exception!", - caughtException.get()); - } - } - } - - private static ThreadGroup getRootThreadGroup() { - ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); - while (threadGroup.getParent() != null) { - threadGroup = threadGroup.getParent(); - } - return threadGroup; - } -} diff --git a/test/jdk/java/awt/Toolkit/DisplayChangesException/DisplayChangesException.java b/test/jdk/java/awt/Toolkit/DisplayChangesException/DisplayChangesException.java deleted file mode 100644 index 0f13265ac58..00000000000 --- a/test/jdk/java/awt/Toolkit/DisplayChangesException/DisplayChangesException.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2018, 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 java.awt.EventQueue; -import java.awt.GraphicsEnvironment; -import java.awt.Toolkit; -import java.lang.reflect.Method; -import java.util.concurrent.CountDownLatch; - -import javax.swing.JButton; -import javax.swing.JFrame; - -import sun.awt.DisplayChangedListener; -import sun.awt.SunToolkit; - -/** - * @test - * @key headful - * @bug 8207070 - * @modules java.desktop/sun.java2d - * java.desktop/sun.awt - * java.desktop/sun.awt.windows:open - */ -public final class DisplayChangesException { - - private static boolean fail; - private static CountDownLatch go = new CountDownLatch(1); - - static final class TestThread extends Thread { - - private JFrame frame; - - private TestThread(ThreadGroup tg, String threadName) { - super(tg, threadName); - } - - public void run() { - try { - test(); - } catch (final Exception e) { - throw new RuntimeException(e); - } - } - - private void test() throws Exception { - SunToolkit.createNewAppContext(); - EventQueue.invokeAndWait(() -> { - frame = new JFrame(); - final JButton b = new JButton(); - b.addPropertyChangeListener(evt -> { - if (!SunToolkit.isDispatchThreadForAppContext(b)) { - System.err.println("Wrong thread:" + currentThread()); - fail = true; - } - }); - frame.add(b); - frame.setSize(100, 100); - frame.setLocationRelativeTo(null); - frame.pack(); - }); - go.await(); - EventQueue.invokeAndWait(() -> { - frame.dispose(); - }); - } - } - - public static void main(final String[] args) throws Exception { - ThreadGroup tg0 = new ThreadGroup("ThreadGroup0"); - ThreadGroup tg1 = new ThreadGroup("ThreadGroup1"); - - TestThread t0 = new TestThread(tg0, "TestThread 0"); - TestThread t1 = new TestThread(tg1, "TestThread 1"); - - t0.start(); - t1.start(); - Thread.sleep(1500); // Cannot use Robot.waitForIdle - testToolkit(); - Thread.sleep(1500); - testGE(); - Thread.sleep(1500); - go.countDown(); - - if (fail) { - throw new RuntimeException(); - } - } - - private static void testGE() { - Object ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); - if (!(ge instanceof DisplayChangedListener)) { - return; - } - ((DisplayChangedListener) ge).displayChanged(); - } - - private static void testToolkit() { - final Class toolkit; - try { - toolkit = Class.forName("sun.awt.windows.WToolkit"); - } catch (final ClassNotFoundException ignored) { - return; - } - try { - final Method displayChanged = toolkit.getMethod("displayChanged"); - displayChanged.invoke(Toolkit.getDefaultToolkit()); - } catch (final Exception e) { - e.printStackTrace(); - fail = true; - } - } -} - diff --git a/test/jdk/java/awt/font/GlyphVector/GlyphMetricsRotatedFontTest.java b/test/jdk/java/awt/font/GlyphVector/GlyphMetricsRotatedFontTest.java new file mode 100644 index 00000000000..eb00fd4f34d --- /dev/null +++ b/test/jdk/java/awt/font/GlyphVector/GlyphMetricsRotatedFontTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8148334 8377937 + * @summary Checks behavior of GlyphVector.getGlyphMetrics(int) with rotated fonts. + */ + +import java.awt.Font; +import java.awt.GraphicsEnvironment; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphMetrics; +import java.awt.font.GlyphVector; +import java.awt.geom.AffineTransform; + +public class GlyphMetricsRotatedFontTest { + + public static void main(String[] args) { + + String text = "The quick brown \r\n fox JUMPS over \t the lazy dog."; + FontRenderContext frc = new FontRenderContext(null, true, true); + + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + String[] names = ge.getAvailableFontFamilyNames(); + + for (String name : names) { + + Font normal = new Font(name, Font.PLAIN, 60); + if (normal.canDisplayUpTo("AZaz09") != -1) { + continue; + } + + double theta = 0.5; // about 30 degrees + AffineTransform tx = AffineTransform.getRotateInstance(theta); + Font rotated = normal.deriveFont(tx); + + GlyphVector gv1 = normal.createGlyphVector(frc, text); + GlyphVector gv2 = rotated.createGlyphVector(frc, text); + + for (int i = 0; i < gv1.getNumGlyphs(); i++) { + GlyphMetrics gm1 = gv1.getGlyphMetrics(i); + GlyphMetrics gm2 = gv2.getGlyphMetrics(i); + assertEqual(0, gm1.getAdvanceY(), 0, name + " normal y", i); + double expectedX = Math.cos(theta) * gm1.getAdvanceX(); + double expectedY = Math.sin(theta) * gm1.getAdvanceX(); + assertEqual(expectedX, gm2.getAdvanceX(), 1, name + " rotated x", i); + assertEqual(expectedY, gm2.getAdvanceY(), 1, name + " rotated y", i); + } + } + } + + private static void assertEqual(double d1, double d2, double variance, + String scenario, int index) { + if (Math.abs(d1 - d2) > variance) { + String msg = String.format("%s for index %d: %f != %f", scenario, index, d1, d2); + throw new RuntimeException(msg); + } + } +} diff --git a/test/jdk/java/lang/management/RuntimeMXBean/InputArgument.java b/test/jdk/java/lang/management/RuntimeMXBean/InputArgument.java index 66c3d3f41f5..0e7609b86ed 100644 --- a/test/jdk/java/lang/management/RuntimeMXBean/InputArgument.java +++ b/test/jdk/java/lang/management/RuntimeMXBean/InputArgument.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,41 +62,60 @@ * @run main/othervm -Dprops=something InputArgument -Dprops=something */ +/* + * @test + * @bug 8378110 + * @summary RuntimeMXBean.getInputArguments() handling of flags from settings file. + * + * @run driver InputArgument generateFlagsFile + * @run main/othervm -XX:+UseFastJNIAccessors -XX:Flags=InputArgument.flags InputArgument + * -XX:+UseFastJNIAccessors -XX:-UseG1GC -XX:+UseParallelGC -XX:MaxHeapSize=100M + */ + import java.lang.management.*; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.List; import java.util.ListIterator; public class InputArgument { private static RuntimeMXBean rm = ManagementFactory.getRuntimeMXBean(); - private static String vmOption = null; public static void main(String args[]) throws Exception { - // set the expected input argument - if (args.length > 0) { - vmOption = args[0]; - } - - List options = rm.getInputArguments(); - if (vmOption == null) { + if (args.length == 1 && "generateFlagsFile".equals(args[0])) { + generateFlagsFile(); return; } - boolean testFailed = true; + String[] vmOptions = args; + List options = rm.getInputArguments(); System.out.println("Number of arguments = " + options.size()); int i = 0; for (String arg : options) { System.out.println("Input arg " + i + " = " + arg); i++; - if (arg.equals(vmOption)) { - testFailed = false; - break; - } } - if (testFailed) { - throw new RuntimeException("TEST FAILED: " + - "VM option " + vmOption + " not found"); + + for (String expected : vmOptions) { + boolean found = false; + for (String arg : options) { + if (arg.equals(expected)) { + found = true; + break; + } + } + if (!found) { + throw new RuntimeException("TEST FAILED: " + + "VM option " + expected + " not found"); + } } System.out.println("Test passed."); } + + private static void generateFlagsFile() throws Exception { + // 3 types of flag; both boolean cases and 1 numeric + Files.writeString(Paths.get("", "InputArgument.flags"), + String.format("-UseG1GC%n+UseParallelGC%nMaxHeapSize=100M%n")); + } } diff --git a/test/jdk/java/lang/runtime/ObjectMethodsTest.java b/test/jdk/java/lang/runtime/ObjectMethodsTest.java index 951d3b68383..d7ca5912273 100644 --- a/test/jdk/java/lang/runtime/ObjectMethodsTest.java +++ b/test/jdk/java/lang/runtime/ObjectMethodsTest.java @@ -36,11 +36,11 @@ import java.lang.invoke.MethodType; import java.lang.runtime.ObjectMethods; import static java.lang.invoke.MethodType.methodType; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.*; public class ObjectMethodsTest { @@ -144,8 +144,8 @@ public class ObjectMethodsTest { assertEquals("Empty[]", (String)handle.invokeExact(new Empty())); } - Class NPE = NullPointerException.class; - Class IAE = IllegalArgumentException.class; + private static final Class NPE = NullPointerException.class; + private static final Class IAE = IllegalArgumentException.class; @Test public void exceptions() { @@ -157,25 +157,60 @@ public class ObjectMethodsTest { assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.EQUALS_DESC, C.class, "x;y", C.ACCESSORS)); assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "hashCode", C.TO_STRING_DESC, C.class, "x;y", C.ACCESSORS)); assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "equals", C.HASHCODE_DESC, C.class, "x;y", C.ACCESSORS)); + } - record NamePlusType(String mn, MethodType mt) {} - List namePlusTypeList = List.of( + record NamePlusType(String name, MethodType type) {} + + static List namePlusTypeList() { + return List.of( new NamePlusType("toString", C.TO_STRING_DESC), new NamePlusType("equals", C.EQUALS_DESC), new NamePlusType("hashCode", C.HASHCODE_DESC) ); - - for (NamePlusType npt : namePlusTypeList) { - assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, npt.mn(), npt.mt(), C.class, "x;y", null)); - assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, npt.mn(), npt.mt(), C.class, "x;y", new MethodHandle[]{null})); - assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, npt.mn(), npt.mt(), C.class, null, C.ACCESSORS)); - assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, npt.mn(), npt.mt(), null, "x;y", C.ACCESSORS)); - assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, npt.mn(), null, C.class, "x;y", C.ACCESSORS)); - assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, null, npt.mt(), C.class, "x;y", C.ACCESSORS)); - assertThrows(NPE, () -> ObjectMethods.bootstrap(null, npt.mn(), npt.mt(), C.class, "x;y", C.ACCESSORS)); - } } + @MethodSource("namePlusTypeList") + @ParameterizedTest + void commonExceptions(NamePlusType npt) { + String name = npt.name(); + MethodType type = npt.type(); + + // Null checks + assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, name, type, C.class, "x;y", null)); + assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, name, type, C.class, "x;y", new MethodHandle[]{null})); + assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, name, type, C.class, null, C.ACCESSORS)); + assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, name, type, null, "x;y", C.ACCESSORS)); + assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, name, null, C.class, "x;y", C.ACCESSORS)); + assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, null, type, C.class, "x;y", C.ACCESSORS)); + assertThrows(NPE, () -> ObjectMethods.bootstrap(null, name, type, C.class, "x;y", C.ACCESSORS)); + + // Bad indy call receiver type - change C to this test class + assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, name, type.changeParameterType(0, this.getClass()), C.class, "x;y", C.ACCESSORS)); + + // Bad getter types + var wrongReceiverGetter = assertDoesNotThrow(() -> MethodHandles.lookup().findGetter(this.getClass(), "y", int.class)); + assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, name, type, C.class, "x;y", + new MethodHandle[]{ + C.ACCESSORS[0], + wrongReceiverGetter, + })); + var extraArgGetter = MethodHandles.dropArguments(C.ACCESSORS[1], 1, int.class); + assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, name, type, C.class, "x;y", + new MethodHandle[]{ + C.ACCESSORS[0], + extraArgGetter, + })); + var voidReturnGetter = MethodHandles.empty(MethodType.methodType(void.class, C.class)); + assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, name, type, C.class, "x;y", + new MethodHandle[]{ + C.ACCESSORS[0], + voidReturnGetter, + })); + } + + // same field name and type as C::y, for wrongReceiverGetter + private int y; + // Based on the ObjectMethods internal implementation private static int hashCombiner(int x, int y) { return x*31 + y; diff --git a/test/jdk/java/net/httpclient/BufferingSubscriberCancelTest.java b/test/jdk/java/net/httpclient/BufferingSubscriberCancelTest.java index 7813b8c3d7b..4d73ec31280 100644 --- a/test/jdk/java/net/httpclient/BufferingSubscriberCancelTest.java +++ b/test/jdk/java/net/httpclient/BufferingSubscriberCancelTest.java @@ -214,6 +214,6 @@ public class BufferingSubscriberCancelTest { return; Thread.sleep(100); } - assertEquals(expected, actual); // will fail with the usual testng message + assertEquals(expected, actual); // will fail with the usual junit message } } diff --git a/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileDownloadTest.java b/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileDownloadTest.java index eb397d37b7a..92d359e32c6 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, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * 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,15 +37,11 @@ * jdk.test.lib.net.SimpleSSLContext * jdk.test.lib.Platform * jdk.test.lib.util.FileUtils - * @run testng/othervm BodyHandlerOfFileDownloadTest + * @run junit/othervm BodyHandlerOfFileDownloadTest */ import jdk.test.lib.net.SimpleSSLContext; import jdk.test.lib.util.FileUtils; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import javax.net.ssl.SSLContext; import java.io.IOException; @@ -73,28 +69,35 @@ import static java.net.http.HttpOption.H3_DISCOVERY; import static java.nio.file.StandardOpenOption.CREATE; import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING; import static java.nio.file.StandardOpenOption.WRITE; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; public class BodyHandlerOfFileDownloadTest implements HttpServerAdapters { static final String MSG = "msg"; static final String contentDispositionValue = "attachment; filename=example.html"; private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); - HttpTestServer httpTestServer; // HTTP/1.1 [ 5 servers ] - HttpTestServer httpsTestServer; // HTTPS/1.1 - HttpTestServer http2TestServer; // HTTP/2 ( h2c ) - HttpTestServer https2TestServer; // HTTP/2 ( h2 ) - HttpTestServer http3TestServer; // HTTP/3 ( h3 ) - String httpURI; - String httpsURI; - String http2URI; - String https2URI; - String http3URI; + private static HttpTestServer httpTestServer; // HTTP/1.1 [ 5 servers ] + private static HttpTestServer httpsTestServer; // HTTPS/1.1 + private static HttpTestServer http2TestServer; // HTTP/2 ( h2c ) + private static HttpTestServer https2TestServer; // HTTP/2 ( h2 ) + private static HttpTestServer http3TestServer; // HTTP/3 ( h3 ) + private static String httpURI; + private static String httpsURI; + private static String http2URI; + private static String https2URI; + private static String http3URI; - FileSystem zipFs; - Path defaultFsPath; - Path zipFsPath; + private static FileSystem zipFs; + private static Path defaultFsPath; + private static Path zipFsPath; // Default file system @@ -106,12 +109,10 @@ public class BodyHandlerOfFileDownloadTest implements HttpServerAdapters { return dir; } - @DataProvider(name = "defaultFsData") - public Object[][] defaultFsData() { + public static Object[][] defaultFsData() { return new Object[][]{ { http3URI, defaultFsPath, MSG, true }, { http3URI, defaultFsPath, MSG, false }, - { httpURI, defaultFsPath, MSG, true }, { httpsURI, defaultFsPath, MSG, true }, { http2URI, defaultFsPath, MSG, true }, @@ -123,7 +124,8 @@ public class BodyHandlerOfFileDownloadTest implements HttpServerAdapters { }; } - @Test(dataProvider = "defaultFsData") + @ParameterizedTest + @MethodSource("defaultFsData") public void testDefaultFs(String uriString, Path path, String expectedMsg, @@ -171,10 +173,10 @@ public class BodyHandlerOfFileDownloadTest implements HttpServerAdapters { out.printf("Resp code: %s\n", resp.statusCode()); out.println("Resp body Path: " + resp.body()); out.printf("Resp body written to file: %s\n", msg); - assertEquals(resp.statusCode(), 200); - assertEquals(msg, expectedMsg); + assertEquals(200, resp.statusCode()); + assertEquals(expectedMsg, msg); assertTrue(resp.headers().firstValue("Content-Disposition").isPresent()); - assertEquals(resp.headers().firstValue("Content-Disposition").get(), contentDispositionValue); + assertEquals(contentDispositionValue, resp.headers().firstValue("Content-Disposition").get()); if (!sameClient) { client.close(); } @@ -199,15 +201,17 @@ public class BodyHandlerOfFileDownloadTest implements HttpServerAdapters { return dir; } - @Test(expectedExceptions = IllegalArgumentException.class) + @Test public void testZipFs() { - out.printf("\n\n--- testZipFs(): starting\n"); - BodyHandlers.ofFileDownload(zipFsPath, CREATE, TRUNCATE_EXISTING, WRITE); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + out.printf("\n\n--- testZipFs(): starting\n"); + BodyHandlers.ofFileDownload(zipFsPath, CREATE, TRUNCATE_EXISTING, WRITE); + }); } - @BeforeTest - public void setup() throws Exception { + @BeforeAll + public static void setup() throws Exception { defaultFsPath = defaultFsDir(); zipFs = newZipFs(); zipFsPath = zipFsDir(zipFs); @@ -239,8 +243,8 @@ public class BodyHandlerOfFileDownloadTest implements HttpServerAdapters { http3TestServer.start(); } - @AfterTest - public void teardown() throws Exception { + @AfterAll + public static void teardown() throws Exception { if (Files.exists(zipFsPath)) FileUtils.deleteFileTreeWithRetry(zipFsPath); if (Files.exists(defaultFsPath)) diff --git a/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileTest.java b/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileTest.java index 13871933eac..53b8607f294 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, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * 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,15 +36,11 @@ * 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 junit/othervm BodyHandlerOfFileTest */ import jdk.test.lib.net.SimpleSSLContext; import jdk.test.lib.util.FileUtils; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import javax.net.ssl.SSLContext; import java.io.IOException; @@ -56,7 +52,10 @@ import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublishers; import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; -import java.nio.file.*; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Map; import jdk.httpclient.test.lib.common.HttpServerAdapters; import static java.lang.System.out; @@ -66,26 +65,31 @@ import static java.net.http.HttpClient.Version.HTTP_2; import static java.net.http.HttpClient.Version.HTTP_3; import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; -import static org.testng.Assert.assertEquals; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.assertEquals; public class BodyHandlerOfFileTest implements HttpServerAdapters { static final String MSG = "msg"; private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); - HttpTestServer httpTestServer; // HTTP/1.1 [ 5 servers ] - HttpTestServer httpsTestServer; // HTTPS/1.1 - HttpTestServer http2TestServer; // HTTP/2 ( h2c ) - HttpTestServer https2TestServer; // HTTP/2 ( h2 ) - HttpTestServer http3TestServer; // HTTP/3 ( h3 ) - String httpURI; - String httpsURI; - String http2URI; - String https2URI; - String http3URI; + private static HttpTestServer httpTestServer; // HTTP/1.1 [ 5 servers ] + private static HttpTestServer httpsTestServer; // HTTPS/1.1 + private static HttpTestServer http2TestServer; // HTTP/2 ( h2c ) + private static HttpTestServer https2TestServer; // HTTP/2 ( h2 ) + private static HttpTestServer http3TestServer; // HTTP/3 ( h3 ) + private static String httpURI; + private static String httpsURI; + private static String http2URI; + private static String https2URI; + private static String http3URI; - FileSystem zipFs; - Path defaultFsPath; - Path zipFsPath; + private static FileSystem zipFs; + private static Path defaultFsPath; + private static Path zipFsPath; // Default file system set-up @@ -97,8 +101,7 @@ public class BodyHandlerOfFileTest implements HttpServerAdapters { return file; } - @DataProvider(name = "defaultFsData") - public Object[][] defaultFsData() { + public static Object[][] defaultFsData() { return new Object[][]{ { http3URI, defaultFsPath, MSG, true }, { http3URI, defaultFsPath, MSG, false }, @@ -114,7 +117,8 @@ public class BodyHandlerOfFileTest implements HttpServerAdapters { }; } - @Test(dataProvider = "defaultFsData") + @ParameterizedTest + @MethodSource("defaultFsData") public void testDefaultFs(String uriString, Path path, String expectedMsg, @@ -139,8 +143,7 @@ public class BodyHandlerOfFileTest implements HttpServerAdapters { return file; } - @DataProvider(name = "zipFsData") - public Object[][] zipFsData() { + public static Object[][] zipFsData() { return new Object[][]{ { http3URI, zipFsPath, MSG, true }, { http3URI, zipFsPath, MSG, false }, @@ -156,7 +159,8 @@ public class BodyHandlerOfFileTest implements HttpServerAdapters { }; } - @Test(dataProvider = "zipFsData") + @ParameterizedTest + @MethodSource("zipFsData") public void testZipFs(String uriString, Path path, String expectedMsg, @@ -203,8 +207,8 @@ public class BodyHandlerOfFileTest implements HttpServerAdapters { String msg = Files.readString(path, StandardCharsets.UTF_8); out.printf("Resp code: %s\n", resp.statusCode()); out.printf("Msg written to %s: %s\n", resp.body(), msg); - assertEquals(resp.statusCode(), 200); - assertEquals(msg, expectedMsg); + assertEquals(200, resp.statusCode()); + assertEquals(expectedMsg, msg); if (!sameClient) { client.close(); } @@ -214,8 +218,8 @@ public class BodyHandlerOfFileTest implements HttpServerAdapters { } } - @BeforeTest - public void setup() throws Exception { + @BeforeAll + public static void setup() throws Exception { defaultFsPath = defaultFsFile(); zipFs = newZipFs(); zipFsPath = zipFsFile(zipFs); @@ -247,8 +251,8 @@ public class BodyHandlerOfFileTest implements HttpServerAdapters { http3TestServer.start(); } - @AfterTest - public void teardown() throws Exception { + @AfterAll + public static void teardown() throws Exception { if (Files.exists(zipFsPath)) FileUtils.deleteFileTreeWithRetry(zipFsPath); if (Files.exists(defaultFsPath)) diff --git a/test/jdk/java/net/httpclient/PathSubscriber/BodySubscriberOfFileTest.java b/test/jdk/java/net/httpclient/PathSubscriber/BodySubscriberOfFileTest.java index d7c9a3af4f1..da0c7220b6b 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, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * 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,15 +35,11 @@ * 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 junit/othervm BodySubscriberOfFileTest */ import jdk.test.lib.net.SimpleSSLContext; import jdk.test.lib.util.FileUtils; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import javax.net.ssl.SSLContext; import java.io.IOException; @@ -58,7 +54,10 @@ import java.net.http.HttpResponse.BodySubscribers; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import java.nio.file.*; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Map; import java.util.concurrent.Flow; import java.util.stream.IntStream; @@ -70,26 +69,32 @@ import static java.net.http.HttpClient.Version.HTTP_2; import static java.net.http.HttpClient.Version.HTTP_3; import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; -import static org.testng.Assert.assertEquals; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.assertEquals; public class BodySubscriberOfFileTest implements HttpServerAdapters { static final String MSG = "msg"; private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); - HttpTestServer httpTestServer; // HTTP/1.1 [ 5 servers ] - HttpTestServer httpsTestServer; // HTTPS/1.1 - HttpTestServer http2TestServer; // HTTP/2 ( h2c ) - HttpTestServer https2TestServer; // HTTP/2 ( h2 ) - HttpTestServer http3TestServer; // HTTP/3 ( h3 ) - String httpURI; - String httpsURI; - String http2URI; - String https2URI; - String http3URI; + private static HttpTestServer httpTestServer; // HTTP/1.1 [ 5 servers ] + private static HttpTestServer httpsTestServer; // HTTPS/1.1 + private static HttpTestServer http2TestServer; // HTTP/2 ( h2c ) + private static HttpTestServer https2TestServer; // HTTP/2 ( h2 ) + private static HttpTestServer http3TestServer; // HTTP/3 ( h3 ) + private static String httpURI; + private static String httpsURI; + private static String http2URI; + private static String https2URI; + private static String http3URI; - FileSystem zipFs; - Path defaultFsPath; - Path zipFsPath; + private static FileSystem zipFs; + private static Path defaultFsPath; + private static Path zipFsPath; // Default file system set-up @@ -101,8 +106,7 @@ public class BodySubscriberOfFileTest implements HttpServerAdapters { return file; } - @DataProvider(name = "defaultFsData") - public Object[][] defaultFsData() { + public static Object[][] defaultFsData() { return new Object[][]{ { http3URI, defaultFsPath, MSG, true }, { http3URI, defaultFsPath, MSG, false }, @@ -118,7 +122,8 @@ public class BodySubscriberOfFileTest implements HttpServerAdapters { }; } - @Test(dataProvider = "defaultFsData") + @ParameterizedTest + @MethodSource("defaultFsData") public void testDefaultFs(String uriString, Path path, String expectedMsg, @@ -143,8 +148,7 @@ public class BodySubscriberOfFileTest implements HttpServerAdapters { return file; } - @DataProvider(name = "zipFsData") - public Object[][] zipFsData() { + public static Object[][] zipFsData() { return new Object[][]{ { http3URI, zipFsPath, MSG, true }, { http3URI, zipFsPath, MSG, false }, @@ -160,7 +164,8 @@ public class BodySubscriberOfFileTest implements HttpServerAdapters { }; } - @Test(dataProvider = "zipFsData") + @ParameterizedTest + @MethodSource("zipFsData") public void testZipFs(String uriString, Path path, String expectedMsg, @@ -209,8 +214,8 @@ public class BodySubscriberOfFileTest implements HttpServerAdapters { String msg = Files.readString(path, StandardCharsets.UTF_8); out.printf("Resp code: %s\n", resp.statusCode()); out.printf("Msg written to %s: %s\n", resp.body(), msg); - assertEquals(resp.statusCode(), 200); - assertEquals(msg, expectedMsg); + assertEquals(200, resp.statusCode()); + assertEquals(expectedMsg, msg); if (!sameClient) { client.close(); } @@ -240,12 +245,12 @@ public class BodySubscriberOfFileTest implements HttpServerAdapters { }); subscriber.onNext(buffers); subscriber.onComplete(); - buffers.forEach(b -> assertEquals(b.remaining(), 0) ); + buffers.forEach(b -> assertEquals(0, b.remaining()) ); assertEquals(expectedSize, Files.size(defaultFsPath)); } - @BeforeTest - public void setup() throws Exception { + @BeforeAll + public static void setup() throws Exception { defaultFsPath = defaultFsFile(); zipFs = newZipFs(); zipFsPath = zipFsFile(zipFs); @@ -277,8 +282,8 @@ public class BodySubscriberOfFileTest implements HttpServerAdapters { http3TestServer.start(); } - @AfterTest - public void teardown() throws Exception { + @AfterAll + public static void teardown() throws Exception { if (Files.exists(zipFsPath)) FileUtils.deleteFileTreeWithRetry(zipFsPath); if (Files.exists(defaultFsPath)) diff --git a/test/jdk/java/net/httpclient/http3/BadCipherSuiteErrorTest.java b/test/jdk/java/net/httpclient/http3/BadCipherSuiteErrorTest.java index 727f2c78352..fdfc498b21e 100644 --- a/test/jdk/java/net/httpclient/http3/BadCipherSuiteErrorTest.java +++ b/test/jdk/java/net/httpclient/http3/BadCipherSuiteErrorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +26,7 @@ * @bug 8157105 * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.common.HttpServerAdapters - * @run testng/othervm/timeout=60 -Djavax.net.debug=ssl -Djdk.httpclient.HttpClient.log=all BadCipherSuiteErrorTest + * @run junit/othervm/timeout=60 -Djavax.net.debug=ssl -Djdk.httpclient.HttpClient.log=all BadCipherSuiteErrorTest * @summary check exception thrown when bad TLS parameters selected */ @@ -49,7 +49,7 @@ import static java.net.http.HttpClient.Version.HTTP_3; import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; /** * When selecting an unacceptable cipher suite the TLS handshake will fail. diff --git a/test/jdk/java/net/httpclient/http3/H3BadHeadersTest.java b/test/jdk/java/net/httpclient/http3/H3BadHeadersTest.java index fb0e1ef3085..fff11f4ceb4 100644 --- a/test/jdk/java/net/httpclient/http3/H3BadHeadersTest.java +++ b/test/jdk/java/net/httpclient/http3/H3BadHeadersTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * 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,13 @@ * @build jdk.httpclient.test.lib.common.HttpServerAdapters * jdk.test.lib.net.SimpleSSLContext * @compile ../ReferenceTracker.java - * @run testng/othervm -Djdk.internal.httpclient.debug=true H3BadHeadersTest + * @run junit/othervm -Djdk.internal.httpclient.debug=true H3BadHeadersTest * @summary this test verifies the behaviour of the HttpClient when presented * with bad headers */ import jdk.httpclient.test.lib.common.HttpServerAdapters; 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 javax.net.ssl.SSLContext; import java.io.IOException; import java.io.InputStream; @@ -57,10 +53,17 @@ import java.util.concurrent.ExecutionException; import static java.net.http.HttpOption.H3_DISCOVERY; import static java.util.List.of; import static java.util.Map.entry; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.fail; + +import org.junit.jupiter.api.AfterAll; + +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.fail; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class H3BadHeadersTest implements HttpServerAdapters { @@ -76,14 +79,13 @@ public class H3BadHeadersTest implements HttpServerAdapters { static final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE; private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); - HttpTestServer http3TestServer; // HTTP/3 ( h3 only ) - HttpTestServer https2TestServer; // HTTP/2 ( h2 + h3 ) - String http3URI; - String https2URI; + private static HttpTestServer http3TestServer; // HTTP/3 ( h3 only ) + private static HttpTestServer https2TestServer; // HTTP/2 ( h2 + h3 ) + private static String http3URI; + private static String https2URI; - @DataProvider(name = "variants") - public Object[][] variants() { + public static Object[][] variants() { return new Object[][] { { http3URI, false}, { https2URI, false}, @@ -93,7 +95,8 @@ public class H3BadHeadersTest implements HttpServerAdapters { } - @Test(dataProvider = "variants") + @ParameterizedTest + @MethodSource("variants") void test(String uri, boolean sameClient) throws Exception @@ -126,8 +129,8 @@ public class H3BadHeadersTest implements HttpServerAdapters { .HEAD().setOption(H3_DISCOVERY, config).build(); System.out.println("\nSending HEAD request: " + head); var headResponse = client.send(head, BodyHandlers.ofString()); - assertEquals(headResponse.statusCode(), 200); - assertEquals(headResponse.version(), Version.HTTP_2); + assertEquals(200, headResponse.statusCode()); + assertEquals(Version.HTTP_2, headResponse.version()); } URI uriWithQuery = URI.create(uri + "?BAD_HEADERS=" + i); @@ -163,7 +166,8 @@ public class H3BadHeadersTest implements HttpServerAdapters { System.err.printf("%ntest %s, %s, DONE%n%n", uri, sameClient); } - @Test(dataProvider = "variants") + @ParameterizedTest + @MethodSource("variants") void testAsync(String uri, boolean sameClient) throws Exception { @@ -199,8 +203,8 @@ public class H3BadHeadersTest implements HttpServerAdapters { System.out.println("\nSending HEAD request: " + head); var headResponse = client.send(head, BodyHandlers.ofString()); - assertEquals(headResponse.statusCode(), 200); - assertEquals(headResponse.version(), Version.HTTP_2); + assertEquals(200, headResponse.statusCode()); + assertEquals(Version.HTTP_2, headResponse.version()); } URI uriWithQuery = URI.create(uri + "?BAD_HEADERS=" + i); @@ -246,8 +250,7 @@ public class H3BadHeadersTest implements HttpServerAdapters { // sync with implementation. static void assertDetailMessage(Throwable throwable, int iterationIndex) { try { - assertTrue(throwable instanceof IOException, - "Expected IOException, got, " + throwable); + assertInstanceOf(IOException.class, throwable, "Expected IOException, got, " + throwable); assertNotNull(throwable.getMessage(), "No message for " + throwable); assertTrue(throwable.getMessage().contains("malformed response"), "Expected \"malformed response\" in: " + throwable.getMessage()); @@ -269,8 +272,8 @@ public class H3BadHeadersTest implements HttpServerAdapters { } } - @BeforeTest - public void setup() throws Exception { + @BeforeAll + public static void setup() throws Exception { System.out.println("creating servers"); http3TestServer = HttpTestServer.create(Http3DiscoveryMode.HTTP_3_URI_ONLY, sslContext); http3TestServer.addHandler(new BadHeadersHandler(), "/http3/echo"); @@ -285,8 +288,8 @@ public class H3BadHeadersTest implements HttpServerAdapters { System.out.println("server started"); } - @AfterTest - public void teardown() throws Exception { + @AfterAll + public static void teardown() throws Exception { System.err.println("\n\n**** stopping servers\n"); System.out.println("stopping servers"); http3TestServer.stop(); diff --git a/test/jdk/java/net/httpclient/http3/H3BasicTest.java b/test/jdk/java/net/httpclient/http3/H3BasicTest.java index a03df11c1a3..bddb9879ae9 100644 --- a/test/jdk/java/net/httpclient/http3/H3BasicTest.java +++ b/test/jdk/java/net/httpclient/http3/H3BasicTest.java @@ -31,7 +31,7 @@ * jdk.test.lib.Asserts * jdk.test.lib.Utils * jdk.test.lib.net.SimpleSSLContext - * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors + * @run junit/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors * -Djdk.internal.httpclient.debug=true * H3BasicTest */ @@ -60,7 +60,6 @@ import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.httpclient.test.lib.http3.Http3TestServer; import jdk.test.lib.RandomFactory; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.annotations.Test; import static java.net.http.HttpClient.Version.HTTP_3; import static java.net.http.HttpOption.H3_DISCOVERY; import static java.net.http.HttpOption.Http3DiscoveryMode.ALT_SVC; @@ -70,6 +69,8 @@ import static jdk.test.lib.Asserts.assertFileContentsEqual; import static jdk.test.lib.Utils.createTempFile; import static jdk.test.lib.Utils.createTempFileOfSize; +import org.junit.jupiter.api.Test; + public class H3BasicTest implements HttpServerAdapters { private static final Random RANDOM = RandomFactory.getRandom(); @@ -151,7 +152,7 @@ public class H3BasicTest implements HttpServerAdapters { } @Test - public static void test() throws Exception { + public void test() throws Exception { try { initialize(); System.out.println("servers initialized"); diff --git a/test/jdk/java/net/httpclient/http3/H3ConcurrentPush.java b/test/jdk/java/net/httpclient/http3/H3ConcurrentPush.java index 0cdb2f900fd..4392f829258 100644 --- a/test/jdk/java/net/httpclient/http3/H3ConcurrentPush.java +++ b/test/jdk/java/net/httpclient/http3/H3ConcurrentPush.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +25,7 @@ * @test * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer - * @run testng/othervm + * @run junit/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=errors,requests,responses,trace * -Djdk.httpclient.http3.maxConcurrentPushStreams=45 @@ -73,17 +73,18 @@ import java.util.function.Supplier; import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.internal.net.http.common.Utils; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; import static java.net.http.HttpOption.Http3DiscoveryMode.ALT_SVC; import static java.net.http.HttpOption.Http3DiscoveryMode.ANY; import static java.net.http.HttpOption.H3_DISCOVERY; import static java.nio.charset.StandardCharsets.UTF_8; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; + +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class H3ConcurrentPush implements HttpServerAdapters { @@ -92,7 +93,7 @@ public class H3ConcurrentPush implements HttpServerAdapters { static final PrintStream err = System.err; static final PrintStream out = System.out; - static Map PUSH_PROMISES = Map.of( + static final Map PUSH_PROMISES = Map.of( "/x/y/z/1", "the first push promise body", "/x/y/z/2", "the second push promise body", "/x/y/z/3", "the third push promise body", @@ -105,13 +106,13 @@ public class H3ConcurrentPush implements HttpServerAdapters { ); static final String MAIN_RESPONSE_BODY = "the main response body"; - HttpTestServer server; - URI uri; - URI headURI; - ServerPushHandler pushHandler; + private static HttpTestServer server; + private static URI uri; + private static URI headURI; + private static ServerPushHandler pushHandler; - @BeforeTest - public void setup() throws Exception { + @BeforeAll + public static void setup() throws Exception { server = HttpTestServer.create(ANY, SimpleSSLContext.findSSLContext()); pushHandler = new ServerPushHandler(MAIN_RESPONSE_BODY, PUSH_PROMISES); server.addHandler(pushHandler, "/push/"); @@ -122,14 +123,14 @@ public class H3ConcurrentPush implements HttpServerAdapters { headURI = new URI("https://" + server.serverAuthority() + "/head/x"); } - @AfterTest - public void teardown() { + @AfterAll + public static void teardown() { server.stop(); } static HttpResponse assert200ResponseCode(HttpResponse response) { - assertEquals(response.statusCode(), 200); - assertEquals(response.version(), Version.HTTP_3); + assertEquals(200, response.statusCode()); + assertEquals(Version.HTTP_3, response.version()); return response; } @@ -137,8 +138,8 @@ public class H3ConcurrentPush implements HttpServerAdapters { HttpRequest headRequest = HttpRequest.newBuilder(headURI) .HEAD().version(Version.HTTP_2).build(); var headResponse = client.send(headRequest, BodyHandlers.ofString()); - assertEquals(headResponse.statusCode(), 200); - assertEquals(headResponse.version(), Version.HTTP_2); + assertEquals(200, headResponse.statusCode()); + assertEquals(Version.HTTP_2, headResponse.version()); } static final class TestPushPromiseHandler implements PushPromiseHandler { @@ -233,16 +234,16 @@ public class H3ConcurrentPush implements HttpServerAdapters { promises.forEach((request, value) -> { HttpResponse response = value.join(); - assertEquals(response.statusCode(), 200); + assertEquals(200, response.statusCode()); if (PUSH_PROMISES.containsKey(request.uri().getPath())) { - assertEquals(response.body(), PUSH_PROMISES.get(request.uri().getPath())); + assertEquals(PUSH_PROMISES.get(request.uri().getPath()), response.body()); } else { - assertEquals(response.body(), MAIN_RESPONSE_BODY); + assertEquals(MAIN_RESPONSE_BODY, response.body()); } }); int expectedPushes = Math.min(PUSH_PROMISES.size(), maxPushes) + 5; - assertEquals(promises.size(), expectedPushes); + assertEquals(expectedPushes, promises.size()); promises.clear(); @@ -251,12 +252,12 @@ public class H3ConcurrentPush implements HttpServerAdapters { client.sendAsync(HttpRequest.newBuilder(uri).build(), BodyHandlers.ofString()) .thenApply(H3ConcurrentPush::assert200ResponseCode) .thenApply(HttpResponse::body) - .thenAccept(body -> assertEquals(body, MAIN_RESPONSE_BODY)) + .thenAccept(body -> assertEquals(MAIN_RESPONSE_BODY, body)) .join(); } catch (CompletionException c) { throw new AssertionError(c.getCause()); } - assertEquals(promises.size(), 0); + assertEquals(0, promises.size()); // Send with no promise handler, but use pushId bigger than allowed. // This should cause the connection to get closed @@ -268,7 +269,7 @@ public class H3ConcurrentPush implements HttpServerAdapters { client.sendAsync(bigger, BodyHandlers.ofString()) .thenApply(H3ConcurrentPush::assert200ResponseCode) .thenApply(HttpResponse::body) - .thenAccept(body -> assertEquals(body, MAIN_RESPONSE_BODY)) + .thenAccept(body -> assertEquals(MAIN_RESPONSE_BODY, body)) .join(); throw new AssertionError("Expected IOException not thrown"); } catch (CompletionException c) { @@ -287,7 +288,7 @@ public class H3ConcurrentPush implements HttpServerAdapters { throw new AssertionError("Unexpected exception: " + c.getCause(), c.getCause()); } } - assertEquals(promises.size(), 0); + assertEquals(0, promises.size()); // the next time around we should have a new connection, // so we can restart from scratch @@ -298,7 +299,7 @@ public class H3ConcurrentPush implements HttpServerAdapters { var error = errors.stream().findFirst().orElse(null); if (error != null) throw error; var notified = custom.notified; - assertEquals(notified.size(), 9*4*2, "Unexpected notification: " + notified); + assertEquals(9*4*2, notified.size(), "Unexpected notification: " + notified); } } diff --git a/test/jdk/java/net/httpclient/http3/H3ConnectionPoolTest.java b/test/jdk/java/net/httpclient/http3/H3ConnectionPoolTest.java index c90059ccbfd..614d564005b 100644 --- a/test/jdk/java/net/httpclient/http3/H3ConnectionPoolTest.java +++ b/test/jdk/java/net/httpclient/http3/H3ConnectionPoolTest.java @@ -28,7 +28,7 @@ * jdk.test.lib.Asserts * jdk.test.lib.Utils * jdk.test.lib.net.SimpleSSLContext - * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors,http3,quic:hs + * @run junit/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors,http3,quic:hs * -Djdk.internal.httpclient.debug=false * H3ConnectionPoolTest */ @@ -53,7 +53,6 @@ import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.httpclient.test.lib.http3.Http3TestServer; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.annotations.Test; import static java.net.http.HttpClient.Version.HTTP_2; import static java.net.http.HttpClient.Version.HTTP_3; @@ -65,6 +64,8 @@ import static jdk.test.lib.Asserts.assertEquals; import static jdk.test.lib.Asserts.assertNotEquals; import static jdk.test.lib.Asserts.assertTrue; +import org.junit.jupiter.api.Test; + public class H3ConnectionPoolTest implements HttpServerAdapters { private static final String CLASS_NAME = H3ConnectionPoolTest.class.getSimpleName(); @@ -172,7 +173,7 @@ public class H3ConnectionPoolTest implements HttpServerAdapters { } @Test - public static void testH3Only() throws Exception { + public void testH3Only() throws Exception { System.out.println("\nTesting HTTP/3 only"); initialize(true); try (HttpClient client = getClient()) { @@ -212,12 +213,12 @@ public class H3ConnectionPoolTest implements HttpServerAdapters { } @Test - public static void testH2H3WithTwoAltSVC() throws Exception { + public void testH2H3WithTwoAltSVC() throws Exception { testH2H3(false); } @Test - public static void testH2H3WithAltSVCOnSamePort() throws Exception { + public void testH2H3WithAltSVCOnSamePort() throws Exception { testH2H3(true); } @@ -309,7 +310,7 @@ public class H3ConnectionPoolTest implements HttpServerAdapters { // fourth request with HTTP_3_URI_ONLY should reuse the first connection, // and not reuse the second. HttpRequest request4 = req1Builder.copy().build(); - HttpResponse response4 = client.send(request1, BodyHandlers.ofString()); + HttpResponse response4 = client.send(request4, BodyHandlers.ofString()); assertEquals(HTTP_3, response4.version()); assertEquals(response4.connectionLabel().get(), response1.connectionLabel().get()); assertNotEquals(response4.connectionLabel().get(), response3.connectionLabel().get()); @@ -345,12 +346,12 @@ public class H3ConnectionPoolTest implements HttpServerAdapters { } @Test - public static void testParallelH2H3WithTwoAltSVC() throws Exception { + public void testParallelH2H3WithTwoAltSVC() throws Exception { testH2H3Concurrent(false); } @Test - public static void testParallelH2H3WithAltSVCOnSamePort() throws Exception { + public void testParallelH2H3WithAltSVCOnSamePort() throws Exception { testH2H3Concurrent(true); } diff --git a/test/jdk/java/net/httpclient/http3/H3FixedThreadPoolTest.java b/test/jdk/java/net/httpclient/http3/H3FixedThreadPoolTest.java index 6c181186fda..fd0e8214361 100644 --- a/test/jdk/java/net/httpclient/http3/H3FixedThreadPoolTest.java +++ b/test/jdk/java/net/httpclient/http3/H3FixedThreadPoolTest.java @@ -36,7 +36,7 @@ * JTreg on Tier 7 so that, if the client becomes wedged again, the * JTreg timeout handlers can collect more diagnostic information. * - * @run testng/othervm -Djdk.internal.httpclient.debug=err + * @run junit/othervm -Djdk.internal.httpclient.debug=err * -Djdk.httpclient.HttpClient.log=ssl,headers,requests,responses,errors * -Djdk.httpclient.quic.idleTimeout=666666 * -Djdk.test.server.quic.idleTimeout=666666 @@ -69,7 +69,7 @@ import static java.net.http.HttpOption.H3_DISCOVERY; import static jdk.test.lib.Asserts.assertFileContentsEqual; import static jdk.test.lib.Utils.createTempFileOfSize; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Test; public class H3FixedThreadPoolTest implements HttpServerAdapters { @@ -118,7 +118,7 @@ public class H3FixedThreadPoolTest implements HttpServerAdapters { } @Test - public static void test() throws Exception { + public void test() throws Exception { try { initialize(); simpleTest(false); diff --git a/test/jdk/java/net/httpclient/http3/H3HeaderSizeLimitTest.java b/test/jdk/java/net/httpclient/http3/H3HeaderSizeLimitTest.java index b48ef9a33f3..d5864989436 100644 --- a/test/jdk/java/net/httpclient/http3/H3HeaderSizeLimitTest.java +++ b/test/jdk/java/net/httpclient/http3/H3HeaderSizeLimitTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * 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,6 @@ import java.net.http.HttpClient.Version; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; -import java.time.Duration; import java.util.concurrent.ExecutionException; import javax.net.ssl.SSLContext; @@ -39,16 +38,16 @@ import jdk.httpclient.test.lib.http3.Http3TestServer; import jdk.httpclient.test.lib.quic.QuicServer; import jdk.internal.net.http.Http3ConnectionAccess; import jdk.internal.net.http.http3.ConnectionSettings; -import jdk.test.lib.Utils; import jdk.test.lib.net.SimpleSSLContext; import jdk.test.lib.net.URIBuilder; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + /* * @test * @summary Verifies that the HTTP client respects the SETTINGS_MAX_FIELD_SECTION_SIZE setting on HTTP3 connection @@ -57,7 +56,7 @@ import static java.net.http.HttpOption.H3_DISCOVERY; * @build jdk.test.lib.net.SimpleSSLContext * jdk.httpclient.test.lib.common.HttpServerAdapters * @build java.net.http/jdk.internal.net.http.Http3ConnectionAccess - * @run testng/othervm + * @run junit/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=requests,responses,errors H3HeaderSizeLimitTest */ @@ -65,11 +64,11 @@ public class H3HeaderSizeLimitTest implements HttpServerAdapters { private static final long HEADER_SIZE_LIMIT_BYTES = 1024; private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); - private HttpTestServer h3Server; - private String requestURIBase; + private static HttpTestServer h3Server; + private static String requestURIBase; - @BeforeClass - public void beforeClass() throws Exception { + @BeforeAll + public static void beforeClass() throws Exception { final QuicServer quicServer = Http3TestServer.quicServerBuilder() .sslContext(sslContext) .build(); @@ -82,8 +81,8 @@ public class H3HeaderSizeLimitTest implements HttpServerAdapters { .port(h3Server.getAddress().getPort()).build().toString(); } - @AfterClass - public void afterClass() throws Exception { + @AfterAll + public static void afterClass() throws Exception { if (h3Server != null) { System.out.println("Stopping server " + h3Server.getAddress()); h3Server.stop(); @@ -111,7 +110,7 @@ public class H3HeaderSizeLimitTest implements HttpServerAdapters { final HttpResponse response = client.send( reqBuilder.build(), BodyHandlers.discarding()); - Assert.assertEquals(response.statusCode(), 200, "Unexpected status code"); + Assertions.assertEquals(200, response.statusCode(), "Unexpected status code"); if (i == 3) { var cf = Http3ConnectionAccess.peerSettings(client, response); if (!cf.isDone()) { @@ -131,14 +130,14 @@ public class H3HeaderSizeLimitTest implements HttpServerAdapters { } final HttpRequest request = reqBuilder.build(); System.out.println("Issuing request to " + reqURI); - final IOException thrown = Assert.expectThrows(ProtocolException.class, + final IOException thrown = Assertions.assertThrows(ProtocolException.class, () -> client.send(request, BodyHandlers.discarding())); if (!thrown.getMessage().equals("Request headers size exceeds limit set by peer")) { throw thrown; } // test same with async System.out.println("Issuing async request to " + reqURI); - final ExecutionException asyncThrown = Assert.expectThrows(ExecutionException.class, + final ExecutionException asyncThrown = Assertions.assertThrows(ExecutionException.class, () -> client.sendAsync(request, BodyHandlers.discarding()).get()); if (!(asyncThrown.getCause() instanceof ProtocolException)) { System.err.println("Received unexpected cause"); diff --git a/test/jdk/java/net/httpclient/http3/H3HeadersEncoding.java b/test/jdk/java/net/httpclient/http3/H3HeadersEncoding.java index 44ccfac4a6a..6b7b24f049d 100644 --- a/test/jdk/java/net/httpclient/http3/H3HeadersEncoding.java +++ b/test/jdk/java/net/httpclient/http3/H3HeadersEncoding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * @build jdk.httpclient.test.lib.common.HttpServerAdapters * jdk.test.lib.net.SimpleSSLContext * @compile ../ReferenceTracker.java - * @run testng/othervm -Djdk.httpclient.qpack.encoderTableCapacityLimit=4096 + * @run junit/othervm -Djdk.httpclient.qpack.encoderTableCapacityLimit=4096 * -Djdk.httpclient.qpack.decoderMaxTableCapacity=4096 * -Dhttp3.test.server.encoderAllowedHeaders=* * -Dhttp3.test.server.decoderMaxTableCapacity=4096 @@ -40,9 +40,6 @@ import jdk.test.lib.RandomFactory; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; import javax.net.ssl.SSLContext; import java.io.IOException; @@ -72,17 +69,21 @@ import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; import static jdk.httpclient.test.lib.common.HttpServerAdapters.*; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + public class H3HeadersEncoding { private static final int REQUESTS_COUNT = 500; private static final int HEADERS_PER_REQUEST = 20; private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); - HttpTestServer http3TestServer; - HeadersHandler serverHeadersHandler; - String http3URI; + private static HttpTestServer http3TestServer; + private static HeadersHandler serverHeadersHandler; + private static String http3URI; - @BeforeTest - public void setup() throws Exception { + @BeforeAll + public static void setup() throws Exception { System.out.println("Creating servers"); http3TestServer = HttpTestServer.create(Http3DiscoveryMode.HTTP_3_URI_ONLY, sslContext); serverHeadersHandler = new HeadersHandler(); @@ -92,8 +93,8 @@ public class H3HeadersEncoding { http3TestServer.start(); } - @AfterTest - public void tearDown() { + @AfterAll + public static void tearDown() { http3TestServer.stop(); } @@ -272,7 +273,7 @@ public class H3HeadersEncoding { } - private class HeadersHandler implements HttpTestHandler { + private static class HeadersHandler implements HttpTestHandler { @Override public void handle(HttpTestExchange t) throws IOException { diff --git a/test/jdk/java/net/httpclient/http3/H3ImplicitPushCancel.java b/test/jdk/java/net/httpclient/http3/H3ImplicitPushCancel.java index 130ccd40cd6..570f84ad620 100644 --- a/test/jdk/java/net/httpclient/http3/H3ImplicitPushCancel.java +++ b/test/jdk/java/net/httpclient/http3/H3ImplicitPushCancel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +25,7 @@ * @test * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer - * @run testng/othervm + * @run junit/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=errors,requests,responses,trace * H3ImplicitPushCancel @@ -56,17 +56,18 @@ import java.util.concurrent.ConcurrentMap; import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.internal.net.http.common.Utils; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; import static java.net.http.HttpOption.Http3DiscoveryMode.ANY; import static java.nio.charset.StandardCharsets.UTF_8; -import static org.testng.Assert.assertEquals; + +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class H3ImplicitPushCancel implements HttpServerAdapters { - static Map PUSH_PROMISES = Map.of( + static final Map PUSH_PROMISES = Map.of( "/x/y/z/1", "the first push promise body", "/x/y/z/2", "the second push promise body", "/x/y/z/3", "the third push promise body", @@ -79,12 +80,12 @@ public class H3ImplicitPushCancel implements HttpServerAdapters { ); static final String MAIN_RESPONSE_BODY = "the main response body"; - HttpTestServer server; - URI uri; - URI headURI; + private static HttpTestServer server; + private static URI uri; + private static URI headURI; - @BeforeTest - public void setup() throws Exception { + @BeforeAll + public static void setup() throws Exception { server = HttpTestServer.create(ANY, SimpleSSLContext.findSSLContext()); HttpTestHandler pushHandler = new ServerPushHandler(MAIN_RESPONSE_BODY, PUSH_PROMISES); @@ -96,14 +97,14 @@ public class H3ImplicitPushCancel implements HttpServerAdapters { headURI = new URI("https://" + server.serverAuthority() + "/head/x"); } - @AfterTest - public void teardown() { + @AfterAll + public static void teardown() { server.stop(); } static HttpResponse assert200ResponseCode(HttpResponse response) { - assertEquals(response.statusCode(), 200); - assertEquals(response.version(), Version.HTTP_3); + assertEquals(200, response.statusCode()); + assertEquals(Version.HTTP_3, response.version()); return response; } @@ -111,8 +112,8 @@ public class H3ImplicitPushCancel implements HttpServerAdapters { HttpRequest headRequest = HttpRequest.newBuilder(headURI) .HEAD().version(Version.HTTP_2).build(); var headResponse = client.send(headRequest, BodyHandlers.ofString()); - assertEquals(headResponse.statusCode(), 200); - assertEquals(headResponse.version(), Version.HTTP_2); + assertEquals(200, headResponse.statusCode()); + assertEquals(Version.HTTP_2, headResponse.version()); } /* @@ -136,7 +137,7 @@ public class H3ImplicitPushCancel implements HttpServerAdapters { .build(), BodyHandlers.ofString()) .thenApply(H3ImplicitPushCancel::assert200ResponseCode) .thenApply(HttpResponse::body) - .thenAccept(body -> assertEquals(body, MAIN_RESPONSE_BODY)) + .thenAccept(body -> assertEquals(MAIN_RESPONSE_BODY, body)) .join(); System.out.println("Got result before error was raised"); throw new AssertionError("should have failed"); @@ -171,14 +172,14 @@ public class H3ImplicitPushCancel implements HttpServerAdapters { promises.putIfAbsent(main.request(), CompletableFuture.completedFuture(main)); promises.forEach((request, value) -> { HttpResponse response = value.join(); - assertEquals(response.statusCode(), 200); + assertEquals(200, response.statusCode()); if (PUSH_PROMISES.containsKey(request.uri().getPath())) { - assertEquals(response.body(), PUSH_PROMISES.get(request.uri().getPath())); + assertEquals(PUSH_PROMISES.get(request.uri().getPath()), response.body()); } else { - assertEquals(response.body(), MAIN_RESPONSE_BODY); + assertEquals(MAIN_RESPONSE_BODY, response.body()); } }); - assertEquals(promises.size(), PUSH_PROMISES.size() + 1); + assertEquals(PUSH_PROMISES.size() + 1, promises.size()); promises.clear(); @@ -187,13 +188,13 @@ public class H3ImplicitPushCancel implements HttpServerAdapters { client.sendAsync(HttpRequest.newBuilder(uri).build(), BodyHandlers.ofString()) .thenApply(H3ImplicitPushCancel::assert200ResponseCode) .thenApply(HttpResponse::body) - .thenAccept(body -> assertEquals(body, MAIN_RESPONSE_BODY)) + .thenAccept(body -> assertEquals(MAIN_RESPONSE_BODY, body)) .join(); } catch (CompletionException c) { throw new AssertionError(c.getCause()); } - assertEquals(promises.size(), 0); + assertEquals(0, promises.size()); } } diff --git a/test/jdk/java/net/httpclient/http3/H3InsertionsLimitTest.java b/test/jdk/java/net/httpclient/http3/H3InsertionsLimitTest.java index ff38cd4fa98..6eabc23677a 100644 --- a/test/jdk/java/net/httpclient/http3/H3InsertionsLimitTest.java +++ b/test/jdk/java/net/httpclient/http3/H3InsertionsLimitTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * 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,13 +27,8 @@ import jdk.httpclient.test.lib.quic.QuicServer; import jdk.internal.net.http.http3.ConnectionSettings; import jdk.internal.net.http.qpack.Encoder; import jdk.internal.net.http.qpack.TableEntry; -import jdk.test.lib.Utils; import jdk.test.lib.net.SimpleSSLContext; import jdk.test.lib.net.URIBuilder; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; import javax.net.ssl.SSLContext; import java.io.IOException; @@ -44,12 +39,16 @@ import java.net.http.HttpClient; import java.net.http.HttpClient.Version; import java.net.http.HttpRequest; import java.net.http.HttpResponse.BodyHandlers; -import java.time.Duration; import java.util.concurrent.CountDownLatch; import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + /* * @test * @summary Verifies that the HTTP client respects the maxLiteralWithIndexing @@ -59,7 +58,7 @@ import static java.net.http.HttpOption.H3_DISCOVERY; * @build jdk.test.lib.net.SimpleSSLContext * jdk.httpclient.test.lib.common.HttpServerAdapters * @build java.net.http/jdk.internal.net.http.Http3ConnectionAccess - * @run testng/othervm -Djdk.httpclient.qpack.encoderTableCapacityLimit=4096 + * @run junit/othervm -Djdk.httpclient.qpack.encoderTableCapacityLimit=4096 * -Djdk.internal.httpclient.qpack.allowBlockingEncoding=true * -Djdk.httpclient.qpack.decoderMaxTableCapacity=4096 * -Djdk.httpclient.qpack.decoderBlockedStreams=1024 @@ -75,8 +74,8 @@ public class H3InsertionsLimitTest implements HttpServerAdapters { private static final long HEADER_SIZE_LIMIT_BYTES = 8192; private static final long MAX_SERVER_DT_CAPACITY = 4096; private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); - private HttpTestServer h3Server; - private String requestURIBase; + private static HttpTestServer h3Server; + private static String requestURIBase; public static final long MAX_LITERALS_WITH_INDEXING = 32L; private static final CountDownLatch WAIT_FOR_FAILURE = new CountDownLatch(1); @@ -120,8 +119,8 @@ public class H3InsertionsLimitTest implements HttpServerAdapters { exchange.sendResponseHeaders(200, 0); } - @BeforeClass - public void beforeClass() throws Exception { + @BeforeAll + public static void beforeClass() throws Exception { final QuicServer quicServer = Http3TestServer.quicServerBuilder() .bindAddress(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)) .sslContext(sslContext) @@ -138,8 +137,8 @@ public class H3InsertionsLimitTest implements HttpServerAdapters { .port(h3Server.getAddress().getPort()).build().toString(); } - @AfterClass - public void afterClass() throws Exception { + @AfterAll + public static void afterClass() throws Exception { if (h3Server != null) { System.out.println("Stopping server " + h3Server.getAddress()); h3Server.stop(); @@ -161,10 +160,10 @@ public class H3InsertionsLimitTest implements HttpServerAdapters { System.out.println("Issuing request to " + reqURI); try { client.send(request, BodyHandlers.discarding()); - Assert.fail("IOException expected"); + Assertions.fail("IOException expected"); } catch (IOException ioe) { System.out.println("Got IOException: " + ioe); - Assert.assertTrue(ioe.getMessage() + Assertions.assertTrue(ioe.getMessage() .contains("Too many literal with indexing")); } finally { WAIT_FOR_FAILURE.countDown(); diff --git a/test/jdk/java/net/httpclient/http3/H3LogHandshakeErrors.java b/test/jdk/java/net/httpclient/http3/H3LogHandshakeErrors.java index f7a258c069c..85a4b6113f0 100644 --- a/test/jdk/java/net/httpclient/http3/H3LogHandshakeErrors.java +++ b/test/jdk/java/net/httpclient/http3/H3LogHandshakeErrors.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * 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,10 +24,8 @@ import java.io.IOException; import java.net.BindException; import java.net.ServerSocket; -import java.net.Socket; import java.net.URI; import java.net.http.HttpClient; -import java.net.http.HttpOption; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; @@ -44,16 +42,16 @@ import javax.net.ssl.SSLContext; import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.internal.net.http.quic.QuicConnectionImpl; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; import static java.net.http.HttpClient.Builder.NO_PROXY; import static java.net.http.HttpClient.Version.HTTP_3; import static java.net.http.HttpOption.H3_DISCOVERY; import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; -import static org.testng.Assert.*; + +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; /* * @test @@ -63,7 +61,7 @@ import static org.testng.Assert.*; * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext * jdk.httpclient.test.lib.common.HttpServerAdapters - * @run testng/othervm + * @run junit/othervm * -Djdk.httpclient.HttpClient.log=errors * H3LogHandshakeErrors */ @@ -71,14 +69,14 @@ import static org.testng.Assert.*; public class H3LogHandshakeErrors implements HttpServerAdapters { private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); - private HttpTestServer h3Server; - private ServerSocket tcpServerSocket = null; - private Thread tcpServerThread = null; - private String requestURI; + private static HttpTestServer h3Server; + private static ServerSocket tcpServerSocket = null; + private static Thread tcpServerThread = null; + private static String requestURI; private static Logger clientLogger; - @BeforeClass - public void beforeClass() throws Exception { + @BeforeAll + public static void beforeClass() throws Exception { // create an H3 only server h3Server = HttpTestServer.create(HTTP_3_URI_ONLY, sslContext); h3Server.addHandler((exchange) -> exchange.sendResponseHeaders(200, 0), "/hello"); @@ -113,8 +111,8 @@ public class H3LogHandshakeErrors implements HttpServerAdapters { } } - @AfterClass - public void afterClass() throws Exception { + @AfterAll + public static void afterClass() throws Exception { if (h3Server != null) { System.out.println("Stopping server " + h3Server.getAddress()); h3Server.stop(); diff --git a/test/jdk/java/net/httpclient/http3/H3MemoryHandlingTest.java b/test/jdk/java/net/httpclient/http3/H3MemoryHandlingTest.java index c9474be51c2..2fcb7388f7b 100644 --- a/test/jdk/java/net/httpclient/http3/H3MemoryHandlingTest.java +++ b/test/jdk/java/net/httpclient/http3/H3MemoryHandlingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * 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,9 +30,6 @@ import jdk.internal.net.http.quic.streams.QuicBidiStream; import jdk.internal.net.quic.QuicVersion; import jdk.test.lib.net.SimpleSSLContext; import jdk.test.lib.net.URIBuilder; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; import javax.net.ssl.SSLContext; import java.io.IOException; @@ -52,7 +49,11 @@ import java.util.concurrent.TimeUnit; import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; -import static org.testng.Assert.*; + +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; /* * @test @@ -62,7 +63,7 @@ import static org.testng.Assert.*; * @build jdk.test.lib.net.SimpleSSLContext * jdk.httpclient.test.lib.common.HttpServerAdapters * @build java.net.http/jdk.internal.net.http.Http3ConnectionAccess - * @run testng/othervm + * @run junit/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=requests,responses,errors * -Djdk.httpclient.quic.maxStreamInitialData=16384 @@ -71,11 +72,11 @@ import static org.testng.Assert.*; public class H3MemoryHandlingTest implements HttpServerAdapters { private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); - private QuicStandaloneServer server; - private String requestURIBase; + private static QuicStandaloneServer server; + private static String requestURIBase; - @BeforeClass - public void beforeClass() throws Exception { + @BeforeAll + public static void beforeClass() throws Exception { server = QuicStandaloneServer.newBuilder() .availableVersions(new QuicVersion[]{QuicVersion.QUIC_V1}) .sslContext(sslContext) @@ -87,8 +88,8 @@ public class H3MemoryHandlingTest implements HttpServerAdapters { .port(server.getAddress().getPort()).build().toString(); } - @AfterClass - public void afterClass() throws Exception { + @AfterAll + public static void afterClass() throws Exception { if (server != null) { System.out.println("Stopping server " + server.getAddress()); server.close(); @@ -125,19 +126,16 @@ public class H3MemoryHandlingTest implements HttpServerAdapters { serverAllWritesDone.complete(false); } }); - HttpClient client = getHttpClient(); - try { + try (HttpClient client = getHttpClient()) { HttpRequest request = getRequest(); final HttpResponse response1 = client.send( request, BodyHandlers.ofInputStream()); - assertEquals(response1.statusCode(), 200); + assertEquals(200, response1.statusCode()); assertFalse(errorCF.isDone(), "Expected the connection to be open"); assertFalse(serverAllWritesDone.isDone()); response1.body().close(); final boolean done = serverAllWritesDone.get(10, TimeUnit.SECONDS); assertFalse(done, "Too much data was buffered by the client"); - } finally { - client.close(); } } @@ -176,12 +174,12 @@ public class H3MemoryHandlingTest implements HttpServerAdapters { handlerCF.completeExceptionally(e); } }); - HttpClient client = getHttpClient(); - try { + + try (HttpClient client = getHttpClient()) { HttpRequest request = getRequest(); final HttpResponse response1 = client.send( - request, BodyHandlers.ofInputStream()); - assertEquals(response1.statusCode(), 200); + request, BodyHandlers.ofInputStream()); + assertEquals(200, response1.statusCode()); assertFalse(errorCF.isDone(), "Expected the connection to be open"); assertFalse(handlerCF.isDone()); assertTrue(writerBlocked.await(10, TimeUnit.SECONDS), @@ -191,10 +189,8 @@ public class H3MemoryHandlingTest implements HttpServerAdapters { try (InputStream body = response1.body()) { receivedResponse = body.readAllBytes(); } - assertEquals(receivedResponse.length, 32768, + assertEquals(32768, receivedResponse.length, "Unexpected response length"); - } finally { - client.close(); } assertTrue(handlerCF.get(10, TimeUnit.SECONDS), "Unexpected result"); diff --git a/test/jdk/java/net/httpclient/http3/H3MultipleConnectionsToSameHost.java b/test/jdk/java/net/httpclient/http3/H3MultipleConnectionsToSameHost.java index 14149da7815..67ac821b6f7 100644 --- a/test/jdk/java/net/httpclient/http3/H3MultipleConnectionsToSameHost.java +++ b/test/jdk/java/net/httpclient/http3/H3MultipleConnectionsToSameHost.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext * jdk.httpclient.test.lib.http2.Http2TestServer - * @run testng/othervm/timeout=360 -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=360 -XX:+CrashOnOutOfMemoryError * -Djdk.httpclient.quic.minPtoBackoffTime=60 * -Djdk.httpclient.quic.maxPtoBackoffTime=90 * -Djdk.httpclient.quic.maxPtoBackoff=10 @@ -52,7 +52,7 @@ * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext * jdk.httpclient.test.lib.http2.Http2TestServer - * @run testng/othervm/timeout=360 -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=360 -XX:+CrashOnOutOfMemoryError * -Djdk.httpclient.quic.minPtoBackoffTime=45 * -Djdk.httpclient.quic.maxPtoBackoffTime=60 * -Djdk.httpclient.quic.maxPtoBackoff=9 @@ -75,7 +75,7 @@ * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext * jdk.httpclient.test.lib.http2.Http2TestServer - * @run testng/othervm/timeout=360 -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=360 -XX:+CrashOnOutOfMemoryError * -Djdk.httpclient.quic.idleTimeout=120 * -Djdk.httpclient.keepalive.timeout.h3=120 * -Djdk.test.server.quic.idleTimeout=90 @@ -100,7 +100,7 @@ * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext * jdk.httpclient.test.lib.http2.Http2TestServer - * @run testng/othervm/timeout=360 -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=360 -XX:+CrashOnOutOfMemoryError * -Djdk.httpclient.quic.idleTimeout=120 * -Djdk.httpclient.keepalive.timeout.h3=120 * -Djdk.test.server.quic.idleTimeout=90 @@ -161,14 +161,15 @@ import javax.net.ssl.SSLContext; import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.internal.net.http.common.Utils; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.Assert; -import org.testng.annotations.Test; import static java.net.http.HttpClient.Version.HTTP_3; import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; import static jdk.internal.net.http.Http3ClientProperties.MAX_STREAM_LIMIT_WAIT_TIMEOUT; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + public class H3MultipleConnectionsToSameHost implements HttpServerAdapters { static HttpTestServer httpsServer; static HttpClient client = null; @@ -223,11 +224,11 @@ public class H3MultipleConnectionsToSameHost implements HttpServerAdapters { } public static void main(String[] args) throws Exception { - test(); + new H3MultipleConnectionsToSameHost().test(); } @Test - public static void test() throws Exception { + public void test() throws Exception { try { long prestart = System.nanoTime(); initialize(); @@ -244,7 +245,7 @@ public class H3MultipleConnectionsToSameHost implements HttpServerAdapters { .GET().build(); long start = System.nanoTime(); var resp = client.send(request, BodyHandlers.ofByteArrayConsumer(b-> {})); - Assert.assertEquals(resp.statusCode(), 200); + Assertions.assertEquals(200, resp.statusCode()); long elapsed = System.nanoTime() - start; System.out.println("First request took: " + elapsed + " nanos (" + TimeUnit.NANOSECONDS.toMillis(elapsed) + " ms)"); final int max = property("simpleget.requests", 50); @@ -298,7 +299,7 @@ public class H3MultipleConnectionsToSameHost implements HttpServerAdapters { } } - list.forEach((cf) -> Assert.assertEquals(cf.join().statusCode(), 200)); + list.forEach((cf) -> Assertions.assertEquals(200, cf.join().statusCode())); client.close(); } catch (Throwable tt) { System.err.println("tt caught"); diff --git a/test/jdk/java/net/httpclient/http3/H3PushCancel.java b/test/jdk/java/net/httpclient/http3/H3PushCancel.java index 324942b67d0..b9e15b7d8e5 100644 --- a/test/jdk/java/net/httpclient/http3/H3PushCancel.java +++ b/test/jdk/java/net/httpclient/http3/H3PushCancel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +25,7 @@ * @test * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer - * @run testng/othervm + * @run junit/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=errors,requests,responses,trace * -Djdk.httpclient.http3.maxConcurrentPushStreams=5 @@ -69,18 +69,19 @@ import java.util.function.Function; import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.internal.net.http.common.Utils; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; import static java.net.http.HttpOption.Http3DiscoveryMode.ANY; import static java.nio.charset.StandardCharsets.UTF_8; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; + +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class H3PushCancel implements HttpServerAdapters { - static Map PUSH_PROMISES = Map.of( + static final Map PUSH_PROMISES = Map.of( "/x/y/z/1", "the first push promise body", "/x/y/z/2", "the second push promise body", "/x/y/z/3", "the third push promise body", @@ -93,13 +94,13 @@ public class H3PushCancel implements HttpServerAdapters { ); static final String MAIN_RESPONSE_BODY = "the main response body"; - HttpTestServer server; - URI uri; - URI headURI; - ServerPushHandler pushHandler; + private static HttpTestServer server; + private static URI uri; + private static URI headURI; + private static ServerPushHandler pushHandler; - @BeforeTest - public void setup() throws Exception { + @BeforeAll + public static void setup() throws Exception { server = HttpTestServer.create(ANY, SimpleSSLContext.findSSLContext()); pushHandler = new ServerPushHandler(MAIN_RESPONSE_BODY, PUSH_PROMISES); server.addHandler(pushHandler, "/push/"); @@ -110,14 +111,14 @@ public class H3PushCancel implements HttpServerAdapters { headURI = new URI("https://" + server.serverAuthority() + "/head/x"); } - @AfterTest - public void teardown() { + @AfterAll + public static void teardown() { server.stop(); } static HttpResponse assert200ResponseCode(HttpResponse response) { - assertEquals(response.statusCode(), 200); - assertEquals(response.version(), Version.HTTP_3); + assertEquals(200, response.statusCode()); + assertEquals(Version.HTTP_3, response.version()); return response; } @@ -125,8 +126,8 @@ public class H3PushCancel implements HttpServerAdapters { HttpRequest headRequest = HttpRequest.newBuilder(headURI) .HEAD().version(Version.HTTP_2).build(); var headResponse = client.send(headRequest, BodyHandlers.ofString()); - assertEquals(headResponse.statusCode(), 200); - assertEquals(headResponse.version(), Version.HTTP_2); + assertEquals(200, headResponse.statusCode()); + assertEquals(Version.HTTP_2, headResponse.version()); } @Test @@ -173,14 +174,14 @@ public class H3PushCancel implements HttpServerAdapters { promises.putIfAbsent(main.request(), CompletableFuture.completedFuture(main)); promises.forEach((request, value) -> { HttpResponse response = value.join(); - assertEquals(response.statusCode(), 200); + assertEquals(200, response.statusCode()); if (PUSH_PROMISES.containsKey(request.uri().getPath())) { - assertEquals(response.body(), PUSH_PROMISES.get(request.uri().getPath())); + assertEquals(PUSH_PROMISES.get(request.uri().getPath()), response.body()); } else { - assertEquals(response.body(), MAIN_RESPONSE_BODY); + assertEquals(MAIN_RESPONSE_BODY, response.body()); } }); - assertEquals(promises.size(), Math.min(PUSH_PROMISES.size(), maxPushes) + 1); + assertEquals(Math.min(PUSH_PROMISES.size(), maxPushes) + 1, promises.size()); promises.clear(); } @@ -190,12 +191,12 @@ public class H3PushCancel implements HttpServerAdapters { client.sendAsync(HttpRequest.newBuilder(uri).build(), BodyHandlers.ofString()) .thenApply(H3PushCancel::assert200ResponseCode) .thenApply(HttpResponse::body) - .thenAccept(body -> assertEquals(body, MAIN_RESPONSE_BODY)) + .thenAccept(body -> assertEquals(MAIN_RESPONSE_BODY, body)) .join(); } catch (CompletionException c) { throw new AssertionError(c.getCause()); } - assertEquals(promises.size(), 0); + assertEquals(0, promises.size()); // Send with no promise handler, but use pushId bigger than allowed. // This should cause the connection to get closed @@ -207,7 +208,7 @@ public class H3PushCancel implements HttpServerAdapters { client.sendAsync(bigger, BodyHandlers.ofString()) .thenApply(H3PushCancel::assert200ResponseCode) .thenApply(HttpResponse::body) - .thenAccept(body -> assertEquals(body, MAIN_RESPONSE_BODY)) + .thenAccept(body -> assertEquals(MAIN_RESPONSE_BODY, body)) .join(); throw new AssertionError("Expected IOException not thrown"); } catch (CompletionException c) { @@ -226,7 +227,7 @@ public class H3PushCancel implements HttpServerAdapters { throw new AssertionError("Unexpected exception: " + c.getCause(), c.getCause()); } } - assertEquals(promises.size(), 0); + assertEquals(0, promises.size()); // the next time around we should have a new connection // so we can restart from scratch @@ -315,16 +316,16 @@ public class H3PushCancel implements HttpServerAdapters { promises.putIfAbsent(main.request(), CompletableFuture.completedFuture(main)); promises.forEach((request, value) -> { HttpResponse response = value.join(); - assertEquals(response.statusCode(), 200); + assertEquals(200, response.statusCode()); if (PUSH_PROMISES.containsKey(request.uri().getPath())) { - assertEquals(response.body(), PUSH_PROMISES.get(request.uri().getPath())); + assertEquals(PUSH_PROMISES.get(request.uri().getPath()), response.body()); } else { - assertEquals(response.body(), MAIN_RESPONSE_BODY); + assertEquals(MAIN_RESPONSE_BODY, response.body()); } }); int expectedPushes = Math.min(PUSH_PROMISES.size(), maxPushes) + 1; if (i == 0) expectedPushes--; // pushId == 1 was cancelled - assertEquals(promises.size(), expectedPushes); + assertEquals(expectedPushes, promises.size()); promises.clear(); } @@ -334,12 +335,12 @@ public class H3PushCancel implements HttpServerAdapters { client.sendAsync(HttpRequest.newBuilder(uri).build(), BodyHandlers.ofString()) .thenApply(H3PushCancel::assert200ResponseCode) .thenApply(HttpResponse::body) - .thenAccept(body -> assertEquals(body, MAIN_RESPONSE_BODY)) + .thenAccept(body -> assertEquals(MAIN_RESPONSE_BODY, body)) .join(); } catch (CompletionException c) { throw new AssertionError(c.getCause()); } - assertEquals(promises.size(), 0); + assertEquals(0, promises.size()); // Send with no promise handler, but use pushId bigger than allowed. // This should cause the connection to get closed @@ -351,7 +352,7 @@ public class H3PushCancel implements HttpServerAdapters { client.sendAsync(bigger, BodyHandlers.ofString()) .thenApply(H3PushCancel::assert200ResponseCode) .thenApply(HttpResponse::body) - .thenAccept(body ->assertEquals(body, MAIN_RESPONSE_BODY)) + .thenAccept(body ->assertEquals(MAIN_RESPONSE_BODY, body)) .join(); throw new AssertionError("Expected IOException not thrown"); } catch (CompletionException c) { @@ -370,7 +371,7 @@ public class H3PushCancel implements HttpServerAdapters { throw new AssertionError("Unexpected exception: " + c.getCause(), c.getCause()); } } - assertEquals(promises.size(), 0); + assertEquals(0, promises.size()); // the next time around we should have a new connection // so we can restart from scratch @@ -379,7 +380,7 @@ public class H3PushCancel implements HttpServerAdapters { errors.forEach(t -> t.printStackTrace(System.out)); var error = errors.stream().findFirst().orElse(null); if (error != null) throw error; - assertEquals(notified.size(), 0, "Unexpected notification: " + notified); + assertEquals(0, notified.size(), "Unexpected notification: " + notified); } } diff --git a/test/jdk/java/net/httpclient/http3/H3RedirectTest.java b/test/jdk/java/net/httpclient/http3/H3RedirectTest.java index 0a5546bc1c1..67a7d99fa71 100644 --- a/test/jdk/java/net/httpclient/http3/H3RedirectTest.java +++ b/test/jdk/java/net/httpclient/http3/H3RedirectTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +28,7 @@ * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.common.TestUtil * jdk.httpclient.test.lib.common.HttpServerAdapters * @compile ../ReferenceTracker.java - * @run testng/othervm + * @run junit/othervm * -Djdk.httpclient.HttpClient.log=frames,ssl,requests,responses,errors * -Djdk.internal.httpclient.debug=true * H3RedirectTest @@ -50,11 +50,12 @@ import javax.net.ssl.SSLContext; import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.annotations.Test; import static java.net.http.HttpClient.Version.HTTP_3; import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; +import org.junit.jupiter.api.Test; + public class H3RedirectTest implements HttpServerAdapters { static int httpPort; private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); @@ -135,7 +136,7 @@ public class H3RedirectTest implements HttpServerAdapters { } @Test - public static void test() throws Exception { + public void test() throws Exception { try { initialize(); simpleTest(); diff --git a/test/jdk/java/net/httpclient/http3/H3ServerPush.java b/test/jdk/java/net/httpclient/http3/H3ServerPush.java index 83f68a15579..50aa817b155 100644 --- a/test/jdk/java/net/httpclient/http3/H3ServerPush.java +++ b/test/jdk/java/net/httpclient/http3/H3ServerPush.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * jdk.httpclient.test.lib.http2.PushHandler * jdk.test.lib.Utils * jdk.test.lib.net.SimpleSSLContext - * @run testng/othervm/timeout=960 + * @run junit/othervm/timeout=960 * -Djdk.httpclient.HttpClient.log=errors,requests,headers * -Djdk.internal.httpclient.debug=false * H3ServerPush @@ -66,13 +66,14 @@ import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.httpclient.test.lib.http2.PushHandler; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; import static java.nio.charset.StandardCharsets.UTF_8; import static jdk.test.lib.Utils.createTempFileOfSize; -import static org.testng.Assert.assertEquals; + +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class H3ServerPush implements HttpServerAdapters { @@ -81,14 +82,14 @@ public class H3ServerPush implements HttpServerAdapters { static final int LOOPS = 13; static final int FILE_SIZE = 512 * 1024 + 343; - static Path tempFile; + private static Path tempFile; - HttpTestServer server; - URI uri; - URI headURI; + private static HttpTestServer server; + private static URI uri; + private static URI headURI; - @BeforeTest - public void setup() throws Exception { + @BeforeAll + public static void setup() throws Exception { tempFile = createTempFileOfSize(CLASS_NAME, ".dat", FILE_SIZE); var sslContext = SimpleSSLContext.findSSLContext(); var h2Server = new Http2TestServer(true, sslContext); @@ -109,12 +110,12 @@ public class H3ServerPush implements HttpServerAdapters { HttpRequest headRequest = HttpRequest.newBuilder(headURI) .HEAD().version(Version.HTTP_2).build(); var headResponse = client.send(headRequest, BodyHandlers.ofString()); - assertEquals(headResponse.statusCode(), 200); - assertEquals(headResponse.version(), Version.HTTP_2); + assertEquals(200, headResponse.statusCode()); + assertEquals(Version.HTTP_2, headResponse.version()); } - @AfterTest - public void teardown() { + @AfterAll + public static void teardown() { server.stop(); } @@ -144,7 +145,7 @@ public class H3ServerPush implements HttpServerAdapters { resultMap.put(request, cf); System.out.println("waiting for response"); var resp = cf.join(); - assertEquals(resp.version(), Version.HTTP_3); + assertEquals(Version.HTTP_3, resp.version()); var seen = new HashSet<>(); resultMap.forEach((k, v) -> { if (seen.add(k)) { @@ -158,16 +159,16 @@ public class H3ServerPush implements HttpServerAdapters { for (HttpRequest r : resultMap.keySet()) { System.out.println("Checking " + r); HttpResponse response = resultMap.get(r).join(); - assertEquals(response.statusCode(), 200); - assertEquals(response.version(), Version.HTTP_3); - assertEquals(response.body(), tempFileAsString); + assertEquals(200, response.statusCode()); + assertEquals(Version.HTTP_3, response.version()); + assertEquals(tempFileAsString, response.body()); } resultMap.forEach((k, v) -> { if (seen.add(k)) { System.out.println("Got " + v.join()); } }); - assertEquals(resultMap.size(), LOOPS + 1); + assertEquals(LOOPS + 1, resultMap.size()); } } @@ -194,11 +195,11 @@ public class H3ServerPush implements HttpServerAdapters { System.err.println("results.size: " + resultMap.size()); for (HttpRequest r : resultMap.keySet()) { HttpResponse response = resultMap.get(r).join(); - assertEquals(response.statusCode(), 200); - assertEquals(response.version(), Version.HTTP_3); - assertEquals(response.body(), tempFileAsString); + assertEquals(200, response.statusCode()); + assertEquals(Version.HTTP_3, response.version()); + assertEquals(tempFileAsString, response.body()); } - assertEquals(resultMap.size(), LOOPS + 1); + assertEquals(LOOPS + 1, resultMap.size()); } } @@ -242,12 +243,12 @@ public class H3ServerPush implements HttpServerAdapters { resultsMap.put(request, cf); for (HttpRequest r : resultsMap.keySet()) { HttpResponse response = resultsMap.get(r).join(); - assertEquals(response.statusCode(), 200); - assertEquals(response.version(), Version.HTTP_3); + assertEquals(200, response.statusCode()); + assertEquals(Version.HTTP_3, response.version()); String fileAsString = Files.readString(response.body()); - assertEquals(fileAsString, tempFileAsString); + assertEquals(tempFileAsString, fileAsString); } - assertEquals(resultsMap.size(), LOOPS + 1); + assertEquals(LOOPS + 1, resultsMap.size()); } } @@ -274,12 +275,12 @@ public class H3ServerPush implements HttpServerAdapters { resultsMap.put(request, cf); for (HttpRequest r : resultsMap.keySet()) { HttpResponse response = resultsMap.get(r).join(); - assertEquals(response.statusCode(), 200); - assertEquals(response.version(), Version.HTTP_3); + assertEquals(200, response.statusCode()); + assertEquals(Version.HTTP_3, response.version()); String fileAsString = Files.readString(response.body()); - assertEquals(fileAsString, tempFileAsString); + assertEquals(tempFileAsString, fileAsString); } - assertEquals(resultsMap.size(), LOOPS + 1); + assertEquals(LOOPS + 1, resultsMap.size()); } } @@ -340,13 +341,13 @@ public class H3ServerPush implements HttpServerAdapters { resultsMap.put(request, cf); for (HttpRequest r : resultsMap.keySet()) { HttpResponse response = resultsMap.get(r).join(); - assertEquals(response.statusCode(), 200); - assertEquals(response.version(), Version.HTTP_3); + assertEquals(200, response.statusCode()); + assertEquals(Version.HTTP_3, response.version()); byte[] ba = byteArrayConsumerMap.get(r).getAccumulatedBytes(); String result = new String(ba, UTF_8); - assertEquals(result, tempFileAsString); + assertEquals(tempFileAsString, result); } - assertEquals(resultsMap.size(), LOOPS + 1); + assertEquals(LOOPS + 1, resultsMap.size()); } } @@ -384,13 +385,13 @@ public class H3ServerPush implements HttpServerAdapters { resultsMap.put(request, cf); for (HttpRequest r : resultsMap.keySet()) { HttpResponse response = resultsMap.get(r).join(); - assertEquals(response.statusCode(), 200); - assertEquals(response.version(), Version.HTTP_3); + assertEquals(200, response.statusCode()); + assertEquals(Version.HTTP_3, response.version()); byte[] ba = byteArrayConsumerMap.get(r).getAccumulatedBytes(); String result = new String(ba, UTF_8); - assertEquals(result, tempFileAsString); + assertEquals(tempFileAsString, result); } - assertEquals(resultsMap.size(), LOOPS + 1); + assertEquals(LOOPS + 1, resultsMap.size()); } } } diff --git a/test/jdk/java/net/httpclient/http3/H3ServerPushCancel.java b/test/jdk/java/net/httpclient/http3/H3ServerPushCancel.java index 312b9ac507d..b34e2a1567e 100644 --- a/test/jdk/java/net/httpclient/http3/H3ServerPushCancel.java +++ b/test/jdk/java/net/httpclient/http3/H3ServerPushCancel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +25,7 @@ * @test * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer - * @run testng/othervm + * @run junit/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=errors,requests,responses,trace * -Djdk.httpclient.http3.maxConcurrentPushStreams=45 @@ -73,9 +73,6 @@ import java.util.function.Supplier; import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.internal.net.http.common.Utils; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; import static java.net.http.HttpClient.Version.HTTP_2; import static java.net.http.HttpClient.Version.HTTP_3; @@ -83,10 +80,14 @@ import static java.net.http.HttpOption.Http3DiscoveryMode.ALT_SVC; import static java.net.http.HttpOption.Http3DiscoveryMode.ANY; import static java.net.http.HttpOption.H3_DISCOVERY; import static java.nio.charset.StandardCharsets.UTF_8; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; + +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class H3ServerPushCancel implements HttpServerAdapters { @@ -95,7 +96,7 @@ public class H3ServerPushCancel implements HttpServerAdapters { static final PrintStream err = System.err; static final PrintStream out = System.out; - static Map PUSH_PROMISES = Map.of( + static final Map PUSH_PROMISES = Map.of( "/x/y/z/1", "the first push promise body", "/x/y/z/2", "the second push promise body", "/x/y/z/3", "the third push promise body", @@ -109,13 +110,13 @@ public class H3ServerPushCancel implements HttpServerAdapters { static final String MAIN_RESPONSE_BODY = "the main response body"; static final int REQUESTS = 5; - HttpTestServer server; - URI uri; - URI headURI; - ServerPushHandler pushHandler; + private static HttpTestServer server; + private static URI uri; + private static URI headURI; + private static ServerPushHandler pushHandler; - @BeforeTest - public void setup() throws Exception { + @BeforeAll + public static void setup() throws Exception { server = HttpTestServer.create(ANY, SimpleSSLContext.findSSLContext()); pushHandler = new ServerPushHandler(MAIN_RESPONSE_BODY, PUSH_PROMISES); server.addHandler(pushHandler, "/push/"); @@ -126,14 +127,14 @@ public class H3ServerPushCancel implements HttpServerAdapters { headURI = new URI("https://" + server.serverAuthority() + "/head/x"); } - @AfterTest - public void teardown() { + @AfterAll + public static void teardown() { server.stop(); } static HttpResponse assert200ResponseCode(HttpResponse response) { - assertEquals(response.statusCode(), 200); - assertEquals(response.version(), HTTP_3); + assertEquals(200, response.statusCode()); + assertEquals(HTTP_3, response.version()); return response; } @@ -141,8 +142,8 @@ public class H3ServerPushCancel implements HttpServerAdapters { HttpRequest headRequest = HttpRequest.newBuilder(headURI) .HEAD().version(HTTP_2).build(); var headResponse = client.send(headRequest, BodyHandlers.ofString()); - assertEquals(headResponse.statusCode(), 200); - assertEquals(headResponse.version(), HTTP_2); + assertEquals(200, headResponse.statusCode()); + assertEquals(HTTP_2, headResponse.version()); } static final class TestPushPromiseHandler implements PushPromiseHandler { @@ -283,14 +284,14 @@ public class H3ServerPushCancel implements HttpServerAdapters { throw new AssertionError("Unexpected message: " + msg, ex); } } else { - assertEquals(join(value).body(), PUSH_PROMISES.get(request.uri().getPath())); + assertEquals(PUSH_PROMISES.get(request.uri().getPath()), join(value).body()); } expectedPushIds.add(pushId); - } else assertEquals(pushId.getClass(), Http3PushId.class); + } else assertEquals(Http3PushId.class, pushId.getClass()); } else { HttpResponse response = join(value); - assertEquals(response.statusCode(), 200); - assertEquals(response.body(), MAIN_RESPONSE_BODY); + assertEquals(200, response.statusCode()); + assertEquals(MAIN_RESPONSE_BODY, response.body()); } }); @@ -311,12 +312,12 @@ public class H3ServerPushCancel implements HttpServerAdapters { client.sendAsync(HttpRequest.newBuilder(uri).build(), BodyHandlers.ofString()) .thenApply(H3ServerPushCancel::assert200ResponseCode) .thenApply(HttpResponse::body) - .thenAccept(body -> assertEquals(body, MAIN_RESPONSE_BODY)) + .thenAccept(body -> assertEquals(MAIN_RESPONSE_BODY, body)) .join(); } catch (CompletionException c) { throw new AssertionError(c.getCause()); } - assertEquals(promises.size(), 0); + assertEquals(0, promises.size()); // Send with no promise handler, but use pushId bigger than allowed. // This should cause the connection to get closed @@ -328,7 +329,7 @@ public class H3ServerPushCancel implements HttpServerAdapters { client.sendAsync(bigger, BodyHandlers.ofString()) .thenApply(H3ServerPushCancel::assert200ResponseCode) .thenApply(HttpResponse::body) - .thenAccept(body -> assertEquals(body, MAIN_RESPONSE_BODY)) + .thenAccept(body -> assertEquals(MAIN_RESPONSE_BODY, body)) .join(); throw new AssertionError("Expected IOException not thrown"); } catch (CompletionException c) { @@ -347,7 +348,7 @@ public class H3ServerPushCancel implements HttpServerAdapters { throw new AssertionError("Unexpected exception: " + c.getCause(), c.getCause()); } } - assertEquals(promises.size(), 0); + assertEquals(0, promises.size()); // the next time around we should have a new connection, // so we can restart from scratch @@ -408,7 +409,7 @@ public class H3ServerPushCancel implements HttpServerAdapters { // excluding those that got cancelled, // we should have received REQUEST-1 notifications // per push promise and per connection - assertEquals(count, (PUSH_PROMISES.size()-3)*2*(REQUESTS-1), + assertEquals((PUSH_PROMISES.size()-3)*2*(REQUESTS-1), count, "Unexpected notification: " + notified); } } diff --git a/test/jdk/java/net/httpclient/http3/H3ServerPushWithDiffTypes.java b/test/jdk/java/net/httpclient/http3/H3ServerPushWithDiffTypes.java index d00012826ef..a863db43c29 100644 --- a/test/jdk/java/net/httpclient/http3/H3ServerPushWithDiffTypes.java +++ b/test/jdk/java/net/httpclient/http3/H3ServerPushWithDiffTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +25,7 @@ * @test * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer - * @run testng/othervm + * @run junit/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=errors,requests,responses * H3ServerPushWithDiffTypes @@ -65,11 +65,12 @@ import java.util.function.BiPredicate; import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.annotations.Test; import static java.net.http.HttpOption.Http3DiscoveryMode.ANY; import static java.nio.charset.StandardCharsets.UTF_8; -import static org.testng.Assert.assertEquals; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; public class H3ServerPushWithDiffTypes implements HttpServerAdapters { @@ -89,8 +90,8 @@ public class H3ServerPushWithDiffTypes implements HttpServerAdapters { HttpRequest headRequest = HttpRequest.newBuilder(headURI) .HEAD().version(Version.HTTP_2).build(); var headResponse = client.send(headRequest, BodyHandlers.ofString()); - assertEquals(headResponse.statusCode(), 200); - assertEquals(headResponse.version(), Version.HTTP_2); + assertEquals(200, headResponse.statusCode()); + assertEquals(Version.HTTP_2, headResponse.version()); } @Test @@ -127,13 +128,13 @@ public class H3ServerPushWithDiffTypes implements HttpServerAdapters { results.put(request, cf); cf.join(); - assertEquals(results.size(), PUSH_PROMISES.size() + 1); + assertEquals(PUSH_PROMISES.size() + 1, results.size()); for (HttpRequest r : results.keySet()) { URI u = r.uri(); var resp = results.get(r).get(); - assertEquals(resp.statusCode(), 200); - assertEquals(resp.version(), Version.HTTP_3); + assertEquals(200, resp.statusCode()); + assertEquals(Version.HTTP_3, resp.version()); BodyAndType body = resp.body(); String result; // convert all body types to String for easier comparison @@ -153,7 +154,7 @@ public class H3ServerPushWithDiffTypes implements HttpServerAdapters { String expected = PUSH_PROMISES.get(r.uri().getPath()); if (expected == null) expected = "the main response body"; - assertEquals(result, expected); + assertEquals(expected, result); } } } diff --git a/test/jdk/java/net/httpclient/http3/H3SimpleGet.java b/test/jdk/java/net/httpclient/http3/H3SimpleGet.java index 3745c32afbf..ae113322cd3 100644 --- a/test/jdk/java/net/httpclient/http3/H3SimpleGet.java +++ b/test/jdk/java/net/httpclient/http3/H3SimpleGet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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,14 @@ * @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/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError * H3SimpleGet - * @run testng/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError * -Djdk.httpclient.retryOnStreamlimit=20 * -Djdk.httpclient.redirects.retrylimit=21 * -Dsimpleget.repeat=1 -Dsimpleget.chunks=1 -Dsimpleget.requests=1000 * H3SimpleGet - * @run testng/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError * -Dsimpleget.requests=150 * -Dsimpleget.chunks=16384 * -Djdk.httpclient.retryOnStreamlimit=5 @@ -53,14 +53,14 @@ * @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/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError * H3SimpleGet - * @run testng/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError * -Djdk.httpclient.retryOnStreamlimit=20 * -Djdk.httpclient.redirects.retrylimit=21 * -Dsimpleget.repeat=1 -Dsimpleget.chunks=1 -Dsimpleget.requests=1000 * H3SimpleGet - * @run testng/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError * -Dsimpleget.requests=150 * -Dsimpleget.chunks=16384 * -Djdk.httpclient.retryOnStreamlimit=5 @@ -77,16 +77,16 @@ * @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/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError * -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations * H3SimpleGet - * @run testng/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError * -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations * -Djdk.httpclient.retryOnStreamlimit=20 * -Djdk.httpclient.redirects.retrylimit=21 * -Dsimpleget.repeat=1 -Dsimpleget.chunks=1 -Dsimpleget.requests=1000 * H3SimpleGet - * @run testng/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError * -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations * -Dsimpleget.requests=150 * -Dsimpleget.chunks=16384 @@ -103,16 +103,16 @@ * @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/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError * -Djdk.internal.httpclient.quic.useNioSelector=true * H3SimpleGet - * @run testng/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError * -Djdk.internal.httpclient.quic.useNioSelector=true * -Djdk.httpclient.retryOnStreamlimit=20 * -Djdk.httpclient.redirects.retrylimit=21 * -Dsimpleget.repeat=1 -Dsimpleget.chunks=1 -Dsimpleget.requests=1000 * H3SimpleGet - * @run testng/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError * -Djdk.internal.httpclient.quic.useNioSelector=true * -Dsimpleget.requests=150 * -Dsimpleget.chunks=16384 @@ -129,16 +129,16 @@ * @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/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError * -Djdk.internal.httpclient.quic.useNioSelector=true * H3SimpleGet - * @run testng/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError * -Djdk.internal.httpclient.quic.useNioSelector=true * -Djdk.httpclient.retryOnStreamlimit=20 * -Djdk.httpclient.redirects.retrylimit=21 * -Dsimpleget.repeat=1 -Dsimpleget.chunks=1 -Dsimpleget.requests=1000 * H3SimpleGet - * @run testng/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError + * @run junit/othervm/timeout=480 -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError * -Djdk.internal.httpclient.quic.useNioSelector=true * -Dsimpleget.requests=150 * -Dsimpleget.chunks=16384 @@ -154,7 +154,7 @@ * @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/timeout=480 -Djdk.internal.httpclient.quic.congestionController=reno + * @run junit/othervm/timeout=480 -Djdk.internal.httpclient.quic.congestionController=reno * H3SimpleGet * @summary send multiple GET requests using Reno congestion controller */ @@ -198,13 +198,14 @@ import javax.net.ssl.SSLContext; import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.Assert; -import org.testng.annotations.Test; import static java.net.http.HttpClient.Version.HTTP_3; import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + public class H3SimpleGet implements HttpServerAdapters { static HttpTestServer httpsServer; static HttpClient client = null; @@ -261,13 +262,13 @@ public class H3SimpleGet implements HttpServerAdapters { } public static void main(String[] args) throws Exception { - test(); + new H3SimpleGet().test(); } static volatile boolean waitBeforeTest = false; @Test - public static void test() throws Exception { + public void test() throws Exception { try { if (waitBeforeTest) { Thread.sleep(20000); @@ -283,7 +284,7 @@ public class H3SimpleGet implements HttpServerAdapters { .GET().build(); long start = System.nanoTime(); var resp = client.send(request, BodyHandlers.ofByteArrayConsumer(b-> {})); - Assert.assertEquals(resp.statusCode(), 200); + Assertions.assertEquals(200, resp.statusCode()); long elapsed = System.nanoTime() - start; System.out.println("Stat: First request took: " + elapsed + " nanos (" + TimeUnit.NANOSECONDS.toMillis(elapsed) + " ms)"); @@ -314,7 +315,7 @@ public class H3SimpleGet implements HttpServerAdapters { + connections.size() + " connections"); } } - list.forEach((cf) -> Assert.assertEquals(cf.join().statusCode(), 200)); + list.forEach((cf) -> Assertions.assertEquals(200, cf.join().statusCode())); } catch (Throwable tt) { System.err.println("tt caught"); tt.printStackTrace(); diff --git a/test/jdk/java/net/httpclient/http3/H3SimplePost.java b/test/jdk/java/net/httpclient/http3/H3SimplePost.java index 4cf46988873..0294f2f69da 100644 --- a/test/jdk/java/net/httpclient/http3/H3SimplePost.java +++ b/test/jdk/java/net/httpclient/http3/H3SimplePost.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * @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/timeout=480 H3SimplePost + * @run junit/othervm/timeout=480 H3SimplePost */ // -Djdk.httpclient.HttpClient.log=requests,errors,quic // -Djdk.httpclient.quic.defaultMTU=64000 @@ -37,8 +37,6 @@ import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.Assert; -import org.testng.annotations.Test; import javax.net.ssl.SSLContext; import java.io.IOException; @@ -61,6 +59,9 @@ import static java.net.http.HttpClient.Version.HTTP_3; import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + public class H3SimplePost implements HttpServerAdapters { static HttpTestServer httpsServer; static HttpClient client = null; @@ -115,11 +116,11 @@ public class H3SimplePost implements HttpServerAdapters { } public static void main(String[] args) throws Exception { - test(); + new H3SimplePost().test(); } @Test - public static void test() throws Exception { + public void test() throws Exception { try { long prestart = System.nanoTime(); initialize(); @@ -140,7 +141,7 @@ public class H3SimplePost implements HttpServerAdapters { .build(); long start = System.nanoTime(); var resp = client.send(getRequest, BodyHandlers.ofByteArrayConsumer(b-> {})); - Assert.assertEquals(resp.statusCode(), 200); + Assertions.assertEquals(200, resp.statusCode()); long elapsed = System.nanoTime() - start; System.out.println("First GET request took: " + elapsed + " nanos (" + TimeUnit.NANOSECONDS.toMillis(elapsed) + " ms)"); final int max = 50; @@ -155,7 +156,7 @@ public class H3SimplePost implements HttpServerAdapters { System.out.println("Next " + max + " POST requests took: " + elapsed2 + " nanos (" + TimeUnit.NANOSECONDS.toMillis(elapsed2) + "ms for " + max + " requests): " + elapsed2 / max + " nanos per request (" + TimeUnit.NANOSECONDS.toMillis(elapsed2) / max + " ms)"); - list.forEach((cf) -> Assert.assertEquals(cf.join().statusCode(), 200)); + list.forEach((cf) -> Assertions.assertEquals(200, cf.join().statusCode())); } catch (Throwable tt) { System.err.println("tt caught"); tt.printStackTrace(); diff --git a/test/jdk/java/net/httpclient/http3/H3SimpleTest.java b/test/jdk/java/net/httpclient/http3/H3SimpleTest.java index 1880d436501..4258f3bac73 100644 --- a/test/jdk/java/net/httpclient/http3/H3SimpleTest.java +++ b/test/jdk/java/net/httpclient/http3/H3SimpleTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * 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,16 +32,17 @@ import javax.net.ssl.SSLContext; import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; import static java.net.http.HttpClient.Builder.NO_PROXY; import static java.net.http.HttpClient.Version.HTTP_3; import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + /* * @test * @summary Basic test to verify that simple GET/POST/HEAD @@ -50,21 +51,21 @@ import static java.net.http.HttpOption.H3_DISCOVERY; * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.test.lib.net.SimpleSSLContext * jdk.httpclient.test.lib.common.HttpServerAdapters - * @run testng/othervm + * @run junit/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=requests,responses,errors * H3SimpleTest - * @run testng/othervm + * @run junit/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=requests,responses,errors * -Djava.net.preferIPv6Addresses=true * H3SimpleTest - * @run testng/othervm + * @run junit/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=requests,responses,errors * -Djava.net.preferIPv4Stack=true * H3SimpleTest - * @run testng/othervm + * @run junit/othervm * -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=requests,responses,errors * -Djdk.internal.httpclient.quic.congestionController=reno @@ -74,11 +75,11 @@ import static java.net.http.HttpOption.H3_DISCOVERY; public class H3SimpleTest implements HttpServerAdapters { private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); - private HttpTestServer h3Server; - private String requestURI; + private static HttpTestServer h3Server; + private static String requestURI; - @BeforeClass - public void beforeClass() throws Exception { + @BeforeAll + public static void beforeClass() throws Exception { // create an H3 only server h3Server = HttpTestServer.create(HTTP_3_URI_ONLY, sslContext); h3Server.addHandler((exchange) -> exchange.sendResponseHeaders(200, 0), "/hello"); @@ -87,8 +88,8 @@ public class H3SimpleTest implements HttpServerAdapters { requestURI = "https://" + h3Server.serverAuthority() + "/hello"; } - @AfterClass - public void afterClass() throws Exception { + @AfterAll + public static void afterClass() throws Exception { if (h3Server != null) { System.out.println("Stopping server " + h3Server.getAddress()); h3Server.stop(); @@ -113,18 +114,18 @@ public class H3SimpleTest implements HttpServerAdapters { final HttpRequest req1 = reqBuilder.copy().GET().build(); System.out.println("Issuing request: " + req1); final HttpResponse resp1 = client.send(req1, BodyHandlers.discarding()); - Assert.assertEquals(resp1.statusCode(), 200, "unexpected response code for GET request"); + Assertions.assertEquals(200, resp1.statusCode(), "unexpected response code for GET request"); // POST final HttpRequest req2 = reqBuilder.copy().POST(BodyPublishers.ofString("foo")).build(); System.out.println("Issuing request: " + req2); final HttpResponse resp2 = client.send(req2, BodyHandlers.discarding()); - Assert.assertEquals(resp2.statusCode(), 200, "unexpected response code for POST request"); + Assertions.assertEquals(200, resp2.statusCode(), "unexpected response code for POST request"); // HEAD final HttpRequest req3 = reqBuilder.copy().HEAD().build(); System.out.println("Issuing request: " + req3); final HttpResponse resp3 = client.send(req3, BodyHandlers.discarding()); - Assert.assertEquals(resp3.statusCode(), 200, "unexpected response code for HEAD request"); + Assertions.assertEquals(200, resp3.statusCode(), "unexpected response code for HEAD request"); } } diff --git a/test/jdk/java/net/httpclient/http3/H3StopSendingTest.java b/test/jdk/java/net/httpclient/http3/H3StopSendingTest.java index 5b017c15d9b..86b12a1dae6 100644 --- a/test/jdk/java/net/httpclient/http3/H3StopSendingTest.java +++ b/test/jdk/java/net/httpclient/http3/H3StopSendingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +26,7 @@ * @summary Verifies that the client reacts correctly to the receipt of a STOP_SENDING frame. * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.httpclient.test.lib.common.HttpServerAdapters - * @run testng/othervm/timeout=40 -Djdk.internal.httpclient.debug=true -Djdk.httpclient.HttpClient.log=trace,errors,headers + * @run junit/othervm/timeout=40 -Djdk.internal.httpclient.debug=true -Djdk.httpclient.HttpClient.log=trace,errors,headers * H3StopSendingTest */ @@ -35,9 +35,6 @@ import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestHandler; import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestServer; import jdk.test.lib.net.SimpleSSLContext; import jdk.internal.net.http.http3.Http3Error; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; import javax.net.ssl.SSLContext; import java.io.IOException; @@ -53,14 +50,18 @@ import java.util.concurrent.ExecutionException; import static java.net.http.HttpClient.Builder.NO_PROXY; import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; -import static org.testng.Assert.*; + +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class H3StopSendingTest { - HttpTestServer h3TestServer; - HttpRequest postRequestNoError, postRequestError; - HttpRequest postRequestNoErrorWithData, postRequestErrorWithData; - URI h3TestServerUriNoError, h3TestServerUriError; + private static HttpTestServer h3TestServer; + private static HttpRequest postRequestNoError, postRequestError; + private static HttpRequest postRequestNoErrorWithData, postRequestErrorWithData; + private static URI h3TestServerUriNoError, h3TestServerUriError; private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); static final String TEST_ROOT_PATH = "/h3_stop_sending_test"; @@ -81,13 +82,13 @@ public class H3StopSendingTest { err.println(resp.headers()); err.println(resp.body()); err.println(resp.statusCode()); - assertEquals(resp.statusCode(), 200); + assertEquals(200, resp.statusCode()); resp = client.sendAsync(postRequestNoErrorWithData, HttpResponse.BodyHandlers.ofString()).get(); err.println(resp.headers()); err.println(resp.body()); err.println(resp.statusCode()); - assertEquals(resp.statusCode(), 200); - assertEquals(resp.body(), RESPONSE_MESSAGE.repeat(MESSAGE_REPEAT)); + assertEquals(200, resp.statusCode()); + assertEquals(RESPONSE_MESSAGE.repeat(MESSAGE_REPEAT), resp.body()); } } @@ -125,8 +126,8 @@ public class H3StopSendingTest { } } - @BeforeTest - public void setup() throws IOException { + @BeforeAll + public static void setup() throws IOException { h3TestServer = HttpTestServer.create(HTTP_3_URI_ONLY, sslContext); h3TestServer.addHandler(new ServerRequestStopSendingHandler(), TEST_ROOT_PATH); @@ -162,8 +163,8 @@ public class H3StopSendingTest { .build(); } - @AfterTest - public void afterTest() { + @AfterAll + public static void afterTest() { h3TestServer.stop(); } diff --git a/test/jdk/java/net/httpclient/http3/H3StreamLimitReachedTest.java b/test/jdk/java/net/httpclient/http3/H3StreamLimitReachedTest.java index a4524b9ae5e..1ac4a750d77 100644 --- a/test/jdk/java/net/httpclient/http3/H3StreamLimitReachedTest.java +++ b/test/jdk/java/net/httpclient/http3/H3StreamLimitReachedTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +46,7 @@ * jdk.test.lib.Asserts * jdk.test.lib.Utils * jdk.test.lib.net.SimpleSSLContext - * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors,http3,quic:control + * @run junit/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors,http3,quic:control * -Djdk.internal.httpclient.debug=false * -Djdk.internal.httpclient.quic.maxBidiStreams=1 * H3StreamLimitReachedTest @@ -77,7 +77,7 @@ * jdk.test.lib.Asserts * jdk.test.lib.Utils * jdk.test.lib.net.SimpleSSLContext - * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors,http3,quic:control + * @run junit/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors,http3,quic:control * -Djdk.internal.httpclient.debug=false * -Djdk.internal.httpclient.quic.maxBidiStreams=1 * -Djdk.httpclient.http3.maxStreamLimitTimeout=0 @@ -114,7 +114,6 @@ import jdk.httpclient.test.lib.http2.Http2TestExchange; import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.httpclient.test.lib.http3.Http3TestServer; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.annotations.Test; import static java.net.http.HttpClient.Version.HTTP_2; import static java.net.http.HttpClient.Version.HTTP_3; @@ -125,7 +124,9 @@ import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static jdk.test.lib.Asserts.assertEquals; import static jdk.test.lib.Asserts.assertNotEquals; import static jdk.test.lib.Asserts.assertTrue; -import static org.testng.Assert.assertFalse; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import org.junit.jupiter.api.Test; public class H3StreamLimitReachedTest implements HttpServerAdapters { @@ -329,7 +330,7 @@ public class H3StreamLimitReachedTest implements HttpServerAdapters { } @Test - public static void testH3Only() throws Exception { + public void testH3Only() throws Exception { System.out.println("\nTesting HTTP/3 only"); initialize(true); try (HttpClient client = getClient()) { @@ -402,12 +403,12 @@ public class H3StreamLimitReachedTest implements HttpServerAdapters { } @Test - public static void testH2H3WithTwoAltSVC() throws Exception { + public void testH2H3WithTwoAltSVC() throws Exception { testH2H3(false); } @Test - public static void testH2H3WithAltSVCOnSamePort() throws Exception { + public void testH2H3WithAltSVCOnSamePort() throws Exception { testH2H3(true); } @@ -627,12 +628,12 @@ public class H3StreamLimitReachedTest implements HttpServerAdapters { } @Test - public static void testParallelH2H3WithTwoAltSVC() throws Exception { + public void testParallelH2H3WithTwoAltSVC() throws Exception { testH2H3Concurrent(false); } @Test - public static void testParallelH2H3WithAltSVCOnSamePort() throws Exception { + public void testParallelH2H3WithAltSVCOnSamePort() throws Exception { testH2H3Concurrent(true); } diff --git a/test/jdk/java/net/httpclient/http3/HTTP3NoBodyTest.java b/test/jdk/java/net/httpclient/http3/HTTP3NoBodyTest.java index 601e40c7dc6..b43ce8dcf79 100644 --- a/test/jdk/java/net/httpclient/http3/HTTP3NoBodyTest.java +++ b/test/jdk/java/net/httpclient/http3/HTTP3NoBodyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * jdk.httpclient.test.lib.http3.Http3TestServer * jdk.httpclient.test.lib.common.HttpServerAdapters * @compile ../ReferenceTracker.java - * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors + * @run junit/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors * -Djdk.internal.httpclient.debug=true * HTTP3NoBodyTest * @summary this is a copy of http2/NoBodyTest over HTTP/3 @@ -38,8 +38,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.*; -import javax.net.ssl.*; +import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpHeaders; import java.net.http.HttpRequest; @@ -48,9 +47,12 @@ import java.net.http.HttpOption.Http3DiscoveryMode; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import java.util.Random; -import java.util.concurrent.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; +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; @@ -58,7 +60,6 @@ import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.httpclient.test.lib.http3.Http3TestServer; import jdk.test.lib.net.SimpleSSLContext; import jdk.test.lib.RandomFactory; -import org.testng.annotations.Test; import static java.net.http.HttpClient.Version.HTTP_3; import static java.net.http.HttpOption.Http3DiscoveryMode.ALT_SVC; @@ -66,7 +67,8 @@ import static java.net.http.HttpOption.Http3DiscoveryMode.ANY; import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; -@Test +import org.junit.jupiter.api.Test; + public class HTTP3NoBodyTest { private static final Random RANDOM = RandomFactory.getRandom(); @@ -119,7 +121,7 @@ public class HTTP3NoBodyTest { } @Test - public static void runtest() throws Exception { + public void runtest() throws Exception { try { initialize(); warmup(false); diff --git a/test/jdk/java/net/httpclient/http3/Http3ExpectContinueTest.java b/test/jdk/java/net/httpclient/http3/Http3ExpectContinueTest.java index 53ce6a68d38..1cf6900ed5d 100644 --- a/test/jdk/java/net/httpclient/http3/Http3ExpectContinueTest.java +++ b/test/jdk/java/net/httpclient/http3/Http3ExpectContinueTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * @library /test/lib /test/jdk/java/net/httpclient/lib * @compile ../ReferenceTracker.java * @build jdk.httpclient.test.lib.common.HttpServerAdapters - * @run testng/othervm -Djdk.internal.httpclient.debug=true + * @run junit/othervm -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=errors,requests,headers * Http3ExpectContinueTest */ @@ -36,11 +36,6 @@ import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.httpclient.test.lib.http3.Http3TestServer; import jdk.httpclient.test.lib.quic.QuicServer; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.TestException; -import org.testng.annotations.Test; import javax.net.ssl.SSLContext; import java.io.IOException; @@ -60,15 +55,20 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import static java.net.http.HttpClient.Version.HTTP_3; -import static org.testng.Assert.*; + +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class Http3ExpectContinueTest implements HttpServerAdapters { - ReferenceTracker TRACKER = ReferenceTracker.INSTANCE; + private static final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE; - Http3TestServer http3TestServer; + private static Http3TestServer http3TestServer; - URI h3postUri, h3forcePostUri, h3hangUri; + private static URI h3postUri, h3forcePostUri, h3hangUri; static PrintStream err = new PrintStream(System.err); static PrintStream out = new PrintStream(System.out); @@ -78,8 +78,7 @@ public class Http3ExpectContinueTest implements HttpServerAdapters { static final String BODY = "Post body"; private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); - @DataProvider(name = "uris") - public Object[][] urisData() { + public static Object[][] urisData() { return new Object[][]{ // URI, Expected Status Code, Will finish with Exception { h3postUri, 200, false }, @@ -88,7 +87,8 @@ public class Http3ExpectContinueTest implements HttpServerAdapters { }; } - @Test(dataProvider = "uris") + @ParameterizedTest + @MethodSource("urisData") public void test(URI uri, int expectedStatusCode, boolean exceptionally) throws CancellationException, InterruptedException, ExecutionException, IOException { @@ -149,8 +149,8 @@ public class Http3ExpectContinueTest implements HttpServerAdapters { } } - @BeforeTest - public void setup() throws Exception { + @BeforeAll + public static void setup() throws Exception { final QuicServer quicServer = Http3TestServer.quicServerBuilder() .sslContext(sslContext) .build(); @@ -167,8 +167,8 @@ public class Http3ExpectContinueTest implements HttpServerAdapters { http3TestServer.start(); } - @AfterTest - public void teardown() throws IOException { + @AfterAll + public static void teardown() throws IOException { var error = TRACKER.check(500); if (error != null) throw error; http3TestServer.stop(); @@ -233,11 +233,11 @@ public class Http3ExpectContinueTest implements HttpServerAdapters { } if (exceptionally && testThrowable != null) { err.println("Finished exceptionally Test throwable: " + testThrowable); - assertEquals(IOException.class, testThrowable.getClass()); + assertEquals(testThrowable.getClass(), IOException.class); } else if (exceptionally) { - throw new TestException("Expected case to finish with an IOException but testException is null"); + fail("Expected case to finish with an IOException but testException is null"); } else if (resp != null) { - assertEquals(resp.statusCode(), expectedStatusCode); + assertEquals(expectedStatusCode, resp.statusCode()); err.println("Request completed successfully for path " + path); err.println("Response Headers: " + resp.headers()); err.println("Response Status Code: " + resp.statusCode()); diff --git a/test/jdk/java/net/httpclient/http3/PeerUniStreamDispatcherTest.java b/test/jdk/java/net/httpclient/http3/PeerUniStreamDispatcherTest.java index be1b8304bf1..fc6d43bb472 100644 --- a/test/jdk/java/net/httpclient/http3/PeerUniStreamDispatcherTest.java +++ b/test/jdk/java/net/httpclient/http3/PeerUniStreamDispatcherTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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 - * @run testng/othervm + * @run junit/othervm * -Djdk.internal.httpclient.debug=out * PeerUniStreamDispatcherTest * @summary Unit test for the PeerUniStreamDispatcher @@ -45,8 +45,8 @@ import jdk.internal.net.http.quic.streams.QuicReceiverStream; import jdk.internal.net.http.quic.streams.QuicStreamReader; import jdk.internal.net.http.quic.streams.QuicStreams; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; public class PeerUniStreamDispatcherTest { @@ -301,7 +301,7 @@ public class PeerUniStreamDispatcherTest { assertTrue(reader.connected()); int size = VariableLengthEncoder.getEncodedSize(code); ByteBuffer buffer = ByteBuffer.allocate(size); - assertEquals(buffer.remaining(), size); + assertEquals(size, buffer.remaining()); VariableLengthEncoder.encode(buffer, code); buffer.flip(); stream.buffers.add(buffer); @@ -313,7 +313,7 @@ public class PeerUniStreamDispatcherTest { // will loop correctly. size = VariableLengthEncoder.getEncodedSize(1L << 62 - 5); ByteBuffer buffer2 = ByteBuffer.allocate(size); - assertEquals(buffer2.remaining(), size); + assertEquals(size, buffer2.remaining()); VariableLengthEncoder.encode(buffer2, 1L << 62 - 5); buffer2.flip(); stream.buffers.add(ByteBuffer.wrap(new byte[] {buffer2.get()})); @@ -328,7 +328,7 @@ public class PeerUniStreamDispatcherTest { assertFalse(reader.connected()); assertFalse(dispatcher.dispatched.isEmpty()); assertTrue(stream.buffers.isEmpty()); - assertEquals(dispatcher.dispatched.size(), 1); + assertEquals(1, dispatcher.dispatched.size()); var dispatched = dispatcher.dispatched.get(0); checkDispatched(type, code, stream, dispatched); } @@ -343,30 +343,30 @@ public class PeerUniStreamDispatcherTest { case RESERVED -> DispatchedStream.ReservedStream.class; case UNKNOWN -> DispatchedStream.UnknownStream.class; }; - assertEquals(dispatched.getClass(), streamClass, + assertEquals(streamClass, dispatched.getClass(), "unexpected dispatched class " + dispatched + " for " + type); if (dispatched instanceof DispatchedStream.StandardStream st) { System.out.println("Got expected stream: " + st); - assertEquals(st.type(), type); - assertEquals(st.stream, stream); + assertEquals(type, st.type()); + assertEquals(stream, st.stream); } else if (dispatched instanceof DispatchedStream.ReservedStream res) { System.out.println("Got expected stream: " + res); - assertEquals(res.type(), type); - assertEquals(res.stream, stream); - assertEquals(res.code(), code); + assertEquals(type, res.type()); + assertEquals(stream, res.stream); + assertEquals(code, res.code()); assertTrue(Http3Streams.isReserved(res.code())); } else if (dispatched instanceof DispatchedStream.UnknownStream unk) { System.out.println("Got expected stream: " + unk); - assertEquals(unk.type(), type); - assertEquals(unk.stream, stream); - assertEquals(unk.code(), code); + assertEquals(type, unk.type()); + assertEquals(stream, unk.stream); + assertEquals(code, unk.code()); assertFalse(Http3Streams.isReserved(unk.code())); } else if (dispatched instanceof DispatchedStream.PushStream push) { System.out.println("Got expected stream: " + push); - assertEquals(push.type(), type); - assertEquals(push.stream, stream); - assertEquals(push.pushId, 1L << 62 - 5); - assertEquals(push.type(), DISPATCHED_STREAM.PUSH); + assertEquals(type, push.type()); + assertEquals(stream, push.stream); + assertEquals(1L << 62 - 5, push.pushId); + assertEquals(DISPATCHED_STREAM.PUSH, push.type()); } } @@ -406,9 +406,9 @@ public class PeerUniStreamDispatcherTest { SequentialScheduler scheduler = stream.scheduler; assertTrue(reader.connected()); int size = VariableLengthEncoder.getEncodedSize(code); - assertEquals(size, 8); + assertEquals(8, size); ByteBuffer buffer = ByteBuffer.allocate(size); - assertEquals(buffer.remaining(), size); + assertEquals(size, buffer.remaining()); VariableLengthEncoder.encode(buffer, code); buffer.flip(); dispatcher.start(); @@ -428,7 +428,7 @@ public class PeerUniStreamDispatcherTest { assertFalse(reader.connected()); assertFalse(dispatcher.dispatched.isEmpty()); assertTrue(stream.buffers.isEmpty()); - assertEquals(dispatcher.dispatched.size(), 1); + assertEquals(1, dispatcher.dispatched.size()); var dispatched = dispatcher.dispatched.get(0); checkDispatched(type, code, stream, dispatched); } diff --git a/test/jdk/java/net/httpclient/http3/StopSendingTest.java b/test/jdk/java/net/httpclient/http3/StopSendingTest.java index ff1b8db7bc8..8c9a6f84b65 100644 --- a/test/jdk/java/net/httpclient/http3/StopSendingTest.java +++ b/test/jdk/java/net/httpclient/http3/StopSendingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * 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,14 +44,15 @@ import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.internal.net.http.ResponseSubscribers; import jdk.test.lib.net.SimpleSSLContext; import jdk.test.lib.net.URIBuilder; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY; import static java.net.http.HttpOption.H3_DISCOVERY; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + /* * @test * @summary Exercises the HTTP3 client to send a STOP_SENDING frame @@ -59,17 +60,17 @@ import static java.net.http.HttpOption.H3_DISCOVERY; * @build jdk.test.lib.net.SimpleSSLContext * jdk.httpclient.test.lib.common.HttpServerAdapters * @compile ../ReferenceTracker.java - * @run testng/othervm -Djdk.internal.httpclient.debug=true + * @run junit/othervm -Djdk.internal.httpclient.debug=true * -Djdk.httpclient.HttpClient.log=requests,responses,errors StopSendingTest */ public class StopSendingTest implements HttpServerAdapters { private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); - private HttpTestServer h3Server; - private String requestURIBase; + private static HttpTestServer h3Server; + private static String requestURIBase; - @BeforeClass - public void beforeClass() throws Exception { + @BeforeAll + public static void beforeClass() throws Exception { h3Server = HttpTestServer.create(HTTP_3_URI_ONLY, sslContext); h3Server.addHandler(new Handler(), "/hello"); h3Server.start(); @@ -79,8 +80,8 @@ public class StopSendingTest implements HttpServerAdapters { } - @AfterClass - public void afterClass() throws Exception { + @AfterAll + public static void afterClass() throws Exception { if (h3Server != null) { System.out.println("Stopping server " + h3Server.getAddress()); h3Server.stop(); @@ -154,7 +155,7 @@ public class StopSendingTest implements HttpServerAdapters { // of the Future instance, sometimes the Future.cancel(true) results // in an ExecutionException which wraps the CancellationException. // TODO: fix the actual race condition and then expect only CancellationException here - final Exception actualException = Assert.expectThrows(Exception.class, futureResp::get); + final Exception actualException = Assertions.assertThrows(Exception.class, futureResp::get); if (actualException instanceof CancellationException) { // expected System.out.println("Received the expected CancellationException"); diff --git a/test/jdk/java/net/httpclient/http3/StreamLimitTest.java b/test/jdk/java/net/httpclient/http3/StreamLimitTest.java index e0610cf89b8..9e15db9ceb9 100644 --- a/test/jdk/java/net/httpclient/http3/StreamLimitTest.java +++ b/test/jdk/java/net/httpclient/http3/StreamLimitTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * 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,14 +45,15 @@ import jdk.httpclient.test.lib.quic.QuicServerConnection; import jdk.internal.net.http.quic.QuicTransportParameters; import jdk.internal.net.http.quic.QuicTransportParameters.ParameterId; import jdk.test.lib.net.SimpleSSLContext; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; import static java.net.http.HttpClient.Builder.NO_PROXY; import static java.net.http.HttpClient.Version.HTTP_3; import static java.net.http.HttpOption.H3_DISCOVERY; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + /* * @test * @summary verifies that when the Quic stream limit is reached @@ -64,17 +65,17 @@ import static java.net.http.HttpOption.H3_DISCOVERY; * @build jdk.test.lib.net.SimpleSSLContext * jdk.httpclient.test.lib.common.HttpServerAdapters * jdk.httpclient.test.lib.http3.Http3TestServer - * @run testng/othervm -Djdk.internal.httpclient.debug=true StreamLimitTest + * @run junit/othervm -Djdk.internal.httpclient.debug=true StreamLimitTest */ public class StreamLimitTest { private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); - private HttpTestServer server; - private QuicServer quicServer; - private URI requestURI; - private volatile QuicServerConnection latestServerConn; + private static HttpTestServer server; + private static QuicServer quicServer; + private static URI requestURI; + private static volatile QuicServerConnection latestServerConn; - private final class Handler implements HttpTestHandler { + private static final class Handler implements HttpTestHandler { @Override public void handle(HttpTestExchange exchange) throws IOException { @@ -97,8 +98,8 @@ public class StreamLimitTest { } } - @BeforeClass - public void beforeClass() throws Exception { + @BeforeAll + public static void beforeClass() throws Exception { quicServer = Http3TestServer.quicServerBuilder().sslContext(sslContext).build(); final Http3TestServer h3Server = new Http3TestServer(quicServer) { @Override @@ -118,8 +119,8 @@ public class StreamLimitTest { requestURI = new URI("https://" + server.serverAuthority() + "/foo"); } - @AfterClass - public void afterClass() throws Exception { + @AfterAll + public static void afterClass() throws Exception { latestServerConn = null; if (server != null) { server.stop(); @@ -161,8 +162,8 @@ public class StreamLimitTest { System.out.println("Sending request " + i + " to " + requestURI); final HttpResponse resp = client.send(req, HttpResponse.BodyHandlers.ofString()); - Assert.assertEquals(resp.version(), HTTP_3, "Unexpected response version"); - Assert.assertEquals(resp.statusCode(), 200, "Unexpected response code"); + Assertions.assertEquals(HTTP_3, resp.version(), "Unexpected response version"); + Assertions.assertEquals(200, resp.statusCode(), "Unexpected response code"); final String respBody = resp.body(); System.out.println("Request " + i + " was handled by server connection: " + respBody); if (i == 1) { @@ -170,7 +171,7 @@ public class StreamLimitTest { // to this request requestHandledBy = respBody; } else { - Assert.assertEquals(respBody, requestHandledBy, "Request was handled by an" + + Assertions.assertEquals(requestHandledBy, respBody, "Request was handled by an" + " unexpected server connection"); } } @@ -193,20 +194,20 @@ public class StreamLimitTest { + requestURI); final HttpResponse resp = client.send(reqWithTimeout, HttpResponse.BodyHandlers.ofString()); - Assert.assertEquals(resp.version(), HTTP_3, "Unexpected response version"); - Assert.assertEquals(resp.statusCode(), 200, "Unexpected response code"); + Assertions.assertEquals(HTTP_3, resp.version(), "Unexpected response version"); + Assertions.assertEquals(200, resp.statusCode(), "Unexpected response code"); final String respBody = resp.body(); System.out.println("Request " + i + " was handled by server connection: " + respBody); if (i == 1) { // first request after the limit was hit. // verify that it was handled by a new connection and not the one that handled // the previous N requests - Assert.assertNotEquals(respBody, requestHandledBy, "Request was expected to be" + + Assertions.assertNotEquals(requestHandledBy, respBody, "Request was expected to be" + " handled by a new server connection, but wasn't"); // keep track this new server connection id which responded to this request requestHandledBy = respBody; } else { - Assert.assertEquals(respBody, requestHandledBy, "Request was handled by an" + + Assertions.assertEquals(requestHandledBy, respBody, "Request was handled by an" + " unexpected server connection"); } } @@ -231,13 +232,13 @@ public class StreamLimitTest { " to " + requestURI); final HttpResponse resp = client.send(reqWithTimeout, HttpResponse.BodyHandlers.ofString()); - Assert.assertEquals(resp.version(), HTTP_3, "Unexpected response version"); - Assert.assertEquals(resp.statusCode(), 200, "Unexpected response code"); + Assertions.assertEquals(HTTP_3, resp.version(), "Unexpected response version"); + Assertions.assertEquals(200, resp.statusCode(), "Unexpected response code"); final String respBody = resp.body(); System.out.println("Request " + i + " was handled by server connection: " + respBody); // all these requests should be handled by the same server connection which handled // the previous requests - Assert.assertEquals(respBody, requestHandledBy, "Request was handled by an" + + Assertions.assertEquals(requestHandledBy, respBody, "Request was handled by an" + " unexpected server connection"); } // at this point the newer limit for bidi stream creation has reached on the client. @@ -254,12 +255,12 @@ public class StreamLimitTest { System.out.println("Sending request, without timeout, to " + requestURI); final HttpResponse finalResp = client.send(finalReq, HttpResponse.BodyHandlers.ofString()); - Assert.assertEquals(finalResp.version(), HTTP_3, "Unexpected response version"); - Assert.assertEquals(finalResp.statusCode(), 200, "Unexpected response code"); + Assertions.assertEquals(HTTP_3, finalResp.version(), "Unexpected response version"); + Assertions.assertEquals(200, finalResp.statusCode(), "Unexpected response code"); final String finalRespBody = finalResp.body(); System.out.println("Request was handled by server connection: " + finalRespBody); // this request should have been handled by a new server connection - Assert.assertNotEquals(finalRespBody, requestHandledBy, "Request was handled by an" + + Assertions.assertNotEquals(requestHandledBy, finalRespBody, "Request was handled by an" + " unexpected server connection"); } } diff --git a/test/jdk/java/net/httpclient/offline/OfflineTesting.java b/test/jdk/java/net/httpclient/offline/OfflineTesting.java index 2f4833bf179..f36a457022e 100644 --- a/test/jdk/java/net/httpclient/offline/OfflineTesting.java +++ b/test/jdk/java/net/httpclient/offline/OfflineTesting.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +25,7 @@ * @test * @summary Demonstrates how to achieve testing without network connections * @build DelegatingHttpClient FixedHttpResponse FixedResponseHttpClient - * @run testng/othervm OfflineTesting + * @run junit/othervm OfflineTesting */ import java.io.IOException; @@ -40,13 +40,15 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.BiPredicate; -import org.testng.annotations.Test; import static java.lang.String.format; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Objects.requireNonNull; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.fail; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; public class OfflineTesting { @@ -72,9 +74,9 @@ public class OfflineTesting { client.sendAsync(request, BodyHandlers.ofString()) .thenAccept(response -> { System.out.println("response: " + response); - assertEquals(response.statusCode(), 200); + assertEquals(200, response.statusCode()); assertTrue(response.headers().firstValue("Server").isPresent()); - assertEquals(response.body(), "A response message"); + assertEquals("A response message", response.body()); }) .join(); } @@ -91,9 +93,9 @@ public class OfflineTesting { client.sendAsync(request, BodyHandlers.ofByteArray()) .thenAccept(response -> { System.out.println("response: " + response); - assertEquals(response.statusCode(), 200); + assertEquals(200, response.statusCode()); assertTrue(response.headers().firstValue("Content-Type").isPresent()); - assertEquals(response.body(), "A response message".getBytes(UTF_8)); + Assertions.assertArrayEquals("A response message".getBytes(UTF_8), response.body()); }) .join(); } @@ -125,9 +127,9 @@ public class OfflineTesting { try (var client = fixedClient) { client.sendAsync(request, BodyHandlers.ofString()) .thenAccept(response -> { - assertEquals(response.statusCode(), 404); + assertEquals(404, response.statusCode()); response.headers().firstValue("Content-Type") - .ifPresentOrElse(type -> assertEquals(type, "text/html"), + .ifPresentOrElse(type -> assertEquals("text/html", type), () -> fail("Content-Type not present")); assertTrue(response.body().contains("404 Not Found")); }) @@ -151,8 +153,8 @@ public class OfflineTesting { client.sendAsync(request, BodyHandlers.ofString()) .thenAccept(response -> { System.out.println("response: " + response); - assertEquals(response.statusCode(), 200); - assertEquals(response.body(), "Hello World"); + assertEquals(200, response.statusCode()); + assertEquals("Hello World", response.body()); }) .join(); } @@ -172,8 +174,8 @@ public class OfflineTesting { HttpResponse response = client.send(request, BodyHandlers.ofString()); System.out.println("response: " + response); - assertEquals(response.statusCode(), 200); - assertEquals(response.body(), "Hello chegar!!"); + assertEquals(200, response.statusCode()); + assertEquals("Hello chegar!!", response.body()); } } diff --git a/test/jdk/java/net/httpclient/security/filePerms/FileProcessorPermissionTest.java b/test/jdk/java/net/httpclient/security/filePerms/FileProcessorPermissionTest.java index c8920771727..361b053fe43 100644 --- a/test/jdk/java/net/httpclient/security/filePerms/FileProcessorPermissionTest.java +++ b/test/jdk/java/net/httpclient/security/filePerms/FileProcessorPermissionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* * @test * @summary Basic checks for File Processors - * @run testng/othervm FileProcessorPermissionTest + * @run junit/othervm FileProcessorPermissionTest */ import java.nio.file.Path; @@ -32,9 +32,9 @@ import java.nio.file.Paths; import java.util.List; import java.net.http.HttpRequest; import java.net.http.HttpResponse.BodyHandlers; -import org.testng.annotations.Test; import static java.nio.file.StandardOpenOption.*; -import static org.testng.Assert.*; + +import org.junit.jupiter.api.Test; public class FileProcessorPermissionTest { diff --git a/test/jdk/java/net/httpclient/security/filePerms/SecurityBeforeFile.java b/test/jdk/java/net/httpclient/security/filePerms/SecurityBeforeFile.java index d54e27b89ce..c8d7bb64b36 100644 --- a/test/jdk/java/net/httpclient/security/filePerms/SecurityBeforeFile.java +++ b/test/jdk/java/net/httpclient/security/filePerms/SecurityBeforeFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +25,7 @@ * @test * @summary Verifies security checks are performed before existence checks * in pre-defined body processors APIs - * @run testng/othervm SecurityBeforeFile + * @run junit/othervm SecurityBeforeFile */ import java.io.FileNotFoundException; @@ -35,11 +35,13 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.net.http.HttpRequest.BodyPublishers; import java.net.http.HttpResponse.BodyHandlers; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.System.out; import static java.nio.file.StandardOpenOption.*; -import static org.testng.Assert.*; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.fail; public class SecurityBeforeFile { @@ -57,8 +59,7 @@ public class SecurityBeforeFile { } } - @DataProvider(name = "handlerOpenOptions") - public Object[][] handlerOpenOptions() { + public static Object[][] handlerOpenOptions() { return new Object[][] { { new OpenOption[] { } }, { new OpenOption[] { CREATE } }, @@ -66,7 +67,8 @@ public class SecurityBeforeFile { }; } - @Test(dataProvider = "handlerOpenOptions") + @ParameterizedTest + @MethodSource("handlerOpenOptions") public void BodyHandlersOfFileDownload(OpenOption[] openOptions) { Path p = Paths.get("doesNotExistDir"); if (Files.exists(p)) diff --git a/test/jdk/java/nio/channels/Selector/ConnectionRefusedMessage.java b/test/jdk/java/nio/channels/SocketChannel/ConnectionRefusedMessage.java similarity index 92% rename from test/jdk/java/nio/channels/Selector/ConnectionRefusedMessage.java rename to test/jdk/java/nio/channels/SocketChannel/ConnectionRefusedMessage.java index 04490f63efe..d71bc6569cb 100644 --- a/test/jdk/java/nio/channels/Selector/ConnectionRefusedMessage.java +++ b/test/jdk/java/nio/channels/SocketChannel/ConnectionRefusedMessage.java @@ -42,7 +42,8 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; * @summary Verify that when a SocketChannel is registered with a Selector * with an interest in CONNECT operation, then SocketChannel.finishConnect() * throws the correct exception message, if the connect() fails - * @run junit ${test.main.class} + * @run junit/othervm -Djdk.includeInExceptions=hostInfoExclSocket ${test.main.class} + * @run junit/othervm -Djdk.includeInExceptions=hostInfo -Dcheck.relaxed=true ${test.main.class} */ class ConnectionRefusedMessage { @@ -108,10 +109,14 @@ class ConnectionRefusedMessage { } private static void assertExceptionMessage(final ConnectException ce) { - if (!"Connection refused".equals(ce.getMessage())) { - // propagate the original exception - fail("unexpected exception message: " + ce.getMessage(), ce); + if ("Connection refused".equals(ce.getMessage())) { + return; } + if (Boolean.getBoolean("check.relaxed") && ce.getMessage() != null && ce.getMessage().startsWith("Connection refused")) { + return; + } + // propagate the original exception + fail("unexpected exception message: " + ce.getMessage(), ce); } // Try to find a suitable port to provoke a "Connection Refused" error. diff --git a/test/jdk/java/util/jar/Attributes/IterationOrder.java b/test/jdk/java/util/jar/Attributes/IterationOrder.java index 4028d71e7c4..edd1d9b8bc8 100644 --- a/test/jdk/java/util/jar/Attributes/IterationOrder.java +++ b/test/jdk/java/util/jar/Attributes/IterationOrder.java @@ -1,5 +1,6 @@ /* * Copyright 2014 Google, Inc. All Rights Reserved. + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. * 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 +25,26 @@ /* @test * @bug 8062194 * @summary Ensure Attribute iteration order is the insertion order. + * @run junit IterationOrder */ +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + import java.util.Arrays; import java.util.Map; import java.util.jar.Attributes; import java.util.jar.Attributes.Name; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.fail; public class IterationOrder { - static void checkOrder(Attributes.Name k0, String v0, + + @ParameterizedTest + @MethodSource + void checkOrderTest(Attributes.Name k0, String v0, Attributes.Name k1, String v1, Attributes.Name k2, String v2) { Attributes x = new Attributes(); @@ -48,7 +60,7 @@ public class IterationOrder { && entries[1].getValue() == v1 && entries[2].getKey() == k2 && entries[2].getValue() == v2)) { - throw new AssertionError(Arrays.toString(entries)); + fail(Arrays.toString(entries)); } Object[] keys = x.keySet().toArray(); @@ -56,19 +68,21 @@ public class IterationOrder { && keys[0] == k0 && keys[1] == k1 && keys[2] == k2)) { - throw new AssertionError(Arrays.toString(keys)); + fail(Arrays.toString(keys)); } } - public static void main(String[] args) throws Exception { + static Stream checkOrderTest() { Attributes.Name k0 = Name.MANIFEST_VERSION; Attributes.Name k1 = Name.MAIN_CLASS; Attributes.Name k2 = Name.SEALED; String v0 = "42.0"; String v1 = "com.google.Hello"; String v2 = "yes"; - checkOrder(k0, v0, k1, v1, k2, v2); - checkOrder(k1, v1, k0, v0, k2, v2); - checkOrder(k2, v2, k1, v1, k0, v0); + return Stream.of( + Arguments.of(k0, v0, k1, v1, k2, v2), + Arguments.of(k1, v1, k0, v0, k2, v2), + Arguments.of(k2, v2, k1, v1, k0, v0) + ); } } diff --git a/test/jdk/java/util/jar/Attributes/Name.java b/test/jdk/java/util/jar/Attributes/Name.java index 78306028698..843038cb820 100644 --- a/test/jdk/java/util/jar/Attributes/Name.java +++ b/test/jdk/java/util/jar/Attributes/Name.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved. * 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,20 @@ @bug 4199981 @summary Make sure empty string is not a valid Attributes name. - */ + @run junit Name + */ +import org.junit.jupiter.api.Test; import java.util.jar.Attributes; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class Name { - public static void main(String[] args) throws Exception { - try { - Attributes.Name name = new Attributes.Name(""); - throw new Exception("empty string should be rejected"); - } catch (IllegalArgumentException e) { - } + + @Test + void emptyStringTest() { + assertThrows(IllegalArgumentException.class, () -> new Attributes.Name(""), + "empty string should be rejected"); } } diff --git a/test/jdk/java/util/jar/Attributes/NullAndEmptyKeysAndValues.java b/test/jdk/java/util/jar/Attributes/NullAndEmptyKeysAndValues.java index c62ddcced8a..e99825d235e 100644 --- a/test/jdk/java/util/jar/Attributes/NullAndEmptyKeysAndValues.java +++ b/test/jdk/java/util/jar/Attributes/NullAndEmptyKeysAndValues.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * 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,8 +21,6 @@ * questions. */ -import static java.nio.charset.StandardCharsets.UTF_8; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -31,14 +29,16 @@ import java.util.jar.Manifest; import java.util.jar.Attributes.Name; import java.lang.reflect.Field; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import org.junit.jupiter.api.Test; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.jupiter.api.Assertions.*; /** * @test * @bug 8066619 * @modules java.base/java.util.jar:+open - * @run testng/othervm --enable-final-field-mutation=ALL-UNNAMED NullAndEmptyKeysAndValues + * @run junit/othervm --enable-final-field-mutation=ALL-UNNAMED NullAndEmptyKeysAndValues * @summary Tests manifests with {@code null} and empty string {@code ""} * values as section name, header name, or value in both main and named * attributes sections. @@ -108,7 +108,7 @@ public class NullAndEmptyKeysAndValues { attr.set(mf, mainAtts); mf.getMainAttributes().put(Name.MANIFEST_VERSION, "1.0"); mf = writeAndRead(mf); - assertEquals(mf.getMainAttributes().getValue(SOME_KEY), NULL_TEXT); + assertEquals(NULL_TEXT, mf.getMainAttributes().getValue(SOME_KEY)); } @Test @@ -122,7 +122,7 @@ public class NullAndEmptyKeysAndValues { attr.set(mf, mainAtts); mf.getMainAttributes().put(Name.MANIFEST_VERSION, "1.0"); mf = writeAndRead(mf); - assertEquals(mf.getMainAttributes().getValue(SOME_KEY), EMPTY_STR); + assertEquals(EMPTY_STR, mf.getMainAttributes().getValue(SOME_KEY)); } @Test @@ -171,8 +171,7 @@ public class NullAndEmptyKeysAndValues { map.put(new Name(SOME_KEY), null); }}); mf = writeAndRead(mf); - assertEquals(mf.getEntries().get(SOME_KEY).getValue(SOME_KEY), - NULL_TEXT); + assertEquals(NULL_TEXT, mf.getEntries().get(SOME_KEY).getValue(SOME_KEY)); } @Test @@ -183,8 +182,7 @@ public class NullAndEmptyKeysAndValues { map.put(new Name(SOME_KEY), EMPTY_STR); }}); mf = writeAndRead(mf); - assertEquals(mf.getEntries().get(SOME_KEY).getValue(SOME_KEY), - EMPTY_STR); + assertEquals(EMPTY_STR, mf.getEntries().get(SOME_KEY).getValue(SOME_KEY)); } static Manifest writeAndRead(Manifest mf) throws IOException { diff --git a/test/jdk/java/util/jar/Attributes/PutAndPutAll.java b/test/jdk/java/util/jar/Attributes/PutAndPutAll.java index f459daf8c2e..bd61ba1e92d 100644 --- a/test/jdk/java/util/jar/Attributes/PutAndPutAll.java +++ b/test/jdk/java/util/jar/Attributes/PutAndPutAll.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2026, Oracle and/or its affiliates. All rights reserved. * 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,31 +25,27 @@ @bug 4165833 4167600 @summary Test if put and putAll will test for illegal arguments. - */ + @run junit PutAndPutAll + */ +import org.junit.jupiter.api.Test; + import java.util.jar.Attributes; import java.util.HashMap; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class PutAndPutAll { - public static void main(String[] args) throws Exception { + + @Test + void classCastTest() { Attributes at = new Attributes(); - try{ - at.put("this is not an Attributes.Name", "value"); - throw new Exception("put should check for non Attributes.Name names"); - } catch (ClassCastException e) { - } - - try{ - at.put(new Attributes.Name("name"), new Integer(0)); - throw new Exception("put should check for non String values"); - } catch (ClassCastException e) { - } - - try { - at.putAll(new HashMap()); - throw new Exception("putAll should check for non Attributes maps"); - } catch (ClassCastException e) { - } + assertThrows(ClassCastException.class, + () -> at.put("this is not an Attributes.Name", "value"), "put should check for non Attributes.Name names"); + assertThrows(ClassCastException.class, + () -> at.put(new Attributes.Name("name"), new Integer(0)), "put should check for non String values"); + assertThrows(ClassCastException.class, + () -> at.putAll(new HashMap()), "putAll should check for non Attributes maps"); } } diff --git a/test/jdk/java/util/jar/Attributes/TestAttrsNL.java b/test/jdk/java/util/jar/Attributes/TestAttrsNL.java index 34f7e4c4502..abfd3df6cd7 100644 --- a/test/jdk/java/util/jar/Attributes/TestAttrsNL.java +++ b/test/jdk/java/util/jar/Attributes/TestAttrsNL.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * 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,19 +24,28 @@ /* @test * @bug 8200530 * @summary Test Attributes newline + * @run junit TestAttrsNL */ +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.io.IOException; import java.util.jar.Manifest; import java.util.jar.Attributes; import java.util.jar.Attributes.Name; import java.io.ByteArrayInputStream; import java.util.Map; +import java.util.stream.Stream; import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; public class TestAttrsNL { - public static void main(String[] args) throws Throwable { + static Stream newLineAttributesTest() throws IOException { String manifestStr = "Manifest-Version: 1.0\r\n" + @@ -68,16 +77,16 @@ public class TestAttrsNL { new Name("key44"), "value44" ); - test(new Manifest(new ByteArrayInputStream(manifestStr.getBytes(UTF_8))), - mainAttrsExped, attrsExped); + var normal = Arguments.of(new Manifest(new ByteArrayInputStream(manifestStr.getBytes(UTF_8))), + mainAttrsExped, attrsExped); - test(new Manifest(new ByteArrayInputStream( - manifestStr.replaceAll("\r\n", "\r").getBytes(UTF_8))), - mainAttrsExped, attrsExped); + var carriage = Arguments.of(new Manifest(new ByteArrayInputStream( + manifestStr.replaceAll("\r\n", "\r").getBytes(UTF_8))), + mainAttrsExped, attrsExped); - test(new Manifest(new ByteArrayInputStream( - manifestStr.replaceAll("\r\n", "\n").getBytes(UTF_8))), - mainAttrsExped, attrsExped); + var newLine = Arguments.of(new Manifest(new ByteArrayInputStream( + manifestStr.replaceAll("\r\n", "\n").getBytes(UTF_8))), + mainAttrsExped, attrsExped); // mixed manifestStr = @@ -93,31 +102,33 @@ public class TestAttrsNL { "key22: value22\n END\r\n" + "key33: value33\r \n" + "key44: value44\n"; - test(new Manifest(new ByteArrayInputStream(manifestStr.getBytes(UTF_8))), + var mixed = Arguments.of(new Manifest(new ByteArrayInputStream(manifestStr.getBytes(UTF_8))), mainAttrsExped, attrsExped); - + return Stream.of(normal, carriage, newLine, mixed); } - private static void test(Manifest m, + @ParameterizedTest + @MethodSource + void newLineAttributesTest(Manifest m, Map mainAttrsExped, Map attrsExped) { Attributes mainAttrs = m.getMainAttributes(); mainAttrsExped.forEach( (k, v) -> { - if (!mainAttrs.containsKey(k) || !mainAttrs.get(k).equals(v)) { - System.out.printf(" containsKey(%s) : %b%n", k, mainAttrs.containsKey(k)); - System.out.printf(" get(%s) : %s%n", k, mainAttrs.get(k)); - throw new RuntimeException("expected attr: k=<" + k + ">, v=<" + v + ">"); - } + var expectedMsg = "expected attr: k=<" + k + ">, v=<" + v + ">"; + assertTrue(mainAttrs.containsKey(k), + " containsKey(%s) : %b%n%s".formatted(k, mainAttrs.containsKey(k), expectedMsg)); + assertEquals(v, mainAttrs.get(k), + " get(%s) : %s%n%s".formatted(k, mainAttrs.get(k), expectedMsg)); }); Attributes attrs = m.getAttributes("Hello"); attrs.forEach( (k, v) -> { - if (!attrs.containsKey(k) || !attrs.get(k).equals(v)) { - System.out.printf(" containsKey(%s) : %b%n", k, attrs.containsKey(k)); - System.out.printf(" get(%s) : %s%n", k, attrs.get(k)); - throw new RuntimeException("expected attr: k=<" + k + ">, v=<" + v + ">"); - } + var expectedMsg = "expected attr: k=<" + k + ">, v=<" + v + ">"; + assertTrue(attrs.containsKey(k), + " containsKey(%s) : %b%n%s".formatted(k, attrs.containsKey(k), expectedMsg)); + assertEquals(v, attrs.get(k), + " get(%s) : %s%n%s".formatted(k, attrs.get(k), expectedMsg)); }); } } diff --git a/test/jdk/java/util/jar/JarEntry/GetMethodsReturnClones.java b/test/jdk/java/util/jar/JarEntry/GetMethodsReturnClones.java index 3c4f06dd6f0..a9b35220de3 100644 --- a/test/jdk/java/util/jar/JarEntry/GetMethodsReturnClones.java +++ b/test/jdk/java/util/jar/JarEntry/GetMethodsReturnClones.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2026, Oracle and/or its affiliates. All rights reserved. * 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,20 +26,28 @@ * @bug 6337925 * @summary Ensure that callers cannot modify the internal JarEntry cert and * codesigner arrays. - * @author Sean Mullan + * @run junit GetMethodsReturnClones */ +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.IOException; import java.io.InputStream; import java.security.CodeSigner; import java.security.cert.Certificate; import java.util.*; import java.util.jar.*; +import static org.junit.jupiter.api.Assertions.assertNotNull; + public class GetMethodsReturnClones { private static final String BASE = System.getProperty("test.src", ".") + System.getProperty("file.separator"); + private static List jarEntries; - public static void main(String[] args) throws Exception { + @BeforeAll() + static void setupEntries() throws IOException { List entries = new ArrayList<>(); try (JarFile jf = new JarFile(BASE + "test.jar", true)) { byte[] buffer = new byte[8192]; @@ -55,23 +63,29 @@ public class GetMethodsReturnClones { } } } + jarEntries = entries; + } - for (JarEntry je : entries) { + @Test + void certsTest() { + for (JarEntry je : jarEntries) { Certificate[] certs = je.getCertificates(); - CodeSigner[] signers = je.getCodeSigners(); if (certs != null) { certs[0] = null; certs = je.getCertificates(); - if (certs[0] == null) { - throw new Exception("Modified internal certs array"); - } + assertNotNull(certs[0], "Modified internal certs array"); } + } + } + + @Test + void signersTest() { + for (JarEntry je : jarEntries) { + CodeSigner[] signers = je.getCodeSigners(); if (signers != null) { signers[0] = null; signers = je.getCodeSigners(); - if (signers[0] == null) { - throw new Exception("Modified internal codesigners array"); - } + assertNotNull(signers[0], "Modified internal codesigners array"); } } } diff --git a/test/jdk/java/util/jar/JarFile/Constructor.java b/test/jdk/java/util/jar/JarFile/Constructor.java index 8c1a8623e61..071c68fdd9e 100644 --- a/test/jdk/java/util/jar/JarFile/Constructor.java +++ b/test/jdk/java/util/jar/JarFile/Constructor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * 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,55 +21,45 @@ * questions. */ -/** +/* * @test * @bug 4842702 8211765 * @summary Check that constructors throw specified exceptions - * @author Martin Buchholz + * @run junit Constructor */ +import org.junit.jupiter.api.Test; + import java.util.jar.JarFile; import java.io.File; import java.io.IOException; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class Constructor { - private static void Unreached (Object o) - throws Exception - { - // Should never get here - throw new Exception ("Expected exception was not thrown"); - } - public static void main(String[] args) - throws Exception - { - try { Unreached (new JarFile ((File) null, true, JarFile.OPEN_READ)); } - catch (NullPointerException e) {} + @Test + void constructorTest() { - try { Unreached (new JarFile ((File) null, true)); } - catch (NullPointerException e) {} + assertThrows(NullPointerException.class, () -> new JarFile ((File) null, true, JarFile.OPEN_READ)); - try { Unreached (new JarFile ((File) null)); } - catch (NullPointerException e) {} + assertThrows(NullPointerException.class, () -> new JarFile ((File) null, true)); - try { Unreached (new JarFile ((String) null, true)); } - catch (NullPointerException e) {} + assertThrows(NullPointerException.class, () -> new JarFile ((File) null)); - try { Unreached (new JarFile ((String) null)); } - catch (NullPointerException e) {} + assertThrows(NullPointerException.class, () -> new JarFile ((String) null, true)); - try { Unreached (new JarFile ("NoSuchJar.jar")); } - catch (IOException e) {} + assertThrows(NullPointerException.class, () -> new JarFile ((String) null)); - try { Unreached (new JarFile (new File ("NoSuchJar.jar"))); } - catch (IOException e) {} + assertThrows(IOException.class, () -> new JarFile ("NoSuchJar.jar")); + + assertThrows(IOException.class, () -> new JarFile (new File ("NoSuchJar.jar"))); // Test that an IOExcception is thrown when an invalid charater // is part of the path on Windows and Unix final String invalidOSPath = System.getProperty("os.name") .startsWith("Windows") ? "C:\\*" : "foo\u0000bar"; - try { Unreached (new JarFile (invalidOSPath)); } - catch (IOException e) {} + assertThrows(IOException.class, () -> new JarFile (invalidOSPath)); } } diff --git a/test/jdk/java/util/jar/JarFile/IgnoreUnrelatedSignatureFiles.java b/test/jdk/java/util/jar/JarFile/IgnoreUnrelatedSignatureFiles.java index 0f55702c1f6..e5a32dfde73 100644 --- a/test/jdk/java/util/jar/JarFile/IgnoreUnrelatedSignatureFiles.java +++ b/test/jdk/java/util/jar/JarFile/IgnoreUnrelatedSignatureFiles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +21,7 @@ * questions. */ -/** +/* * @test * @bug 8300140 * @summary Make sure signature related files in subdirectories of META-INF are not considered for verification @@ -29,12 +29,14 @@ * @modules java.base/sun.security.util * @modules java.base/sun.security.tools.keytool * @modules jdk.jartool/sun.security.tools.jarsigner - * @run main/othervm IgnoreUnrelatedSignatureFiles + * @run junit/othervm IgnoreUnrelatedSignatureFiles */ import jdk.internal.access.JavaUtilZipFileAccess; import jdk.internal.access.SharedSecrets; import jdk.security.jarsigner.JarSigner; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import sun.security.tools.jarsigner.Main; import sun.security.util.SignatureFileVerifier; @@ -62,6 +64,10 @@ 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 org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; + public class IgnoreUnrelatedSignatureFiles { private static final JavaUtilZipFileAccess JUZA = SharedSecrets.getJavaUtilZipFileAccess(); @@ -69,56 +75,76 @@ public class IgnoreUnrelatedSignatureFiles { // This path resides in a subdirectory of META-INF, so it should not be considered signature related public static final String SUBDIR_SF_PATH = "META-INF/subdirectory/META-INF/SIGNER.SF"; + // Jars used for testing. See `setupJars` below for setup + static Path j; + static Path s; + static Path m; + static Path sm; + static Path ca; + static Path cas; - public static void main(String[] args) throws Exception { - + @BeforeAll + static void setupJars() throws Exception { // Regular signed JAR - Path j = createJarFile(); - Path s = signJarFile(j, "SIGNER1", "signed"); + j = createJarFile(); + s = signJarFile(j, "SIGNER1", "signed"); // Singed JAR with unrelated signature files - Path m = moveSignatureRelated(s); - Path sm = signJarFile(m, "SIGNER2", "modified-signed"); + m = moveSignatureRelated(s); + sm = signJarFile(m, "SIGNER2", "modified-signed"); // Signed JAR with custom SIG-* files - Path ca = createCustomAlgJar(); - Path cas = signJarFile(ca, "SIGNER1", "custom-signed"); + ca = createCustomAlgJar(); + cas = signJarFile(ca, "SIGNER1", "custom-signed"); + } - // 0: Sanity check that the basic signed JAR verifies + // Sanity check that the basic signed JAR verifies + @Test + void signedJarVerifyTest() throws IOException { try (JarFile jf = new JarFile(s.toFile(), true)) { Map entries = jf.getManifest().getEntries(); - if (entries.size() != 1) { - throw new Exception("Expected a single manifest entry for the digest of a.txt, instead found entries: " + entries.keySet()); - } + assertEquals(1, entries.size(), + "Expected a single manifest entry for the digest of a.txt, instead found entries: " + entries.keySet()); JarEntry entry = jf.getJarEntry("a.txt"); try (InputStream in = jf.getInputStream(entry)) { in.transferTo(OutputStream.nullOutputStream()); } } - // 1: Check ZipFile.Source.isSignatureRelated + } + + // Check ZipFile.Source.isSignatureRelated + @Test + void zipFileSourceIsSignatureRelatedTest() throws IOException { try (JarFile jarFile = new JarFile(m.toFile())) { List manifestAndSignatureRelatedFiles = JUZA.getManifestAndSignatureRelatedFiles(jarFile); for (String signatureRelatedFile : manifestAndSignatureRelatedFiles) { String dir = signatureRelatedFile.substring(0, signatureRelatedFile.lastIndexOf("/")); - if (!"META-INF".equals(dir)) { - throw new Exception("Signature related file does not reside directly in META-INF/ : " + signatureRelatedFile); - } + assertEquals("META-INF", dir, + "Signature related file does not reside directly in META-INF/ : " + signatureRelatedFile); } } + } - // 2: Check SignatureFileVerifier.isSigningRelated - if (SignatureFileVerifier.isSigningRelated(SUBDIR_SF_PATH)) { - throw new Exception("Signature related file does not reside directly in META-INF/ : " + SUBDIR_SF_PATH); - } + // Check SignatureFileVerifier.isSigningRelated + @Test + void sigFileVerifierIsSigningRelatedTest() { + assertFalse(SignatureFileVerifier.isSigningRelated(SUBDIR_SF_PATH), + "Signature related file does not reside directly in META-INF/ : " + SUBDIR_SF_PATH); + } - // 3: Check JarInputStream with doVerify = true + // Check JarInputStream with doVerify = true + @Test + void jarIStreamDoVerifyTest() throws IOException { try (JarInputStream in = new JarInputStream(Files.newInputStream(m), true)) { - while (in.getNextEntry() != null) { + while (in.getNextEntry() != null) { in.transferTo(OutputStream.nullOutputStream()); } } + } - // 4: Check that a JAR containing unrelated .SF, .RSA files is signed as-if it is unsigned + // Check that a JAR containing unrelated .SF, .RSA files is signed as-if it is unsigned + @Test + void unrelatedFilesUnsignedTest() throws IOException { try (ZipFile zf = new ZipFile(sm.toFile())) { ZipEntry mf = zf.getEntry("META-INF/MANIFEST.MF"); try (InputStream stream = zf.getInputStream(mf)) { @@ -126,19 +152,24 @@ public class IgnoreUnrelatedSignatureFiles { // When JarSigner considers a jar to not be already signed, // the 'Manifest-Version' attributed name will be case-normalized // Assert that manifest-version is not in lowercase - if (manifest.startsWith("manifest-version")) { - throw new Exception("JarSigner unexpectedly treated unsigned jar as signed"); - } + assertFalse(manifest.startsWith("manifest-version"), + "JarSigner unexpectedly treated unsigned jar as signed"); } } + } - // 5: Check that a JAR containing non signature related .SF, .RSA files can be signed + // Check that a JAR containing non signature related .SF, .RSA files can be signed + @Test + void nonSigFileIsSignableTest() throws Exception { try (JarFile jf = new JarFile(sm.toFile(), true)) { checkSignedBy(jf, "a.txt", "CN=SIGNER2"); checkSignedBy(jf, "META-INF/subdirectory/META-INF/SIGNER1.SF", "CN=SIGNER2"); } + } - // 6: Check that JarSigner does not move unrelated [SF,RSA] files to the beginning of signed JARs + // Check that JarSigner does not move unrelated [SF,RSA] files to the beginning of signed JARs + @Test + void jarSignerDoesNotMoveUnrelatedTest() throws IOException { try (JarFile zf = new JarFile(sm.toFile())) { List actualOrder = zf.stream().map(ZipEntry::getName).toList(); @@ -154,23 +185,25 @@ public class IgnoreUnrelatedSignatureFiles { "META-INF/subdirectory2/META-INF/SIGNER1.RSA" ); - if (!expectedOrder.equals(actualOrder)) { - String msg = (""" + assertEquals(expectedOrder, actualOrder, (""" Unexpected file order in JAR with unrelated SF,RSA files Expected order: %s Actual order: %s""") - .formatted(expectedOrder, actualOrder); - throw new Exception(msg); - } + .formatted(expectedOrder, actualOrder)); } + } - // 7: Check that jarsigner ignores unrelated signature files + // Check that jarsigner ignores unrelated signature files + @Test + void jarSignerIgnoresUnrelatedTest() throws Exception { String message = jarSignerVerify(m); - if (message.contains("WARNING")) { - throw new Exception("jarsigner output contains unexpected warning: " +message); - } + assertFalse(message.contains("WARNING"), + "jarsigner output contains unexpected warning: " + message); + } - // 8: Check that SignatureFileVerifier.isSigningRelated handles custom SIG-* files correctly + // Check that SignatureFileVerifier.isSigningRelated handles custom SIG-* files correctly + @Test + void customSIGFilesTest() throws IOException { try (JarFile jf = new JarFile(cas.toFile(), true)) { // These files are not signature-related and should be signed @@ -185,10 +218,9 @@ public class IgnoreUnrelatedSignatureFiles { Set actualSigned = jf.getManifest().getEntries().keySet(); - if (!expectedSigned.equals(actualSigned)) { - throw new Exception("Unexpected MANIFEST entries. Expected %s, got %s" - .formatted(expectedSigned, actualSigned)); - } + assertEquals(expectedSigned, actualSigned, + "Unexpected MANIFEST entries. Expected %s, got %s" + .formatted(expectedSigned, actualSigned)); } } @@ -220,22 +252,17 @@ public class IgnoreUnrelatedSignatureFiles { // Verify that the entry is signed CodeSigner[] signers = je.getCodeSigners(); - if (signers == null) { - throw new Exception(String.format("Expected %s to be signed", name)); - } + assertNotNull(signers, "Expected %s to be signed".formatted(name)); // There should be a single signer - if (signers.length != 1) { - throw new Exception(String.format("Expected %s to be signed by exactly one signer", name)); - } + assertEquals(1, signers.length, + "Expected %s to be signed by exactly one signer".formatted(name)); String actualSigner = ((X509Certificate) signers[0] .getSignerCertPath().getCertificates().get(0)) .getIssuerX500Principal().getName(); - - if (!actualSigner.equals(expectedSigner)) { - throw new Exception(String.format("Expected %s to be signed by %s, was signed by %s", name, expectedSigner, actualSigner)); - } + assertEquals(expectedSigner, actualSigner, + "Expected %s to be signed by %s, was signed by %s".formatted(name, expectedSigner, actualSigner)); } /** diff --git a/test/jdk/java/util/jar/JarFile/JarBacktickManifest.java b/test/jdk/java/util/jar/JarFile/JarBacktickManifest.java index 65d54a67a47..66edf3ae3ee 100644 --- a/test/jdk/java/util/jar/JarFile/JarBacktickManifest.java +++ b/test/jdk/java/util/jar/JarFile/JarBacktickManifest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * @summary Make sure scanning manifest doesn't throw AIOOBE on certain strings containing backticks. * @library /test/lib/ * @build jdk.test.lib.util.JarBuilder - * @run testng JarBacktickManifest + * @run junit JarBacktickManifest */ import java.io.File; @@ -35,19 +35,20 @@ import java.io.IOException; import java.nio.file.Files; import java.util.jar.JarFile; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - import jdk.test.lib.util.JarBuilder; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; + public class JarBacktickManifest { public static final String VERIFY_MANIFEST_JAR = "verifyManifest.jar"; - @BeforeClass - public void initialize() throws Exception { + @BeforeAll + public static void initialize() throws Exception { JarBuilder jb = new JarBuilder(VERIFY_MANIFEST_JAR); jb.addAttribute("Test", " Class-`Path` "); jb.addAttribute("Test2", " Multi-`Release "); @@ -55,14 +56,14 @@ public class JarBacktickManifest { } @Test - public void test() throws Exception { + public void backtickTest() throws Exception { try (JarFile jf = new JarFile(VERIFY_MANIFEST_JAR)) { // do not set runtime versioning - Assert.assertFalse(jf.isMultiRelease(), "Shouldn't be multi-release"); + assertFalse(jf.isMultiRelease(), "Shouldn't be multi-release"); } } - @AfterClass - public void close() throws IOException { + @AfterAll + public static void close() throws IOException { Files.delete(new File(VERIFY_MANIFEST_JAR).toPath()); } } diff --git a/test/jdk/java/util/jar/JarFile/JarNoManifest.java b/test/jdk/java/util/jar/JarFile/JarNoManifest.java index 971ce92f9e9..31301e28975 100644 --- a/test/jdk/java/util/jar/JarFile/JarNoManifest.java +++ b/test/jdk/java/util/jar/JarFile/JarNoManifest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved. * 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,18 +24,25 @@ /* @test @bug 4771616 @summary JarFile.maybeInstantiateVerifier must check for absence of manifest + @run junit JarNoManifest */ +import org.junit.jupiter.api.Test; + import java.io.*; import java.util.jar.*; import java.util.zip.*; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + public class JarNoManifest { - public static void main(String[] args) throws Exception { - File f = new File(System.getProperty("test.src","."), "no-manifest.jar"); - JarFile jar = new JarFile(f); - ZipEntry entry = jar.getEntry("JarNoManifest.java"); - // The following throws a NullPointerException when the bug is present - InputStream in = jar.getInputStream(entry); - } + + @Test + void absentManifestTest() throws IOException { + File f = new File(System.getProperty("test.src", "."), "no-manifest.jar"); + JarFile jar = new JarFile(f); + ZipEntry entry = jar.getEntry("JarNoManifest.java"); + // The following throws a NullPointerException when the bug is present + assertDoesNotThrow(() -> jar.getInputStream(entry)); + } } diff --git a/test/jdk/java/util/jar/JarFile/MevNPE.java b/test/jdk/java/util/jar/JarFile/MevNPE.java index f8627d33324..20ac9f2d796 100644 --- a/test/jdk/java/util/jar/JarFile/MevNPE.java +++ b/test/jdk/java/util/jar/JarFile/MevNPE.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2026, Oracle and/or its affiliates. All rights reserved. * 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,22 +24,27 @@ /* @test * @bug 7023056 * @summary NPE from sun.security.util.ManifestEntryVerifier.verify during Maven build + * @run junit MevNPE */ +import org.junit.jupiter.api.Test; + import java.io.*; import java.util.jar.*; public class MevNPE { - public static void main(String[] args) throws Exception { + + @Test + void noNpeTest() throws IOException { File f = new File(System.getProperty("test.src", "."), "Signed.jar"); try (JarFile jf = new JarFile(f, true)) { try (InputStream s1 = jf.getInputStream( jf.getJarEntry(JarFile.MANIFEST_NAME))) { s1.read(new byte[10000]); - }; + } try (InputStream s2 = jf.getInputStream( jf.getJarEntry(JarFile.MANIFEST_NAME))) { s2.read(new byte[10000]); - }; + } } } } diff --git a/test/jdk/java/util/jar/JarFile/ScanSignedJar.java b/test/jdk/java/util/jar/JarFile/ScanSignedJar.java index fe49cea24aa..75b4732645d 100644 --- a/test/jdk/java/util/jar/JarFile/ScanSignedJar.java +++ b/test/jdk/java/util/jar/JarFile/ScanSignedJar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * 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,35 @@ * questions. */ -/** +/* * @test * @bug 4953126 * @summary Check that a signed JAR file containing an unsupported signer info * attribute can be parsed successfully. + * @run junit ScanSignedJar */ +import org.junit.jupiter.api.Test; + import java.io.File; +import java.io.IOException; import java.io.InputStream; -import java.security.cert.Certificate; import java.util.Enumeration; import java.util.jar.*; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class ScanSignedJar { - public static void main(String[] args) throws Exception { + @Test + void unsupportedSignerTest() throws IOException { boolean isSigned = false; try (JarFile file = new JarFile(new File(System.getProperty("test.src","."), - "bogus-signerinfo-attr.jar"))) { + "bogus-signerinfo-attr.jar"))) { byte[] buffer = new byte[8192]; - for (Enumeration entries = file.entries(); entries.hasMoreElements();) { - JarEntry entry = (JarEntry) entries.nextElement(); + for (Enumeration entries = file.entries(); entries.hasMoreElements();) { + JarEntry entry = entries.nextElement(); try (InputStream jis = file.getInputStream(entry)) { while (jis.read(buffer, 0, buffer.length) != -1) { // read the jar entry @@ -53,14 +59,9 @@ public class ScanSignedJar { isSigned = true; } System.out.println((isSigned ? "[signed] " : "\t ") + - entry.getName()); + entry.getName()); } } - - if (isSigned) { - System.out.println("\nJAR file has signed entries"); - } else { - throw new Exception("Failed to detect that the JAR file is signed"); - } + assertTrue(isSigned, "Failed to detect that the JAR file is signed"); } } diff --git a/test/jdk/java/util/jar/JarFile/SignedJarFileGetInputStream.java b/test/jdk/java/util/jar/JarFile/SignedJarFileGetInputStream.java index 84ad357079d..9e524d5afd0 100644 --- a/test/jdk/java/util/jar/JarFile/SignedJarFileGetInputStream.java +++ b/test/jdk/java/util/jar/JarFile/SignedJarFileGetInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2026, Oracle and/or its affiliates. All rights reserved. * 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,45 +24,38 @@ /* @test * @bug 4845692 8206863 * @summary JarFile.getInputStream should not throw when jar file is signed - * @author Martin Buchholz + * @run junit SignedJarFileGetInputStream */ +import org.junit.jupiter.api.Test; + import java.io.*; import java.util.*; import java.util.jar.*; import java.util.zip.*; -public class SignedJarFileGetInputStream { - public static void main(String args[]) throws Throwable { - JarFile jar = new JarFile( - new File(System.getProperty("test.src", "."), "Signed.jar")); +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; +public class SignedJarFileGetInputStream { + + @Test + void signedJarTest() throws IOException { + JarFile jar = new JarFile( + new File(System.getProperty("test.src", "."), "Signed.jar")); for (Enumeration e = jar.entries(); e.hasMoreElements();) { JarEntry entry = (JarEntry) e.nextElement(); - InputStream is = jar.getInputStream(new ZipEntry(entry.getName())); + InputStream is = assertDoesNotThrow(() -> jar.getInputStream(new ZipEntry(entry.getName()))); is.close(); } - // read(), available() on closed stream should throw IOException InputStream is = jar.getInputStream(new ZipEntry("Test.class")); is.close(); byte[] buffer = new byte[1]; - try { - is.read(); - throw new AssertionError("Should have thrown IOException"); - } catch (IOException success) {} - try { - is.read(buffer); - throw new AssertionError("Should have thrown IOException"); - } catch (IOException success) {} - try { - is.read(buffer, 0, buffer.length); - throw new AssertionError("Should have thrown IOException"); - } catch (IOException success) {} - try { - is.available(); - throw new AssertionError("Should have thrown IOException"); - } catch (IOException success) {} + assertThrows(IOException.class, () -> is.read()); + assertThrows(IOException.class, () -> is.read(buffer)); + assertThrows(IOException.class, () -> is.read(buffer, 0, buffer.length)); + assertThrows(IOException.class, () -> is.available()); } } diff --git a/test/jdk/java/util/jar/JarFile/SignedJarPendingBlock.java b/test/jdk/java/util/jar/JarFile/SignedJarPendingBlock.java index a6f9955a507..a6326be622a 100644 --- a/test/jdk/java/util/jar/JarFile/SignedJarPendingBlock.java +++ b/test/jdk/java/util/jar/JarFile/SignedJarPendingBlock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * 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,15 +21,21 @@ * questions. */ -/** +/* * @test * @modules java.base/sun.security.tools.keytool * @summary JARs with pending block files (where .RSA comes before .SF) should verify correctly + * @run junit SignedJarPendingBlock */ import jdk.security.jarsigner.JarSigner; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.FieldSource; import java.io.File; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; @@ -42,32 +48,47 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class SignedJarPendingBlock { - public static void main(String[] args) throws Exception { + static Path signed; + static Path pendingBlocks; + static Path invalid; + + // Construct the test data + @BeforeAll + static void setup() throws Exception { Path jar = createJarFile(); - Path signed = signJarFile(jar); - Path pendingBlocks = moveBlockFirst(signed); - Path invalid = invalidate(pendingBlocks); - - // 1: Regular signed JAR with no pending blocks should verify - checkSigned(signed); - - // 2: Signed jar with pending blocks should verify - checkSigned(pendingBlocks); - - // 3: Invalid signed jar with pending blocks should throw SecurityException - try { - checkSigned(invalid); - throw new Exception("Expected invalid digest to be detected"); - } catch (SecurityException se) { - // Ignore - } + signed = signJarFile(jar); + pendingBlocks = moveBlockFirst(signed); + invalid = invalidate(pendingBlocks); } - private static void checkSigned(Path b) throws Exception { - try (JarFile jf = new JarFile(b.toFile(), true)) { + // Regular signed JAR with no pending blocks should verify + @Test + void checkValidSignedJar() { + assertDoesNotThrow(() -> checkSigned(signed), + "Valid digest should not fail"); + } + // Signed jar with pending blocks should verify + @Test + void checkValidSignedPendingJar() { + assertDoesNotThrow(() -> checkSigned(pendingBlocks), + "Valid digest should not fail"); + } + + // Invalid signed jar with pending blocks should throw SecurityException + @Test + void checkInvalidSignedJar() { + assertThrows(SecurityException.class, () -> checkSigned(invalid), + "Expected invalid digest to be detected"); + } + + private static void checkSigned(Path b) throws IOException { + try (JarFile jf = new JarFile(b.toFile(), true)) { JarEntry je = jf.getJarEntry("a.txt"); try (InputStream in = jf.getInputStream(je)) { in.transferTo(OutputStream.nullOutputStream()); diff --git a/test/jdk/java/util/jar/JarFile/SorryClosed.java b/test/jdk/java/util/jar/JarFile/SorryClosed.java index 19481347394..38950539c57 100644 --- a/test/jdk/java/util/jar/JarFile/SorryClosed.java +++ b/test/jdk/java/util/jar/JarFile/SorryClosed.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. * 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,43 +24,49 @@ /* @test * @bug 4910572 * @summary Accessing a closed jar file should generate IllegalStateException. - * @author Martin Buchholz + * @run junit SorryClosed */ +import org.junit.jupiter.api.Test; + import java.io.IOException; import java.io.File; import java.util.jar.JarFile; import java.util.zip.ZipEntry; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class SorryClosed { - public static void main(String args[]) throws IOException { - File file = new File(System.getProperty("test.src","."), "test.jar"); - String testEntryName = "test.class"; + private static final File file = new File(System.getProperty("test.src", "."), "test.jar"); + private static final String testEntryName = "test.class"; - try { - JarFile f = new JarFile(file); - ZipEntry e = f.getEntry(testEntryName); - f.close(); - f.getInputStream(e); - } catch (IllegalStateException e) {} // OK + @Test + void getInputStreamTest() throws IOException { + JarFile f = new JarFile(file); + ZipEntry e = f.getEntry(testEntryName); + f.close(); + assertThrows(IllegalStateException.class, () -> f.getInputStream(e)); + } - try { - JarFile f = new JarFile(file); - f.close(); - f.getEntry(testEntryName); - } catch (IllegalStateException e) {} // OK + @Test + void getEntryTest() throws IOException { + JarFile f = new JarFile(file); + f.close(); + assertThrows(IllegalStateException.class, () -> f.getEntry(testEntryName)); + } - try { - JarFile f = new JarFile(file); - f.close(); - f.getJarEntry(testEntryName); - } catch (IllegalStateException e) {} // OK + @Test + void getJarEntryTest() throws IOException { + JarFile f = new JarFile(file); + f.close(); + assertThrows(IllegalStateException.class, () -> f.getJarEntry(testEntryName)); + } - try { - JarFile f = new JarFile(file); - f.close(); - f.getManifest(); - } catch (IllegalStateException e) {} // OK + @Test + void getManifestTest() throws IOException { + JarFile f = new JarFile(file); + f.close(); + assertThrows(IllegalStateException.class, f::getManifest); } } diff --git a/test/jdk/java/util/jar/JarFile/TurkCert.java b/test/jdk/java/util/jar/JarFile/TurkCert.java index 68e3d83e002..216fd535e2b 100644 --- a/test/jdk/java/util/jar/JarFile/TurkCert.java +++ b/test/jdk/java/util/jar/JarFile/TurkCert.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved. * 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,38 +21,35 @@ * questions. */ -/** +/* * @test * @bug 4624534 * @summary Make sure jar certificates work for Turkish locale - * @author kladko + * @run junit/othervm -Duser.language=tr -Duser.country=TR TurkCert */ +import org.junit.jupiter.api.Test; + import java.util.*; import java.util.jar.*; import java.security.cert.*; import java.io.*; +import static org.junit.jupiter.api.Assertions.assertNotNull; + public class TurkCert { - public static void main(String[] args) throws Exception{ - Locale reservedLocale = Locale.getDefault(); - try { - Locale.setDefault(Locale.of("tr", "TR")); - File f = new File(System.getProperty("test.src","."), "test.jar"); - try (JarFile jf = new JarFile(f, true)) { - JarEntry je = (JarEntry)jf.getEntry("test.class"); - try (InputStream is = jf.getInputStream(je)) { - byte[] b = new byte[1024]; - while (is.read(b) != -1) { - } - } - if (je.getCertificates() == null) { - throw new Exception("Null certificate for test.class."); + + @Test + void turkishLocaleTest() throws IOException { + File f = new File(System.getProperty("test.src", "."), "test.jar"); + try (JarFile jf = new JarFile(f, true)) { + JarEntry je = (JarEntry)jf.getEntry("test.class"); + try (InputStream is = jf.getInputStream(je)) { + byte[] b = new byte[1024]; + while (is.read(b) != -1) { } } - } finally { - // restore the default locale - Locale.setDefault(reservedLocale); + assertNotNull(je.getCertificates(), "Null certificate for test.class."); } } } diff --git a/test/jdk/java/util/jar/JarFile/VerifySignedJar.java b/test/jdk/java/util/jar/JarFile/VerifySignedJar.java index bd5490502c9..e1602c0aa46 100644 --- a/test/jdk/java/util/jar/JarFile/VerifySignedJar.java +++ b/test/jdk/java/util/jar/JarFile/VerifySignedJar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved. * 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,18 +21,20 @@ * questions. */ -/** +/* * @test - * @library /test/lib * @modules java.base/sun.security.x509 * @modules java.base/sun.security.tools.keytool * @bug 4419266 4842702 * @summary Make sure verifying signed Jar doesn't throw SecurityException + * @run junit VerifySignedJar */ import jdk.security.jarsigner.JarSigner; +import org.junit.jupiter.api.Test; import sun.security.tools.keytool.CertAndKeyGen; import sun.security.x509.X500Name; +import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; @@ -40,21 +42,24 @@ import java.security.KeyStore; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.Collections; -import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; -import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import static jdk.test.lib.Utils.runAndCheckException; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; public class VerifySignedJar { - public static void main(String[] args) throws Exception { - + @Test + void signedJarSecurityExceptionTest() throws Exception { Path j = createJar(); Path s = signJar(j, keyEntry("cn=duke")); @@ -70,38 +75,30 @@ public class VerifySignedJar { } // Read ZIP and JAR entries by name - Objects.requireNonNull(jf.getEntry("getprop.class")); - Objects.requireNonNull(jf.getJarEntry("getprop.class")); + assertNotNull(jf.getEntry("getprop.class")); + assertNotNull(jf.getJarEntry("getprop.class")); // Make sure we throw NPE on null parameters - runAndCheckException(() -> jf.getEntry(null), NullPointerException.class); - runAndCheckException(() -> jf.getJarEntry(null), NullPointerException.class); - runAndCheckException(() -> jf.getInputStream(null), NullPointerException.class); + assertThrows(NullPointerException.class, () -> jf.getEntry(null)); + assertThrows(NullPointerException.class, () -> jf.getJarEntry(null)); + assertThrows(NullPointerException.class, () -> jf.getInputStream(null)); } catch (SecurityException se) { - throw new Exception("Got SecurityException when verifying signed " + - "jar:" + se); + fail("Got SecurityException when verifying signed jar:" + se); } } // Check that a JAR entry is signed by an expected DN - private static void checkSignedBy(JarEntry e, String expectedDn) throws Exception { + private static void checkSignedBy(JarEntry e, String expectedDn) { Certificate[] certs = e.getCertificates(); - if (certs == null || certs.length == 0) { - throw new Exception("JarEntry has no certificates: " + e.getName()); - } - - if (certs[0] instanceof X509Certificate x) { - String name = x.getSubjectX500Principal().getName(); - if (!name.equalsIgnoreCase(expectedDn)) { - throw new Exception("Expected entry signed by %s, was %s".formatted(name, expectedDn)); - } - } else { - throw new Exception("Expected JarEntry.getCertificate to return X509Certificate"); - } + assertNotNull(certs, "JarEntry has no certificates: " + e.getName()); + assertNotEquals(0, certs.length, "JarEntry has no certificates: " + e.getName()); + var x = assertInstanceOf(X509Certificate.class, certs[0], "Expected JarEntry.getCertificate to return X509Certificate"); + String name = x.getSubjectX500Principal().getName(); + assertTrue(name.equalsIgnoreCase(expectedDn), "Expected entry signed by %s, was %s".formatted(name, expectedDn)); } - private static Path createJar() throws Exception { + private static Path createJar() throws IOException { Path j = Path.of("unsigned.jar"); try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(j))){ out.putNextEntry(new JarEntry("getprop.class")); diff --git a/test/jdk/java/util/jar/JarFile/jarVerification/MultiProviderTest.java b/test/jdk/java/util/jar/JarFile/jarVerification/MultiProviderTest.java index 4d191d7b3cd..b4b7fda081e 100644 --- a/test/jdk/java/util/jar/JarFile/jarVerification/MultiProviderTest.java +++ b/test/jdk/java/util/jar/JarFile/jarVerification/MultiProviderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * jdk.test.lib.JDKToolLauncher * MultiThreadLoad FooService * @modules java.base/jdk.internal.access:+open - * @run main MultiProviderTest - * @run main MultiProviderTest sign + * @run junit MultiProviderTest */ import java.io.File; @@ -51,27 +50,33 @@ import jdk.test.lib.compiler.CompilerUtils; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.util.JarUtils; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import static java.nio.file.StandardOpenOption.CREATE; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import static java.util.Arrays.asList; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; public class MultiProviderTest { private static final String METAINFO = "META-INF/services/FooService"; - private static String COMBO_CP = Utils.TEST_CLASS_PATH + File.pathSeparator; private static String TEST_CLASS_PATH = System.getProperty("test.classes", "."); - private static boolean signJars = false; static final int NUM_JARS = 5; + // Reset per each test run under JUnit default lifecycle + private boolean signJars = false; + private String COMBO_CP = Utils.TEST_CLASS_PATH + File.pathSeparator; private static final String KEYSTORE = "keystore.jks"; private static final String ALIAS = "JavaTest"; private static final String STOREPASS = "changeit"; private static final String KEYPASS = "changeit"; - public static void main(String[] args) throws Throwable { - signJars = args.length >=1 && args[0].equals("sign"); + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void classLoadingTest(boolean sign) throws Throwable { + signJars = sign; initialize(); List cmds = new ArrayList<>(); cmds.add(JDKToolFinder.getJDKTool("java")); @@ -86,18 +91,16 @@ public class MultiProviderTest { "MultiThreadLoad", TEST_CLASS_PATH)); - try { + assertDoesNotThrow(() -> { OutputAnalyzer outputAnalyzer = ProcessTools.executeCommand(cmds.stream() - .filter(t -> !t.isEmpty()) - .toArray(String[]::new)) + .filter(t -> !t.isEmpty()) + .toArray(String[]::new)) .shouldHaveExitValue(0); System.out.println("Output:" + outputAnalyzer.getOutput()); - } catch (Throwable t) { - throw new RuntimeException("Unexpected fail.", t); - } + }); } - public static void initialize() throws Throwable { + public void initialize() throws Throwable { if (signJars) { genKey(); } diff --git a/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarAPI.java b/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarAPI.java index e8abec354ed..1ba25ef6985 100644 --- a/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarAPI.java +++ b/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarAPI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +31,7 @@ * CreateMultiReleaseTestJars * jdk.test.lib.compiler.Compiler * jdk.test.lib.util.JarBuilder - * @run testng MultiReleaseJarAPI + * @run junit MultiReleaseJarAPI */ import java.io.File; @@ -44,37 +44,41 @@ import java.util.Map; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import java.util.jar.JarFile; +import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import jdk.test.lib.RandomFactory; -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.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +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.*; public class MultiReleaseJarAPI { private static final Random RANDOM = RandomFactory.getRandom(); - String userdir = System.getProperty("user.dir","."); - CreateMultiReleaseTestJars creator = new CreateMultiReleaseTestJars(); - File unversioned = new File(userdir, "unversioned.jar"); - File multirelease = new File(userdir, "multi-release.jar"); - File signedmultirelease = new File(userdir, "signed-multi-release.jar"); + private static final String userdir = System.getProperty("user.dir", "."); + private static final CreateMultiReleaseTestJars creator = new CreateMultiReleaseTestJars(); + private static final File unversioned = new File(userdir, "unversioned.jar"); + private static final File multirelease = new File(userdir, "multi-release.jar"); + private static final File signedmultirelease = new File(userdir, "signed-multi-release.jar"); - - @BeforeClass - public void initialize() throws Exception { + @BeforeAll + public static void initialize() throws Exception { creator.compileEntries(); creator.buildUnversionedJar(); creator.buildMultiReleaseJar(); creator.buildSignedMultiReleaseJar(); } - @AfterClass - public void close() throws IOException { + @AfterAll + public static void close() throws IOException { Files.delete(unversioned.toPath()); Files.delete(multirelease.toPath()); Files.delete(signedmultirelease.toPath()); @@ -83,19 +87,19 @@ public class MultiReleaseJarAPI { @Test public void isMultiReleaseJar() throws Exception { try (JarFile jf = new JarFile(unversioned)) { - Assert.assertFalse(jf.isMultiRelease()); + assertFalse(jf.isMultiRelease()); } try (JarFile jf = new JarFile(unversioned, true, ZipFile.OPEN_READ, Runtime.version())) { - Assert.assertFalse(jf.isMultiRelease()); + assertFalse(jf.isMultiRelease()); } try (JarFile jf = new JarFile(multirelease)) { - Assert.assertTrue(jf.isMultiRelease()); + assertTrue(jf.isMultiRelease()); } try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Runtime.version())) { - Assert.assertTrue(jf.isMultiRelease()); + assertTrue(jf.isMultiRelease()); } testCustomMultiReleaseValue("true", true); @@ -155,45 +159,46 @@ public class MultiReleaseJarAPI { creator.buildCustomMultiReleaseJar(fileName, value, extraAttributes); File custom = new File(userdir, fileName); try (JarFile jf = new JarFile(custom, true, ZipFile.OPEN_READ, Runtime.version())) { - Assert.assertEquals(jf.isMultiRelease(), expected); + assertEquals(expected, jf.isMultiRelease()); } Files.delete(custom.toPath()); } - @DataProvider(name = "versions") - public Object[][] createVersionData() throws Exception { - return new Object[][]{ - {JarFile.baseVersion(), 8}, - {JarFile.runtimeVersion(), Runtime.version().major()}, - {Runtime.version(), Runtime.version().major()}, - {Runtime.Version.parse("7.1"), JarFile.baseVersion().major()}, - {Runtime.Version.parse("9"), 9}, - {Runtime.Version.parse("9.1.5-ea+200"), 9} - }; + public static Stream createVersionData() { + return Stream.of( + Arguments.of(JarFile.baseVersion(), 8), + Arguments.of(JarFile.runtimeVersion(), Runtime.version().major()), + Arguments.of(Runtime.version(), Runtime.version().major()), + Arguments.of(Runtime.Version.parse("7.1"), JarFile.baseVersion().major()), + Arguments.of(Runtime.Version.parse("9"), 9), + Arguments.of(Runtime.Version.parse("9.1.5-ea+200"), 9) + ); } - @Test(dataProvider="versions") + @ParameterizedTest + @MethodSource("createVersionData") public void testVersioning(Runtime.Version value, int xpected) throws Exception { Runtime.Version expected = Runtime.Version.parse(String.valueOf(xpected)); Runtime.Version base = JarFile.baseVersion(); // multi-release jar, opened as unversioned try (JarFile jar = new JarFile(multirelease)) { - Assert.assertEquals(jar.getVersion(), base); + assertEquals(base, jar.getVersion()); } System.err.println("test versioning for Release " + value); try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, value)) { - Assert.assertEquals(jf.getVersion(), expected); + assertEquals(expected, jf.getVersion()); } // regular, unversioned, jar try (JarFile jf = new JarFile(unversioned, true, ZipFile.OPEN_READ, value)) { - Assert.assertEquals(jf.getVersion(), base); + assertEquals(base, jf.getVersion()); } } - @Test(dataProvider="versions") + @ParameterizedTest + @MethodSource("createVersionData") public void testAliasing(Runtime.Version version, int xpected) throws Exception { int n = Math.max(version.major(), JarFile.baseVersion().major()); Runtime.Version value = Runtime.Version.parse(String.valueOf(n)); @@ -231,7 +236,7 @@ public class MultiReleaseJarAPI { } assert versionedBytes.length > 0; - Assert.assertTrue(Arrays.equals(baseBytes, versionedBytes)); + assertTrue(Arrays.equals(baseBytes, versionedBytes)); } @Test @@ -243,11 +248,11 @@ public class MultiReleaseJarAPI { try (JarFile jf = new JarFile(multirelease)) { ze1 = jf.getEntry(vname); } - Assert.assertEquals(ze1.getName(), vname); + assertEquals(vname, ze1.getName()); try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Runtime.Version.parse("9"))) { ze2 = jf.getEntry(rname); } - Assert.assertEquals(ze2.getName(), rname); - Assert.assertNotEquals(ze1.getName(), ze2.getName()); + assertEquals(rname, ze2.getName()); + assertNotEquals(ze2.getName(), ze1.getName()); } } diff --git a/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarHttpProperties.java b/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarHttpProperties.java index 16f764c6674..7d3a933a619 100644 --- a/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarHttpProperties.java +++ b/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarHttpProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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,17 +31,17 @@ * @build CreateMultiReleaseTestJars * jdk.test.lib.compiler.Compiler * jdk.test.lib.util.JarBuilder - * @run testng MultiReleaseJarHttpProperties - * @run testng/othervm -Djdk.util.jar.version=0 MultiReleaseJarHttpProperties - * @run testng/othervm -Djdk.util.jar.version=8 MultiReleaseJarHttpProperties - * @run testng/othervm -Djdk.util.jar.version=9 MultiReleaseJarHttpProperties - * @run testng/othervm -Djdk.util.jar.version=100 MultiReleaseJarHttpProperties - * @run testng/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarHttpProperties - * @run testng/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarHttpProperties - * @run testng/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarHttpProperties - * @run testng/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarHttpProperties - * @run testng/othervm -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarHttpProperties - * @run testng/othervm -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarHttpProperties + * @run junit MultiReleaseJarHttpProperties + * @run junit/othervm -Djdk.util.jar.version=0 MultiReleaseJarHttpProperties + * @run junit/othervm -Djdk.util.jar.version=8 MultiReleaseJarHttpProperties + * @run junit/othervm -Djdk.util.jar.version=9 MultiReleaseJarHttpProperties + * @run junit/othervm -Djdk.util.jar.version=100 MultiReleaseJarHttpProperties + * @run junit/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarHttpProperties + * @run junit/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarHttpProperties + * @run junit/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarHttpProperties + * @run junit/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarHttpProperties + * @run junit/othervm -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarHttpProperties + * @run junit/othervm -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarHttpProperties */ import java.io.IOException; @@ -56,16 +56,19 @@ import java.util.concurrent.Executors; import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.SimpleFileServer; import jdk.test.lib.net.URIBuilder; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class MultiReleaseJarHttpProperties extends MultiReleaseJarProperties { private HttpServer server; private ExecutorService executor; static final String TESTCONTEXT = "/multi-release.jar"; //mapped to local file path - @BeforeClass + @BeforeAll public void initialize() throws Exception { server = SimpleFileServer.createFileServer(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), Path.of(System.getProperty("user.dir", ".")), SimpleFileServer.OutputLevel.INFO); @@ -86,7 +89,7 @@ public class MultiReleaseJarHttpProperties extends MultiReleaseJarProperties { rootClass = cldr.loadClass("version.Main"); } - @AfterClass + @AfterAll public void close() throws IOException { // Windows requires server to stop before file is deleted if (server != null) { diff --git a/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarProperties.java b/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarProperties.java index cbc9516542e..a742a593868 100644 --- a/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarProperties.java +++ b/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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,17 @@ * @build CreateMultiReleaseTestJars * jdk.test.lib.compiler.Compiler * jdk.test.lib.util.JarBuilder - * @run testng MultiReleaseJarProperties - * @run testng/othervm -Djdk.util.jar.version=0 MultiReleaseJarProperties - * @run testng/othervm -Djdk.util.jar.version=8 MultiReleaseJarProperties - * @run testng/othervm -Djdk.util.jar.version=9 MultiReleaseJarProperties - * @run testng/othervm -Djdk.util.jar.version=100 MultiReleaseJarProperties - * @run testng/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarProperties - * @run testng/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarProperties - * @run testng/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarProperties - * @run testng/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarProperties - * @run testng/othervm -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarProperties - * @run testng/othervm -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarProperties + * @run junit MultiReleaseJarProperties + * @run junit/othervm -Djdk.util.jar.version=0 MultiReleaseJarProperties + * @run junit/othervm -Djdk.util.jar.version=8 MultiReleaseJarProperties + * @run junit/othervm -Djdk.util.jar.version=9 MultiReleaseJarProperties + * @run junit/othervm -Djdk.util.jar.version=100 MultiReleaseJarProperties + * @run junit/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarProperties + * @run junit/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarProperties + * @run junit/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarProperties + * @run junit/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarProperties + * @run junit/othervm -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarProperties + * @run junit/othervm -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarProperties */ import java.io.File; @@ -54,12 +54,15 @@ import java.nio.file.Files; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; +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.*; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class MultiReleaseJarProperties { final static int BASE_VERSION = JarFile.baseVersion().major(); @@ -70,7 +73,7 @@ public class MultiReleaseJarProperties { protected ClassLoader cldr; protected Class rootClass; - @BeforeClass + @BeforeAll public void initialize() throws Exception { CreateMultiReleaseTestJars creator = new CreateMultiReleaseTestJars(); creator.compileEntries(); @@ -97,7 +100,7 @@ public class MultiReleaseJarProperties { rootClass = cldr.loadClass("version.Main"); } - @AfterClass + @AfterAll public void close() throws IOException { ((URLClassLoader) cldr).close(); Files.delete(multirelease.toPath()); @@ -115,7 +118,7 @@ public class MultiReleaseJarProperties { protected void invokeMethod(Class vcls, int expected) throws Throwable { MethodType mt = MethodType.methodType(int.class); MethodHandle mh = MethodHandles.lookup().findVirtual(vcls, "getVersion", mt); - Assert.assertEquals(expected, (int) mh.invoke(vcls.newInstance())); + assertEquals(expected, (int) mh.invoke(vcls.newInstance())); } /* @@ -177,7 +180,7 @@ public class MultiReleaseJarProperties { resource = new String(bytes); } String match = "return " + rtVersion + ";"; - Assert.assertTrue(resource.contains(match)); + assertTrue(resource.contains(match)); } @Test @@ -194,6 +197,6 @@ public class MultiReleaseJarProperties { resource = new String(bytes); } String match = "return " + rtVersion + ";"; - Assert.assertTrue(resource.contains(match)); + assertTrue(resource.contains(match)); } } diff --git a/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarSecurity.java b/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarSecurity.java index ec18cad0817..7e0bb2c1ca7 100644 --- a/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarSecurity.java +++ b/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarSecurity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 @@ * @build CreateMultiReleaseTestJars * jdk.test.lib.compiler.Compiler * jdk.test.lib.util.JarBuilder - * @run testng MultiReleaseJarSecurity + * @run junit MultiReleaseJarSecurity */ import java.io.File; @@ -38,45 +38,45 @@ import java.io.InputStream; import java.nio.file.Files; import java.security.CodeSigner; import java.security.cert.Certificate; -import java.util.Arrays; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.zip.ZipFile; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; public class MultiReleaseJarSecurity { static final int MAJOR_VERSION = Runtime.version().major(); - String userdir = System.getProperty("user.dir","."); - File multirelease = new File(userdir, "multi-release.jar"); - File signedmultirelease = new File(userdir, "signed-multi-release.jar"); + static final String USER_DIR = System.getProperty("user.dir", "."); + static final File MULTI_RELEASE = new File(USER_DIR, "multi-release.jar"); + static final File SIGNED_MULTI_RELEASE = new File(USER_DIR, "signed-multi-release.jar"); - @BeforeClass - public void initialize() throws Exception { + @BeforeAll + public static void initialize() throws Exception { CreateMultiReleaseTestJars creator = new CreateMultiReleaseTestJars(); creator.compileEntries(); creator.buildMultiReleaseJar(); creator.buildSignedMultiReleaseJar(); } - @AfterClass - public void close() throws IOException { - Files.delete(multirelease.toPath()); - Files.delete(signedmultirelease.toPath()); + @AfterAll + public static void close() throws IOException { + Files.delete(MULTI_RELEASE.toPath()); + Files.delete(SIGNED_MULTI_RELEASE.toPath()); } @Test public void testCertsAndSigners() throws IOException { - try (JarFile jf = new JarFile(signedmultirelease, true, ZipFile.OPEN_READ, Runtime.version())) { + try (JarFile jf = new JarFile(SIGNED_MULTI_RELEASE, true, ZipFile.OPEN_READ, Runtime.version())) { CertsAndSigners vcas = new CertsAndSigners(jf, jf.getJarEntry("version/Version.class")); CertsAndSigners rcas = new CertsAndSigners(jf, jf.getJarEntry("META-INF/versions/" + MAJOR_VERSION + "/version/Version.class")); - Assert.assertTrue(Arrays.equals(rcas.getCertificates(), vcas.getCertificates())); - Assert.assertTrue(Arrays.equals(rcas.getCodeSigners(), vcas.getCodeSigners())); + assertArrayEquals(rcas.getCertificates(), vcas.getCertificates()); + assertArrayEquals(rcas.getCodeSigners(), vcas.getCodeSigners()); } } diff --git a/test/jdk/java/util/jar/JarFile/mrjar/TestVersionedStream.java b/test/jdk/java/util/jar/JarFile/mrjar/TestVersionedStream.java index dbff39f814e..f88ab0821ae 100644 --- a/test/jdk/java/util/jar/JarFile/mrjar/TestVersionedStream.java +++ b/test/jdk/java/util/jar/JarFile/mrjar/TestVersionedStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +28,7 @@ * @library /test/lib * @build jdk.test.lib.Platform * jdk.test.lib.util.FileUtils - * @run testng TestVersionedStream + * @run junit TestVersionedStream */ import java.io.File; @@ -41,7 +41,6 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -54,18 +53,20 @@ import java.util.stream.Stream; import java.util.zip.ZipFile; import jdk.test.lib.util.FileUtils; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.*; public class TestVersionedStream { - private final Path userdir; - private final Set unversionedEntryNames; + private static final Path userdir; + private static final Set unversionedEntryNames; private static final int LATEST_VERSION = Runtime.version().feature(); - public TestVersionedStream() throws IOException { + static { userdir = Paths.get(System.getProperty("user.dir", ".")); // These are not real class files even though they end with .class. @@ -91,8 +92,7 @@ public class TestVersionedStream { "--release " + LATEST_VERSION + " -C v" + LATEST_VERSION + " ."); System.out.println("Contents of mmr.jar\n======="); - - try(JarFile jf = new JarFile("mmr.jar")) { + try (JarFile jf = new JarFile("mmr.jar")) { unversionedEntryNames = jf.stream() .map(je -> je.getName()) .peek(System.out::println) @@ -100,13 +100,14 @@ public class TestVersionedStream { ? nm.replaceFirst("META-INF/versions/\\d+/", "") : nm) .collect(Collectors.toCollection(LinkedHashSet::new)); + } catch (IOException e) { + throw new RuntimeException("Failed to init \"unversionedEntryNames\"", e); } - System.out.println("======="); } - @AfterClass - public void close() throws IOException { + @AfterAll + public static void close() throws IOException { Files.walk(userdir, 1) .filter(p -> !p.equals(userdir)) .forEach(p -> { @@ -122,53 +123,41 @@ public class TestVersionedStream { }); } - @DataProvider - public Object[][] data() { - return new Object[][] { - {Runtime.Version.parse("8")}, - {Runtime.Version.parse("9")}, - {Runtime.Version.parse("10")}, - {Runtime.Version.parse(Integer.toString(LATEST_VERSION))}, - {JarFile.baseVersion()}, - {JarFile.runtimeVersion()} - }; + public static Stream arguments() { + return Stream.of( + Runtime.Version.parse("8"), + Runtime.Version.parse("9"), + Runtime.Version.parse("10"), + Runtime.Version.parse(Integer.toString(LATEST_VERSION)), + JarFile.baseVersion(), + JarFile.runtimeVersion() + ); } - @Test(dataProvider="data") - public void test(Runtime.Version version) throws Exception { + @ParameterizedTest + @MethodSource("arguments") + public void versionTest(Runtime.Version version) throws Exception { try (JarFile jf = new JarFile(new File("mmr.jar"), false, ZipFile.OPEN_READ, version); Stream jes = jf.versionedStream()) { - Assert.assertNotNull(jes); + assertNotNull(jes); // put versioned entries in list so we can reuse them List versionedEntries = jes.collect(Collectors.toList()); - Assert.assertTrue(versionedEntries.size() > 0); + assertTrue(versionedEntries.size() > 0); // also keep the names - List versionedNames = new ArrayList<>(versionedEntries.size()); + List versionedNames = versionedEntries.stream() + .map(JarEntry::getName) + .collect(Collectors.toList()); // verify the correct order while building enames - Iterator allIt = unversionedEntryNames.iterator(); - Iterator verIt = versionedEntries.iterator(); - boolean match = false; + List unversionedOrder = new ArrayList<>(unversionedEntryNames); + unversionedOrder.retainAll(versionedNames); - while (verIt.hasNext()) { - match = false; - if (!allIt.hasNext()) break; - String name = verIt.next().getName(); - versionedNames.add(name); - while (allIt.hasNext()) { - if (name.equals(allIt.next())) { - match = true; - break; - } - } - } - if (!match) { - Assert.fail("versioned entries not in same order as unversioned entries"); - } + assertIterableEquals(unversionedOrder, versionedNames, + "versioned entries not in same order as unversioned entries"); // verify the contents: // value.[0] end of the path @@ -205,21 +194,21 @@ public class TestVersionedStream { expected.put("q/Bar.class", new String[] { "q/Bar.class", "META-INF/versions/10/q/Bar.class"}); } else { - Assert.fail("Test out of date, please add more cases"); + fail("Test out of date, please add more cases"); } } expected.entrySet().stream().forEach(e -> { String name = e.getKey(); int i = versionedNames.indexOf(name); - Assert.assertTrue(i != -1, name + " not in enames"); + assertTrue(i != -1, name + " not in enames"); JarEntry je = versionedEntries.get(i); try (InputStream is = jf.getInputStream(je)) { String s = new String(is.readAllBytes()).replaceAll(System.lineSeparator(), ""); // end of the path - Assert.assertTrue(s.endsWith(e.getValue()[0]), s); + assertTrue(s.endsWith(e.getValue()[0]), s); // getRealName() - Assert.assertTrue(je.getRealName().equals(e.getValue()[1])); + assertTrue(je.getRealName().equals(e.getValue()[1])); } catch (IOException x) { throw new UncheckedIOException(x); } @@ -227,12 +216,12 @@ public class TestVersionedStream { if (!unversionedEntryNames.contains("META-INF/Foo.class") || versionedNames.indexOf("META-INF/Foo.class") != -1) { - Assert.fail("versioned META-INF/Foo.class test failed"); + fail("versioned META-INF/Foo.class test failed"); } } } - private void createFiles(String... files) { + private static void createFiles(String... files) { ArrayList list = new ArrayList(); Arrays.stream(files) .map(f -> Paths.get(userdir.toAbsolutePath().toString(), f)) @@ -248,7 +237,7 @@ public class TestVersionedStream { }}); } - private void jar(String args) { + private static void jar(String args) { ToolProvider jar = ToolProvider.findFirst("jar").orElseThrow(); jar.run(System.out, System.err, args.split(" +")); } diff --git a/test/jdk/java/util/jar/JarInputStream/EmptyJar.java b/test/jdk/java/util/jar/JarInputStream/EmptyJar.java index 9762455460c..ff961844685 100644 --- a/test/jdk/java/util/jar/JarInputStream/EmptyJar.java +++ b/test/jdk/java/util/jar/JarInputStream/EmptyJar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2026, Oracle and/or its affiliates. All rights reserved. * 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,22 @@ @summary Make sure JarInputStream constructor will not throw NullPointerException when the JAR file is empty. - */ + @run junit EmptyJar + */ + +import org.junit.jupiter.api.Test; import java.util.jar.*; import java.io.*; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + public class EmptyJar { - public static void main(String args[]) throws Exception { - try { - JarInputStream is = new JarInputStream - (new ByteArrayInputStream(new byte[0])); - } catch (NullPointerException e) { - throw new Exception("unexpected NullPointerException"); - } + + @Test + void npeTest() { + // Ensure no NPE is thrown + assertDoesNotThrow(() -> new JarInputStream(new ByteArrayInputStream(new byte[0])), + "unexpected NullPointerException"); } } diff --git a/test/jdk/java/util/jar/JarInputStream/ExtraFileInMetaInf.java b/test/jdk/java/util/jar/JarInputStream/ExtraFileInMetaInf.java index 45865ec0b8f..fe88d225444 100644 --- a/test/jdk/java/util/jar/JarInputStream/ExtraFileInMetaInf.java +++ b/test/jdk/java/util/jar/JarInputStream/ExtraFileInMetaInf.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2026, Oracle and/or its affiliates. All rights reserved. * 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,16 +27,24 @@ * @summary JarInputStream doesn't provide certificates for some file under META-INF * @modules java.base/sun.security.tools.keytool * jdk.jartool/sun.security.tools.jarsigner + * @run junit ExtraFileInMetaInf */ +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + import java.util.jar.*; import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; -public class ExtraFileInMetaInf { - public static void main(String args[]) throws Exception { +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.fail; +public class ExtraFileInMetaInf { + + @BeforeAll + static void setup() throws Exception { // Create a zip file with 2 entries try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("x.jar"))) { @@ -44,7 +52,6 @@ public class ExtraFileInMetaInf { zos.write(new byte[10]); zos.putNextEntry(new ZipEntry("x")); zos.write(new byte[10]); - zos.close(); } // Sign it @@ -54,7 +61,10 @@ public class ExtraFileInMetaInf { "-keyalg rsa -alias a -dname CN=A -genkeypair").split(" ")); sun.security.tools.jarsigner.Main.main( "-keystore ks -storepass changeit x.jar a".split(" ")); + } + @Test + void checkSignedTest() throws IOException { // Check if the entries are signed try (JarInputStream jis = new JarInputStream(new FileInputStream("x.jar"))) { @@ -63,9 +73,7 @@ public class ExtraFileInMetaInf { String name = je.toString(); if (name.equals("META-INF/SUB/file") || name.equals("x")) { while (jis.read(new byte[1000]) >= 0); - if (je.getCertificates() == null) { - throw new Exception(name + " not signed"); - } + assertNotNull(je.getCertificates(), name + " not signed"); } } } diff --git a/test/jdk/java/util/jar/JarInputStream/ScanSignedJar.java b/test/jdk/java/util/jar/JarInputStream/ScanSignedJar.java index 86dbf793e74..23e0a81c4cf 100644 --- a/test/jdk/java/util/jar/JarInputStream/ScanSignedJar.java +++ b/test/jdk/java/util/jar/JarInputStream/ScanSignedJar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2026, Oracle and/or its affiliates. All rights reserved. * 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,19 @@ * @test * @bug 6284489 * @summary Confirm that JarEntry.getCertificates identifies signed entries. + * @run junit ScanSignedJar */ +import org.junit.jupiter.api.Test; + +import java.io.IOException; import java.net.URL; import java.security.CodeSigner; import java.security.cert.Certificate; import java.util.jar.*; +import static org.junit.jupiter.api.Assertions.fail; + /* * Confirm that the signed entries in a JAR file are identified correctly * when JarEntry.getCertificates is used to extract the signer's certificates. @@ -43,13 +49,13 @@ import java.util.jar.*; public class ScanSignedJar { private static final String JAR_LOCATION = - "file:" + - System.getProperty("test.src", ".") + - System.getProperty("file.separator") + - "signed.jar"; - - public static void main(String[] args) throws Exception { + "file:" + + System.getProperty("test.src", ".") + + System.getProperty("file.separator") + + "signed.jar"; + @Test + void signedJarTest() throws IOException { System.out.println("Opening " + JAR_LOCATION + "..."); JarInputStream inStream = new JarInputStream(new URL(JAR_LOCATION).openStream(), true); @@ -71,7 +77,7 @@ public class ScanSignedJar { System.out.println("[unsigned]\t" + name + "\t(" + size + " bytes)"); if (name.equals("Count.class")) { - throw new Exception("Count.class should be signed"); + fail("Count.class should be signed"); } } else if (signers != null && certificates != null) { System.out.println("[" + signers.length + @@ -80,7 +86,7 @@ public class ScanSignedJar { } else { System.out.println("[*ERROR*]\t" + name + "\t(" + size + " bytes)"); - throw new Exception("Cannot determine whether the entry is " + + fail("Cannot determine whether the entry is " + "signed or unsigned (signers[] doesn't match certs[])."); } } diff --git a/test/jdk/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java b/test/jdk/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java index 2e74eb10069..47dc572aa6b 100644 --- a/test/jdk/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java +++ b/test/jdk/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2026, Oracle and/or its affiliates. All rights reserved. * 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,32 +26,32 @@ * @bug 6544278 * @summary Confirm the JarInputStream throws the SecurityException when * verifying an indexed jar file with corrupted signature + * @run junit TestIndexedJarWithBadSignature */ +import org.junit.jupiter.api.Test; + import java.io.IOException; import java.io.FileInputStream; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class TestIndexedJarWithBadSignature { - public static void main(String...args) throws Throwable { + @Test + void securityExceptionTest() throws IOException { try (JarInputStream jis = new JarInputStream( - new FileInputStream(System.getProperty("test.src", ".") + - System.getProperty("file.separator") + - "BadSignedJar.jar"))) - { - JarEntry je1 = jis.getNextJarEntry(); - while(je1!=null){ - System.out.println("Jar Entry1==>"+je1.getName()); - je1 = jis.getNextJarEntry(); // This should throw Security Exception - } - throw new RuntimeException( - "Test Failed:Security Exception not being thrown"); - } catch (IOException ie){ - ie.printStackTrace(); - } catch (SecurityException e) { - System.out.println("Test passed: Security Exception thrown as expected"); + new FileInputStream(System.getProperty("test.src", ".") + + System.getProperty("file.separator") + + "BadSignedJar.jar"))) { + assertThrows(SecurityException.class, () -> { + JarEntry je1; + while ((je1 = jis.getNextJarEntry()) != null) { + System.out.println("Jar Entry1==>" + je1.getName()); + } + }); } } } diff --git a/test/jdk/java/util/jar/Manifest/CreateManifest.java b/test/jdk/java/util/jar/Manifest/CreateManifest.java index 6655089b56d..2eee24fb0be 100644 --- a/test/jdk/java/util/jar/Manifest/CreateManifest.java +++ b/test/jdk/java/util/jar/Manifest/CreateManifest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2026, Oracle and/or its affiliates. All rights reserved. * 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,40 +27,43 @@ * @summary Jar tools fails to generate manifest correctly when boundary condition hit * @modules jdk.jartool/sun.tools.jar * @compile -XDignore.symbol.file=true CreateManifest.java - * @run main CreateManifest + * @run junit CreateManifest */ +import org.junit.jupiter.api.Test; + +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.jar.*; +import static org.junit.jupiter.api.Assertions.assertNotNull; + public class CreateManifest { -public static void main(String arg[]) throws Exception { + @Test + void boundaryTest() throws IOException { + String jarFileName = "test.jar"; + String ManifestName = "MANIFEST.MF"; - String jarFileName = "test.jar"; - String ManifestName = "MANIFEST.MF"; + // create the MANIFEST.MF file + Files.write(Paths.get(ManifestName), FILE_CONTENTS.getBytes()); - // create the MANIFEST.MF file - Files.write(Paths.get(ManifestName), FILE_CONTENTS.getBytes()); + String [] args = new String [] { "cvfm", jarFileName, ManifestName}; + sun.tools.jar.Main jartool = + new sun.tools.jar.Main(System.out, System.err, "jar"); + jartool.run(args); - String [] args = new String [] { "cvfm", jarFileName, ManifestName}; - sun.tools.jar.Main jartool = - new sun.tools.jar.Main(System.out, System.err, "jar"); - jartool.run(args); - - try (JarFile jf = new JarFile(jarFileName)) { - Manifest m = jf.getManifest(); - String result = m.getMainAttributes().getValue("Class-path"); - if (result == null) - throw new RuntimeException("Failed to add Class-path attribute to manifest"); - } finally { - Files.deleteIfExists(Paths.get(jarFileName)); - Files.deleteIfExists(Paths.get(ManifestName)); + try (JarFile jf = new JarFile(jarFileName)) { + Manifest m = jf.getManifest(); + String result = m.getMainAttributes().getValue("Class-path"); + assertNotNull(result, "Failed to add Class-path attribute to manifest"); + } finally { + Files.deleteIfExists(Paths.get(jarFileName)); + Files.deleteIfExists(Paths.get(ManifestName)); + } } -} - private static final String FILE_CONTENTS = "Class-path: \n" + " /ade/dtsao_re/oracle/emcore//lib/em-core-testconsole-uimodel.jar \n" + diff --git a/test/jdk/java/util/jar/Manifest/IncludeInExceptionsTest.java b/test/jdk/java/util/jar/Manifest/IncludeInExceptionsTest.java index 1e272015087..bb3cd6e23ef 100644 --- a/test/jdk/java/util/jar/Manifest/IncludeInExceptionsTest.java +++ b/test/jdk/java/util/jar/Manifest/IncludeInExceptionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. * 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,7 +21,9 @@ * questions. */ -import java.io.File; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; @@ -30,23 +32,29 @@ import java.util.concurrent.Callable; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; +import java.util.stream.Stream; import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.fail; -/** +/* * @test * @bug 8216362 - * @run main/othervm -Djdk.includeInExceptions=jar IncludeInExceptionsTest yes - * @run main/othervm IncludeInExceptionsTest - * @summary Verify that the property jdk.net.includeInExceptions works as expected + * @run junit/othervm -Djdk.includeInExceptions=jar IncludeInExceptionsTest + * @run junit/othervm IncludeInExceptionsTest + * @summary Verify that the property jdk.includeInExceptions works as expected * when an error occurs while reading an invalid Manifest file. */ + /* * @see Manifest#Manifest(JarVerifier,InputStream,String) * @see Manifest#getErrorPosition */ public class IncludeInExceptionsTest { + private static final boolean includeInExceptions = System.getProperty("jdk.includeInExceptions") != null; + static final String FILENAME = "Unique-Filename-Expected-In_Msg.jar"; static final byte[] INVALID_MANIFEST = ( @@ -66,36 +74,26 @@ public class IncludeInExceptionsTest { return jar; } - static void test(Callable attempt, boolean includeInExceptions) throws Exception { - try { - attempt.call(); - throw new AssertionError("Excpected Exception not thrown"); - } catch (IOException e) { - boolean foundFileName = e.getMessage().contains(FILENAME); - if(includeInExceptions && !foundFileName) { - throw new AssertionError("JAR file name expected but not found in error message"); - } else if (foundFileName && !includeInExceptions) { - throw new AssertionError("JAR file name found but should not be in error message"); - } + @ParameterizedTest + @MethodSource("manifests") + void testInvalidManifest(Callable attempt) { + var ioException = assertThrows(IOException.class, attempt::call); + boolean foundFileName = ioException.getMessage().contains(FILENAME); + if (includeInExceptions && !foundFileName) { + fail("JAR file name expected but not found in error message"); + } else if (foundFileName && !includeInExceptions) { + fail("JAR file name found but should not be in error message"); } } - public static void main(String[] args) throws Exception { - - boolean includeInExceptions; - if(args.length > 0) { - includeInExceptions = true; - System.out.println("**** Running test WITH -Djdk.includeInExceptions=jar"); - } else { - includeInExceptions = false; - System.out.println("**** Running test WITHOUT -Djdk.includeInExceptions=jar"); - } - - test(() -> new JarFile(createJarInvalidManifest(FILENAME)).getManifest(), - includeInExceptions); - test(() -> new JarFile(createJarInvalidManifest("Verifying-" + FILENAME), - true).getManifest(), includeInExceptions); + static Stream> manifests() { + Callable jarName = () -> new JarFile(createJarInvalidManifest(FILENAME)).getManifest(); + Callable jarNameVerify = () -> new JarFile(createJarInvalidManifest("Verifying-" + FILENAME), + true).getManifest(); + return Stream.of( + jarName, + jarNameVerify + ); } - } diff --git a/test/jdk/java/util/jar/Manifest/LineBreakLineWidth.java b/test/jdk/java/util/jar/Manifest/LineBreakLineWidth.java index 8009db75601..f33bd7a276f 100644 --- a/test/jdk/java/util/jar/Manifest/LineBreakLineWidth.java +++ b/test/jdk/java/util/jar/Manifest/LineBreakLineWidth.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * 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,23 +21,22 @@ * questions. */ -import static java.nio.charset.StandardCharsets.UTF_8; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.OutputStream; import java.util.jar.Manifest; import java.util.jar.Attributes; import java.util.jar.Attributes.Name; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import org.junit.jupiter.api.Test; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.jupiter.api.Assertions.*; /** * @test * @bug 6372077 - * @run testng LineBreakLineWidth + * @run junit LineBreakLineWidth * @summary write valid manifests with respect to line breaks * and read any line width */ @@ -99,16 +98,10 @@ public class LineBreakLineWidth { assertMainAndSectionValues(mf, name, value); } - static void writeInvalidManifestThrowsException(String name, String value) - throws IOException { - try { - writeManifest(name, value); - } catch (IllegalArgumentException e) { - // no invalid manifest was produced which is considered acceptable - return; - } - - fail("no error writing manifest considered invalid"); + static void writeInvalidManifestThrowsException(String name, String value) { + // no invalid manifest was produced which is considered acceptable + assertThrows(IllegalArgumentException.class, + () -> writeManifest(name, value), "no error writing manifest considered invalid"); } /** @@ -278,8 +271,8 @@ public class LineBreakLineWidth { String mainValue = mf.getMainAttributes().getValue(name); String sectionValue = mf.getAttributes(name).getValue(name); - assertEquals(value, mainValue, "value different in main section"); - assertEquals(value, sectionValue, "value different in named section"); + assertEquals(mainValue, value, "value different in main section"); + assertEquals(sectionValue, value, "value different in named section"); } } diff --git a/test/jdk/java/util/jar/Manifest/ValueUtf8Coding.java b/test/jdk/java/util/jar/Manifest/ValueUtf8Coding.java index 28921bba868..cad0048f098 100644 --- a/test/jdk/java/util/jar/Manifest/ValueUtf8Coding.java +++ b/test/jdk/java/util/jar/Manifest/ValueUtf8Coding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * 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,8 +21,6 @@ * questions. */ -import static java.nio.charset.StandardCharsets.UTF_8; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -32,13 +30,15 @@ import java.util.jar.Manifest; import java.util.List; import java.util.ArrayList; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import org.junit.jupiter.api.Test; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.jupiter.api.Assertions.*; /** * @test * @bug 8066619 8351567 - * @run testng ValueUtf8Coding + * @run junit ValueUtf8Coding * @summary Tests encoding and decoding manifest header values to and from * UTF-8 with the complete Unicode character set. */ /* @@ -187,11 +187,11 @@ public class ValueUtf8Coding { String value = values.get(i); Name name = azName(i); - assertEquals(mf.getMainAttributes().getValue(name), value, + assertEquals(value, mf.getMainAttributes().getValue(name), "main attributes header value"); Attributes attributes = mf.getAttributes(value); assertNotNull(attributes, "named section"); - assertEquals(attributes.getValue(name), value, + assertEquals(value, attributes.getValue(name), "named section attributes value"); } } diff --git a/test/jdk/java/util/jar/Manifest/WriteBinaryStructure.java b/test/jdk/java/util/jar/Manifest/WriteBinaryStructure.java index 379de6b1adb..f91b518aa6c 100644 --- a/test/jdk/java/util/jar/Manifest/WriteBinaryStructure.java +++ b/test/jdk/java/util/jar/Manifest/WriteBinaryStructure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * 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,22 @@ * questions. */ -import static java.nio.charset.StandardCharsets.UTF_8; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.jar.Attributes; import java.util.jar.Attributes.Name; import java.util.jar.Manifest; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import org.junit.jupiter.api.Test; -/** +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.jupiter.api.Assertions.*; + +/* * @test * @bug 8066619 - * @run testng WriteBinaryStructure * @summary Tests that jar manifests are written in a particular structure + * @run junit WriteBinaryStructure */ public class WriteBinaryStructure { @@ -47,10 +47,11 @@ public class WriteBinaryStructure { mf.getMainAttributes().put(new Name("Key"), "Value"); ByteArrayOutputStream buf = new ByteArrayOutputStream(); mf.write(buf); - assertEquals(buf.toByteArray(), ( + assertArrayEquals(( "Manifest-Version: 1.0\r\n" + "Key: Value\r\n" + - "\r\n").getBytes(UTF_8)); + "\r\n").getBytes(UTF_8), + buf.toByteArray()); } @Test @@ -62,12 +63,12 @@ public class WriteBinaryStructure { attributes.put(new Name("Key"), "Value"); ByteArrayOutputStream buf = new ByteArrayOutputStream(); mf.write(buf); - assertEquals(buf.toByteArray(), ( + assertArrayEquals(( "Manifest-Version: 1.0\r\n" + "\r\n" + "Name: Individual-Section-Name\r\n" + "Key: Value\r\n" + - "\r\n").getBytes(UTF_8)); + "\r\n").getBytes(UTF_8), + buf.toByteArray()); } - } diff --git a/test/jdk/java/util/jar/TestExtra.java b/test/jdk/java/util/jar/TestExtra.java index fa6408ba570..776b5e67d14 100644 --- a/test/jdk/java/util/jar/TestExtra.java +++ b/test/jdk/java/util/jar/TestExtra.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2026, Oracle and/or its affiliates. All rights reserved. * 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,180 +21,84 @@ * questions. */ -/** +/* * @test * @bug 6480504 6303183 * @summary Test that client-provided data in the extra field is written and * read correctly, taking into account the JAR_MAGIC written into the extra - * field of the first entry of JAR files. - * @author Dave Bristor + * field of the first entry of JAR files. ZIP file specific. + * @run junit TestExtra */ +import org.junit.jupiter.api.Test; + import java.io.*; import java.nio.charset.Charset; -import java.util.Arrays; +import java.nio.charset.StandardCharsets; import java.util.jar.*; import java.util.zip.*; -/** - * Tests that the get/set operations on extra data in zip and jar files work - * as advertised. The base class tests ZIP files, the member class - * TestJarExtra checks JAR files. - */ -public class TestExtra { - static final int JAR_MAGIC = 0xcafe; // private IN JarOutputStream.java - static final int TEST_HEADER = 0xbabe; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; - static final Charset ascii = Charset.forName("ASCII"); +// Tests that the get/set operations on extra data in ZIP files work as advertised. +public class TestExtra { + + static final int TEST_HEADER = 0xbabe; + static final Charset ascii = StandardCharsets.US_ASCII; // ZipEntry extra data static final byte[][] extra = new byte[][] { - ascii.encode("hello, world").array(), - ascii.encode("foo bar").array() + ascii.encode("hello, world").array(), + ascii.encode("foo bar").array() }; - // For naming entries in JAR/ZIP streams - int count = 1; + // For naming entries in ZIP streams + static int count = 1; // Use byte arrays instead of files - ByteArrayOutputStream baos; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); - // JAR/ZIP content written here. - ZipOutputStream zos; + // ZIP content written here. + ZipOutputStream zos = assertDoesNotThrow(() -> getOutputStream(baos)); - public static void realMain(String[] args) throws Throwable{ - new TestExtra().testHeaderPlusData(); - - new TestJarExtra().testHeaderPlusData(); - new TestJarExtra().testHeaderOnly(); - new TestJarExtra().testClientJarMagic(); - } - - TestExtra() { - try { - baos = new ByteArrayOutputStream(); - zos = getOutputStream(baos); - } catch (Throwable t) { - unexpected(t); - } - } - - /** Test that a header + data set by client works. */ + // Test that a header + data set by client works. + @Test void testHeaderPlusData() throws IOException { for (byte[] b : extra) { ZipEntry ze = getEntry(); byte[] data = new byte[b.length + 4]; set16(data, 0, TEST_HEADER); set16(data, 2, b.length); - for (int i = 0; i < b.length; i++) { - data[i + 4] = b[i]; - } + System.arraycopy(b, 0, data, 4, b.length); ze.setExtra(data); zos.putNextEntry(ze); } zos.close(); - ZipInputStream zis = getInputStream(); - ZipEntry ze = zis.getNextEntry(); checkEntry(ze, 0, extra[0].length); - ze = zis.getNextEntry(); checkEntry(ze, 1, extra[1].length); } - /** Test that a header only (i.e., no extra "data") set by client works. */ - void testHeaderOnly() throws IOException { - ZipEntry ze = getEntry(); - byte[] data = new byte[4]; - set16(data, 0, TEST_HEADER); - set16(data, 2, 0); // Length of data is 0. - ze.setExtra(data); - zos.putNextEntry(ze); - - zos.close(); - - ZipInputStream zis = getInputStream(); - - ze = zis.getNextEntry(); - checkExtra(data, ze.getExtra()); - checkEntry(ze, 0, 0); - } - - /** Tests the client providing extra data which uses JAR_MAGIC header. */ - void testClientJarMagic() throws IOException { - ZipEntry ze = getEntry(); - byte[] data = new byte[8]; - - set16(data, 0, TEST_HEADER); - set16(data, 2, 0); // Length of data is 0. - set16(data, 4, JAR_MAGIC); - set16(data, 6, 0); // Length of data is 0. - - ze.setExtra(data); - zos.putNextEntry(ze); - - zos.close(); - - ZipInputStream zis = getInputStream(); - ze = zis.getNextEntry(); - byte[] e = ze.getExtra(); - checkExtra(data, ze.getExtra()); - checkEntry(ze, 0, 0); - } - - // check if all "expected" extra fields equal to their - // corresponding fields in "extra". The "extra" might have - // timestamp fields added by ZOS. - static void checkExtra(byte[] expected, byte[] extra) { - if (expected == null) - return; - int off = 0; - int len = expected.length; - while (off + 4 < len) { - int tag = get16(expected, off); - int sz = get16(expected, off + 2); - int off0 = 0; - int len0 = extra.length; - boolean matched = false; - while (off0 + 4 < len0) { - int tag0 = get16(extra, off0); - int sz0 = get16(extra, off0 + 2); - if (tag == tag0 && sz == sz0) { - matched = true; - for (int i = 0; i < sz; i++) { - if (expected[off + i] != extra[off0 +i]) - matched = false; - } - break; - } - off0 += (4 + sz0); - } - if (!matched) { - fail("Expected extra data [tag=" + tag + "sz=" + sz + "] check failed"); - } - off += (4 + sz); - } - } - - /** Check that the entry's extra data is correct. */ + // Check that the entry's extra data is correct. void checkEntry(ZipEntry ze, int count, int dataLength) { byte[] extraData = ze.getExtra(); byte[] data = getField(TEST_HEADER, extraData); - if (!check(data != null, "unexpected null data for TEST_HEADER")) { - return; - } - + assertNotNull(data, "unexpected null data for TEST_HEADER"); if (dataLength == 0) { - check(data.length == 0, "unexpected non-zero data length for TEST_HEADER"); + assertEquals(0, data.length, "unexpected non-zero data length for TEST_HEADER"); } else { - check(Arrays.equals(extra[count], data), - "failed to get entry " + ze.getName() - + ", expected " + new String(extra[count]) + ", got '" + new String(data) + "'"); + assertArrayEquals(data, extra[count], + "failed to get entry " + ze.getName() + + ", expected " + new String(extra[count]) + ", got '" + new String(data) + "'"); } } - /** Look up descriptor in data, returning corresponding byte[]. */ + // Look up descriptor in data, returning corresponding byte[]. static byte[] getField(int descriptor, byte[] data) { byte[] rc = null; try { @@ -218,69 +122,23 @@ public class TestExtra { ZipInputStream getInputStream() { return new ZipInputStream( - new ByteArrayInputStream(baos.toByteArray())); + new ByteArrayInputStream(baos.toByteArray())); } - ZipOutputStream getOutputStream(ByteArrayOutputStream baos) throws IOException { + ZipOutputStream getOutputStream(ByteArrayOutputStream baos) { return new ZipOutputStream(baos); } - ZipInputStream getInputStream(ByteArrayInputStream bais) throws IOException { - return new ZipInputStream(bais); + ZipEntry getEntry() { + return new ZipEntry("zip" + count++ + ".txt"); } - ZipEntry getEntry() { return new ZipEntry("zip" + count++ + ".txt"); } - - - private static int get16(byte[] b, int off) { - return (b[off] & 0xff) | ((b[off+1] & 0xff) << 8); + static int get16(byte[] b, int off) { + return (b[off] & 0xff) | ((b[off + 1] & 0xff) << 8); } - private static void set16(byte[] b, int off, int value) { - b[off+0] = (byte)value; - b[off+1] = (byte)(value >> 8); + static void set16(byte[] b, int off, int value) { + b[off + 0] = (byte) value; + b[off + 1] = (byte) (value >> 8); } - - /** Test extra field of a JAR file. */ - static class TestJarExtra extends TestExtra { - ZipOutputStream getOutputStream(ByteArrayOutputStream baos) throws IOException { - return new JarOutputStream(baos); - } - - ZipInputStream getInputStream(ByteArrayInputStream bais) throws IOException { - return new JarInputStream(bais); - } - - ZipEntry getEntry() { return new ZipEntry("jar" + count++ + ".txt"); } - - void checkEntry(ZipEntry ze, int count, int dataLength) { - // zeroth entry should have JAR_MAGIC - if (count == 0) { - byte[] extraData = ze.getExtra(); - byte[] data = getField(JAR_MAGIC, extraData); - if (!check(data != null, "unexpected null data for JAR_MAGIC")) { - check(data.length != 0, "unexpected non-zero data length for JAR_MAGIC"); - } - } - // In a jar file, the first ZipEntry should have both JAR_MAGIC - // and the TEST_HEADER, so check that also. - super.checkEntry(ze, count, dataLength); - } - } - - //--------------------- Infrastructure --------------------------- - static volatile int passed = 0, failed = 0; - static void pass() {passed++;} - static void fail() {failed++; Thread.dumpStack();} - static void fail(String msg) {System.out.println(msg); fail();} - static void unexpected(Throwable t) {failed++; t.printStackTrace();} - static void check(boolean cond) {if (cond) pass(); else fail();} - static boolean check(boolean cond, String msg) {if (cond) pass(); else fail(msg); return cond; } - static void equal(Object x, Object y) { - if (x == null ? y == null : x.equals(y)) pass(); - else fail(x + " not equal to " + y);} - public static void main(String[] args) throws Throwable { - try {realMain(args);} catch (Throwable t) {unexpected(t);} - System.out.println("\nPassed = " + passed + " failed = " + failed); - if (failed > 0) throw new Error("Some tests failed");} } diff --git a/test/jdk/java/util/jar/TestJarExtra.java b/test/jdk/java/util/jar/TestJarExtra.java new file mode 100644 index 00000000000..6619727bfe8 --- /dev/null +++ b/test/jdk/java/util/jar/TestJarExtra.java @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 6480504 6303183 + * @summary Test that client-provided data in the extra field is written and + * read correctly, taking into account the JAR_MAGIC written into the extra + * field of the first entry of JAR files. Jar file specific. + * @run junit TestJarExtra + */ + +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.jar.JarOutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.fail; + +// Tests that the get/set operations on extra data in JAR files work as advertised. +public class TestJarExtra { + + static final int JAR_MAGIC = 0xcafe; // private IN JarOutputStream.java + static final int TEST_HEADER = 0xbabe; + // For naming entries in JAR streams + static int count = 1; + static final Charset ascii = StandardCharsets.US_ASCII; + // ZipEntry extra data + static final byte[][] extra = new byte[][] { + ascii.encode("hello, world").array(), + ascii.encode("foo bar").array() + }; + + // Use byte arrays instead of files + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + // JAR content written here. + JarOutputStream jos = assertDoesNotThrow(() -> getOutputStream(baos)); + + // Test that a header + data set by client works. + @Test + void testHeaderPlusData() throws IOException { + for (byte[] b : extra) { + ZipEntry ze = getEntry(); + byte[] data = new byte[b.length + 4]; + set16(data, 0, TEST_HEADER); + set16(data, 2, b.length); + System.arraycopy(b, 0, data, 4, b.length); + ze.setExtra(data); + jos.putNextEntry(ze); + } + jos.close(); + ZipInputStream zis = getInputStream(); + ZipEntry ze = zis.getNextEntry(); + checkEntry(ze, 0, extra[0].length); + ze = zis.getNextEntry(); + checkEntry(ze, 1, extra[1].length); + } + + // Test that a header only (i.e., no extra "data") set by client works. + @Test + void testHeaderOnly() throws IOException { + ZipEntry ze = getEntry(); + byte[] data = new byte[4]; + set16(data, 0, TEST_HEADER); + set16(data, 2, 0); // Length of data is 0. + ze.setExtra(data); + jos.putNextEntry(ze); + jos.close(); + ZipInputStream zis = getInputStream(); + ze = zis.getNextEntry(); + checkExtra(data, ze.getExtra()); + checkEntry(ze, 0, 0); + } + + // Tests the client providing extra data which uses JAR_MAGIC header. + @Test + void testClientJarMagic() throws IOException { + ZipEntry ze = getEntry(); + byte[] data = new byte[8]; + set16(data, 0, TEST_HEADER); + set16(data, 2, 0); // Length of data is 0. + set16(data, 4, JAR_MAGIC); + set16(data, 6, 0); // Length of data is 0. + ze.setExtra(data); + jos.putNextEntry(ze); + jos.close(); + ZipInputStream zis = getInputStream(); + ze = zis.getNextEntry(); + byte[] e = ze.getExtra(); + checkExtra(data, ze.getExtra()); + checkEntry(ze, 0, 0); + } + + JarOutputStream getOutputStream(ByteArrayOutputStream baos) throws IOException { + return new JarOutputStream(baos); + } + + ZipInputStream getInputStream() { + return new ZipInputStream( + new ByteArrayInputStream(baos.toByteArray())); + } + + ZipEntry getEntry() { + return new ZipEntry("jar" + count++ + ".txt"); + } + + // check if all "expected" extra fields equal to their + // corresponding fields in "extra". The "extra" might have + // timestamp fields added by ZOS. + static void checkExtra(byte[] expected, byte[] extra) { + if (expected == null) + return; + int off = 0; + int len = expected.length; + while (off + 4 < len) { + int tag = get16(expected, off); + int sz = get16(expected, off + 2); + int off0 = 0; + int len0 = extra.length; + boolean matched = false; + while (off0 + 4 < len0) { + int tag0 = get16(extra, off0); + int sz0 = get16(extra, off0 + 2); + if (tag == tag0 && sz == sz0) { + matched = true; + for (int i = 0; i < sz; i++) { + if (expected[off + i] != extra[off0 + i]) + matched = false; + } + break; + } + off0 += (4 + sz0); + } + if (!matched) { + fail("Expected extra data [tag=" + tag + "sz=" + sz + "] check failed"); + } + off += (4 + sz); + } + } + + void checkEntry(ZipEntry ze, int count, int dataLength) { + // zeroth entry should have JAR_MAGIC + if (count == 0) { + byte[] extraData = ze.getExtra(); + byte[] data = getField(JAR_MAGIC, extraData); + assertNotNull(data, "unexpected null data for JAR_MAGIC"); + assertEquals(0, data.length, "unexpected non-zero data length for JAR_MAGIC"); + } + // In a JAR file, the first ZipEntry should have both JAR_MAGIC + // and the TEST_HEADER, so check that also. + byte[] extraData = ze.getExtra(); + byte[] data = getField(TEST_HEADER, extraData); + assertNotNull(data, "unexpected null data for TEST_HEADER"); + if (dataLength == 0) { + assertEquals(0, data.length, "unexpected non-zero data length for TEST_HEADER"); + } else { + assertArrayEquals(data, extra[count], + "failed to get entry " + ze.getName() + + ", expected " + new String(extra[count]) + ", got '" + new String(data) + "'"); + } + } + + // Look up descriptor in data, returning corresponding byte[]. + static byte[] getField(int descriptor, byte[] data) { + byte[] rc = null; + try { + int i = 0; + while (i < data.length) { + if (get16(data, i) == descriptor) { + int length = get16(data, i + 2); + rc = new byte[length]; + for (int j = 0; j < length; j++) { + rc[j] = data[i + 4 + j]; + } + return rc; + } + i += get16(data, i + 2) + 4; + } + } catch (ArrayIndexOutOfBoundsException e) { + // descriptor not found + } + return rc; + } + + static int get16(byte[] b, int off) { + return (b[off] & 0xff) | ((b[off + 1] & 0xff) << 8); + } + + static void set16(byte[] b, int off, int value) { + b[off + 0] = (byte) value; + b[off + 1] = (byte) (value >> 8); + } +} diff --git a/test/jdk/java/util/zip/ZipFile/EndOfCenValidation.java b/test/jdk/java/util/zip/ZipFile/EndOfCenValidation.java index 7adcfb9c128..7ca71c9890a 100644 --- a/test/jdk/java/util/zip/ZipFile/EndOfCenValidation.java +++ b/test/jdk/java/util/zip/ZipFile/EndOfCenValidation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * 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,33 +25,26 @@ * @bug 8272746 * @modules java.base/jdk.internal.util * @summary Verify that ZipFile rejects files with CEN sizes exceeding the implementation limit + * @library /test/lib + * @build jdk.test.lib.util.ZipUtils * @run junit/othervm EndOfCenValidation */ import jdk.internal.util.ArraysSupport; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import java.io.*; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.channels.FileChannel; -import java.nio.charset.StandardCharsets; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.StandardOpenOption; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.HexFormat; -import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; -import java.util.zip.ZipOutputStream; -import static org.junit.jupiter.api.Assertions.*; +import static jdk.test.lib.util.ZipUtils.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * This test augments {@link TestTooManyEntries}. It creates sparse ZIPs where @@ -65,36 +58,13 @@ import static org.junit.jupiter.api.Assertions.*; public class EndOfCenValidation { // Zip files produced by this test - public static final Path CEN_TOO_LARGE_ZIP = Path.of("cen-size-too-large.zip"); - public static final Path INVALID_CEN_SIZE = Path.of("invalid-zen-size.zip"); - public static final Path BAD_CEN_OFFSET_ZIP = Path.of("bad-cen-offset.zip"); - // Some ZipFile constants for manipulating the 'End of central directory record' (END header) - private static final int ENDHDR = ZipFile.ENDHDR; // End of central directory record size - private static final int ENDSIZ = ZipFile.ENDSIZ; // Offset of CEN size field within ENDHDR - private static final int ENDOFF = ZipFile.ENDOFF; // Offset of CEN offset field within ENDHDR + static final Path CEN_TOO_LARGE_ZIP = Path.of("cen-size-too-large.zip"); + static final Path INVALID_CEN_SIZE = Path.of("invalid-zen-size.zip"); + static final Path BAD_CEN_OFFSET_ZIP = Path.of("bad-cen-offset.zip"); + static final Path BAD_ENTRY_COUNT_ZIP = Path.of("bad-entry-count.zip"); + // Maximum allowed CEN size allowed by ZipFile - private static final int MAX_CEN_SIZE = ArraysSupport.SOFT_MAX_ARRAY_LENGTH; - - // Expected message when CEN size does not match file size - private static final String INVALID_CEN_BAD_SIZE = "invalid END header (bad central directory size)"; - // Expected message when CEN offset is too large - private static final String INVALID_CEN_BAD_OFFSET = "invalid END header (bad central directory offset)"; - // Expected message when CEN size is too large - private static final String INVALID_CEN_SIZE_TOO_LARGE = "invalid END header (central directory size too large)"; - // Expected message when total entry count is too large - private static final String INVALID_BAD_ENTRY_COUNT = "invalid END header (total entries count too large)"; - - // A valid ZIP file, used as a template - private byte[] zipBytes; - - /** - * Create a valid ZIP file, used as a template - * @throws IOException if an error occurs - */ - @BeforeEach - public void setup() throws IOException { - zipBytes = templateZip(); - } + static final int MAX_CEN_SIZE = ArraysSupport.SOFT_MAX_ARRAY_LENGTH; /** * Delete big files after test, in case the file system did not support sparse files. @@ -105,6 +75,7 @@ public class EndOfCenValidation { Files.deleteIfExists(CEN_TOO_LARGE_ZIP); Files.deleteIfExists(INVALID_CEN_SIZE); Files.deleteIfExists(BAD_CEN_OFFSET_ZIP); + Files.deleteIfExists(BAD_ENTRY_COUNT_ZIP); } /** @@ -115,14 +86,8 @@ public class EndOfCenValidation { @Test public void shouldRejectTooLargeCenSize() throws IOException { int size = MAX_CEN_SIZE + 1; - Path zip = zipWithModifiedEndRecord(size, true, 0, CEN_TOO_LARGE_ZIP); - - ZipException ex = assertThrows(ZipException.class, () -> { - new ZipFile(zip.toFile()); - }); - - assertEquals(INVALID_CEN_SIZE_TOO_LARGE, ex.getMessage()); + verifyRejection(zip, INVALID_CEN_SIZE_TOO_LARGE); } /** @@ -133,16 +98,9 @@ public class EndOfCenValidation { */ @Test public void shouldRejectInvalidCenSize() throws IOException { - int size = MAX_CEN_SIZE; - Path zip = zipWithModifiedEndRecord(size, false, 0, INVALID_CEN_SIZE); - - ZipException ex = assertThrows(ZipException.class, () -> { - new ZipFile(zip.toFile()); - }); - - assertEquals(INVALID_CEN_BAD_SIZE, ex.getMessage()); + verifyRejection(zip, INVALID_CEN_BAD_SIZE); } /** @@ -153,16 +111,9 @@ public class EndOfCenValidation { */ @Test public void shouldRejectInvalidCenOffset() throws IOException { - int size = MAX_CEN_SIZE; - Path zip = zipWithModifiedEndRecord(size, true, 100, BAD_CEN_OFFSET_ZIP); - - ZipException ex = assertThrows(ZipException.class, () -> { - new ZipFile(zip.toFile()); - }); - - assertEquals(INVALID_CEN_BAD_OFFSET, ex.getMessage()); + verifyRejection(zip, INVALID_CEN_BAD_OFFSET); } /** @@ -181,192 +132,20 @@ public class EndOfCenValidation { Long.MAX_VALUE // Unreasonably large }) public void shouldRejectBadTotalEntries(long totalEntries) throws IOException { - /** - * A small ZIP using the ZIP64 format. - * - * ZIP created using: "echo -n hello | zip zip64.zip -" - * Hex encoded using: "cat zip64.zip | xxd -ps" - * - * The file has the following structure: - * - * 0000 LOCAL HEADER #1 04034B50 - * 0004 Extract Zip Spec 2D '4.5' - * 0005 Extract OS 00 'MS-DOS' - * 0006 General Purpose Flag 0000 - * 0008 Compression Method 0000 'Stored' - * 000A Last Mod Time 5947AB78 'Mon Oct 7 21:27:48 2024' - * 000E CRC 363A3020 - * 0012 Compressed Length FFFFFFFF - * 0016 Uncompressed Length FFFFFFFF - * 001A Filename Length 0001 - * 001C Extra Length 0014 - * 001E Filename '-' - * 001F Extra ID #0001 0001 'ZIP64' - * 0021 Length 0010 - * 0023 Uncompressed Size 0000000000000006 - * 002B Compressed Size 0000000000000006 - * 0033 PAYLOAD hello. - * - * 0039 CENTRAL HEADER #1 02014B50 - * 003D Created Zip Spec 1E '3.0' - * 003E Created OS 03 'Unix' - * 003F Extract Zip Spec 2D '4.5' - * 0040 Extract OS 00 'MS-DOS' - * 0041 General Purpose Flag 0000 - * 0043 Compression Method 0000 'Stored' - * 0045 Last Mod Time 5947AB78 'Mon Oct 7 21:27:48 2024' - * 0049 CRC 363A3020 - * 004D Compressed Length 00000006 - * 0051 Uncompressed Length FFFFFFFF - * 0055 Filename Length 0001 - * 0057 Extra Length 000C - * 0059 Comment Length 0000 - * 005B Disk Start 0000 - * 005D Int File Attributes 0001 - * [Bit 0] 1 Text Data - * 005F Ext File Attributes 11B00000 - * 0063 Local Header Offset 00000000 - * 0067 Filename '-' - * 0068 Extra ID #0001 0001 'ZIP64' - * 006A Length 0008 - * 006C Uncompressed Size 0000000000000006 - * - * 0074 ZIP64 END CENTRAL DIR 06064B50 - * RECORD - * 0078 Size of record 000000000000002C - * 0080 Created Zip Spec 1E '3.0' - * 0081 Created OS 03 'Unix' - * 0082 Extract Zip Spec 2D '4.5' - * 0083 Extract OS 00 'MS-DOS' - * 0084 Number of this disk 00000000 - * 0088 Central Dir Disk no 00000000 - * 008C Entries in this disk 0000000000000001 - * 0094 Total Entries 0000000000000001 - * 009C Size of Central Dir 000000000000003B - * 00A4 Offset to Central dir 0000000000000039 - * - * 00AC ZIP64 END CENTRAL DIR 07064B50 - * LOCATOR - * 00B0 Central Dir Disk no 00000000 - * 00B4 Offset to Central dir 0000000000000074 - * 00BC Total no of Disks 00000001 - * - * 00C0 END CENTRAL HEADER 06054B50 - * 00C4 Number of this disk 0000 - * 00C6 Central Dir Disk no 0000 - * 00C8 Entries in this disk 0001 - * 00CA Total Entries 0001 - * 00CC Size of Central Dir 0000003B - * 00D0 Offset to Central Dir FFFFFFFF - * 00D4 Comment Length 0000 - */ + Path zip = zip64WithModifiedTotalEntries(BAD_ENTRY_COUNT_ZIP, totalEntries); + verifyRejection(zip, INVALID_BAD_ENTRY_COUNT); + } - byte[] zipBytes = HexFormat.of().parseHex(""" - 504b03042d000000000078ab475920303a36ffffffffffffffff01001400 - 2d010010000600000000000000060000000000000068656c6c6f0a504b01 - 021e032d000000000078ab475920303a3606000000ffffffff01000c0000 - 00000001000000b011000000002d010008000600000000000000504b0606 - 2c000000000000001e032d00000000000000000001000000000000000100 - 0000000000003b000000000000003900000000000000504b060700000000 - 740000000000000001000000504b050600000000010001003b000000ffff - ffff0000 - """.replaceAll("\n","")); - - // Buffer to manipulate the above ZIP - ByteBuffer buf = ByteBuffer.wrap(zipBytes).order(ByteOrder.LITTLE_ENDIAN); - // Offset of the 'total entries' in the 'ZIP64 END CENTRAL DIR' record - // Update ZIP64 entry count to a value which cannot possibly fit in the small CEN - buf.putLong(0x94, totalEntries); - // The corresponding END field needs the ZIP64 magic value - buf.putShort(0xCA, (short) 0xFFFF); - // Write the ZIP to disk - Path zipFile = Path.of("bad-entry-count.zip"); - Files.write(zipFile, zipBytes); - - // Verify that the END header is rejected + /** + * Verify that ZipFile rejects the ZIP file with a ZipException + * with the given message + * @param zip ZIP file to open + * @param msg exception message to expect + */ + private static void verifyRejection(Path zip, String msg) { ZipException ex = assertThrows(ZipException.class, () -> { - try (var zf = new ZipFile(zipFile.toFile())) { - } + new ZipFile(zip.toFile()); }); - - assertEquals(INVALID_BAD_ENTRY_COUNT, ex.getMessage()); - } - - /** - * Create an ZIP file with a single entry, then modify the CEN size - * in the 'End of central directory record' (END header) to the given size. - * - * The CEN is optionally "inflated" with trailing zero bytes such that - * its actual size matches the one stated in the END header. - * - * The CEN offset is optiontially adjusted by the given amount - * - * The resulting ZIP is technically not valid, but it does allow us - * to test that large or invalid CEN sizes are rejected - * @param cenSize the CEN size to put in the END record - * @param inflateCen if true, zero-pad the CEN to the desired size - * @param cenOffAdjust Adjust the CEN offset field of the END record with this amount - * @throws IOException if an error occurs - */ - private Path zipWithModifiedEndRecord(int cenSize, - boolean inflateCen, - int cenOffAdjust, - Path zip) throws IOException { - - // A byte buffer for reading the END - ByteBuffer buffer = ByteBuffer.wrap(zipBytes.clone()).order(ByteOrder.LITTLE_ENDIAN); - - // Offset of the END header - int endOffset = buffer.limit() - ENDHDR; - - // Modify the CEN size - int sizeOffset = endOffset + ENDSIZ; - int currentCenSize = buffer.getInt(sizeOffset); - buffer.putInt(sizeOffset, cenSize); - - // Optionally modify the CEN offset - if (cenOffAdjust != 0) { - int offOffset = endOffset + ENDOFF; - int currentCenOff = buffer.getInt(offOffset); - buffer.putInt(offOffset, currentCenOff + cenOffAdjust); - } - - // When creating a sparse file, the file must not already exit - Files.deleteIfExists(zip); - - // Open a FileChannel for writing a sparse file - EnumSet options = EnumSet.of(StandardOpenOption.CREATE_NEW, - StandardOpenOption.WRITE, - StandardOpenOption.SPARSE); - - try (FileChannel channel = FileChannel.open(zip, options)) { - - // Write everything up to END - channel.write(buffer.slice(0, buffer.limit() - ENDHDR)); - - if (inflateCen) { - // Inject "empty bytes" to make the actual CEN size match the END - int injectBytes = cenSize - currentCenSize; - channel.position(channel.position() + injectBytes); - } - // Write the modified END - channel.write(buffer.slice(buffer.limit() - ENDHDR, ENDHDR)); - } - return zip; - } - - /** - * Produce a byte array of a ZIP with a single entry - * - * @throws IOException if an error occurs - */ - private byte[] templateZip() throws IOException { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - try (ZipOutputStream zo = new ZipOutputStream(bout)) { - ZipEntry entry = new ZipEntry("duke.txt"); - zo.putNextEntry(entry); - zo.write("duke".getBytes(StandardCharsets.UTF_8)); - } - return bout.toByteArray(); + assertEquals(msg, ex.getMessage()); } } diff --git a/test/jdk/javax/swing/plaf/metal/MetalTitlePaneBug.java b/test/jdk/javax/swing/plaf/metal/MetalTitlePaneBug.java new file mode 100644 index 00000000000..dde6249752d --- /dev/null +++ b/test/jdk/javax/swing/plaf/metal/MetalTitlePaneBug.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8078744 + * @summary Verifies right half of system menu icon on title bar + * activates when clicked + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MetalTitlePaneBug + */ + +import javax.swing.JFrame; +import javax.swing.UIManager; + +public class MetalTitlePaneBug { + + static final String INSTRUCTIONS = """ + A Frame is shown with a titlepane. + Click on the left edge of the system menu icon on the title pane. + It should show "Restore", "Minimize", "Maximize", "Close" menu. + Click on the right edge of the system menu icon. + It should also show "Restore", "Minimize", "Maximize", "Close" menu. + If it shows, press Pass else press Fail. + """; + + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(MetalTitlePaneBug::createUI) + .build() + .awaitAndCheck(); + } + + static JFrame createUI() { + JFrame.setDefaultLookAndFeelDecorated(true); + JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(200, 100); + return frame; + } +} diff --git a/test/jdk/jdk/nio/zipfs/EndOfCenValidation.java b/test/jdk/jdk/nio/zipfs/EndOfCenValidation.java new file mode 100644 index 00000000000..ed0bdbb52ea --- /dev/null +++ b/test/jdk/jdk/nio/zipfs/EndOfCenValidation.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @modules java.base/jdk.internal.util + * @summary Verify that ZipFileSystem rejects files with CEN sizes exceeding the implementation limit + * @library /test/lib + * @build jdk.test.lib.util.ZipUtils + * @run junit/othervm EndOfCenValidation + */ + +import jdk.internal.util.ArraysSupport; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.zip.ZipException; + +import static jdk.test.lib.util.ZipUtils.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * This test augments {@link TestTooManyEntries}. It creates sparse ZIPs where + * the CEN size is inflated to the desired value. This helps this test run + * fast with much less resources. + * + * While the CEN in these files are zero-filled and the produced ZIPs are technically + * invalid, the CEN is never actually read by ZipFileSystem since it does + * 'End of central directory record' (END header) validation before reading the CEN. + */ +public class EndOfCenValidation { + + // Zip files produced by this test + static final Path CEN_TOO_LARGE_ZIP = Path.of("cen-size-too-large.zip"); + static final Path INVALID_CEN_SIZE = Path.of("invalid-zen-size.zip"); + static final Path BAD_CEN_OFFSET_ZIP = Path.of("bad-cen-offset.zip"); + static final Path BAD_ENTRY_COUNT_ZIP = Path.of("bad-entry-count.zip"); + + // Maximum allowed CEN size allowed by ZipFileSystem + static final int MAX_CEN_SIZE = ArraysSupport.SOFT_MAX_ARRAY_LENGTH; + + /** + * Delete big files after test, in case the file system did not support sparse files. + * @throws IOException if an error occurs + */ + @AfterEach + public void cleanup() throws IOException { + Files.deleteIfExists(CEN_TOO_LARGE_ZIP); + Files.deleteIfExists(INVALID_CEN_SIZE); + Files.deleteIfExists(BAD_CEN_OFFSET_ZIP); + Files.deleteIfExists(BAD_ENTRY_COUNT_ZIP); + } + + /** + * Validates that an 'End of central directory record' (END header) with a CEN + * length exceeding {@link #MAX_CEN_SIZE} limit is rejected + * @throws IOException if an error occurs + */ + @Test + public void shouldRejectTooLargeCenSize() throws IOException { + int size = MAX_CEN_SIZE + 1; + Path zip = zipWithModifiedEndRecord(size, true, 0, CEN_TOO_LARGE_ZIP); + verifyRejection(zip, INVALID_CEN_SIZE_TOO_LARGE); + } + + /** + * Validate that an 'End of central directory record' (END header) + * where the value of the CEN size field exceeds the position of + * the END header is rejected. + * @throws IOException if an error occurs + */ + @Test + public void shouldRejectInvalidCenSize() throws IOException { + int size = MAX_CEN_SIZE; + Path zip = zipWithModifiedEndRecord(size, false, 0, INVALID_CEN_SIZE); + verifyRejection(zip, INVALID_CEN_BAD_SIZE); + } + + /** + * Validate that an 'End of central directory record' (the END header) + * where the value of the CEN offset field is larger than the position + * of the END header minus the CEN size is rejected + * @throws IOException if an error occurs + */ + @Test + public void shouldRejectInvalidCenOffset() throws IOException { + int size = MAX_CEN_SIZE; + Path zip = zipWithModifiedEndRecord(size, true, 100, BAD_CEN_OFFSET_ZIP); + verifyRejection(zip, INVALID_CEN_BAD_OFFSET); + } + + /** + * Validate that a 'Zip64 End of Central Directory' record (the END header) + * where the value of the 'total entries' field is larger than what fits + * in the CEN size is rejected. + * + * @throws IOException if an error occurs + */ + @ParameterizedTest + @ValueSource(longs = { + -1, // Negative + Long.MIN_VALUE, // Very negative + 0x3B / 3L - 1, // Cannot fit in test ZIP's CEN + MAX_CEN_SIZE / 3 + 1, // Too large to allocate int[] entries array + Long.MAX_VALUE // Unreasonably large + }) + public void shouldRejectBadTotalEntries(long totalEntries) throws IOException { + Path zip = zip64WithModifiedTotalEntries(BAD_ENTRY_COUNT_ZIP, totalEntries); + verifyRejection(zip, INVALID_BAD_ENTRY_COUNT); + } + + /** + * Verify that ZipFileSystem.newFileSystem rejects the ZIP file with a ZipException + * with the given message + * @param zip ZIP file to open + * @param msg exception message to expect + */ + private static void verifyRejection(Path zip, String msg) { + ZipException ex = assertThrows(ZipException.class, () -> { + FileSystems.newFileSystem(zip); + }); + assertEquals(msg, ex.getMessage()); + } +} diff --git a/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketReset.java b/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketReset.java index 6b0f365edc7..64779facd26 100644 --- a/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketReset.java +++ b/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketReset.java @@ -21,16 +21,14 @@ * questions. */ -// -// Please run in othervm mode. SunJSSE does not support dynamic system -// properties, no way to re-use system properties in samevm/agentvm mode. -// - /* * @test * @bug 8268965 * @summary Socket reset issue for TLS socket close - * @run main/othervm -Djdk.net.usePlainSocketImpl=true SSLSocketReset + * @comment The test uses SSLContext.getDefault(), so we use othervm to prevent + * usage of unexpected default SSLContext that might be set by some + * other test + * @run main/othervm SSLSocketReset */ import javax.net.ssl.*; diff --git a/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/CommandOutputControlTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/CommandOutputControlTest.java index d71cf7c4d41..b179f32447f 100644 --- a/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/CommandOutputControlTest.java +++ b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/CommandOutputControlTest.java @@ -458,7 +458,7 @@ public class CommandOutputControlTest { processDestroyer.get().join(); } - @DisabledOnOs(value = OS.MAC, disabledReason = "Closing a stream doesn't consistently cause a trouble as it should") + @DisabledOnOs(value = {OS.MAC, OS.LINUX}, disabledReason = "Closing a stream doesn't consistently cause a trouble as expected") @ParameterizedTest @EnumSource(OutputStreams.class) public void test_close_streams(OutputStreams action) throws InterruptedException, IOException { diff --git a/test/lib/jdk/test/lib/Platform.java b/test/lib/jdk/test/lib/Platform.java index 75fdef048bc..170e53930d8 100644 --- a/test/lib/jdk/test/lib/Platform.java +++ b/test/lib/jdk/test/lib/Platform.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2026, Oracle and/or its affiliates. All rights reserved. * 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 @@ import java.nio.file.Paths; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Stream; import static java.util.Locale.ROOT; public class Platform { @@ -188,14 +189,17 @@ public class Platform { } public static boolean isMusl() { - try { - ProcessBuilder pb = new ProcessBuilder("ldd", "--version"); + var lddPath = Stream.of("/bin/ldd", "/usr/bin/ldd").filter(p -> Files.exists(Path.of(p))).findFirst(); + if (lddPath.isPresent()) { + ProcessBuilder pb = new ProcessBuilder(lddPath.get(), "--version"); pb.redirectErrorStream(true); - Process p = pb.start(); - BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream())); - String l = b.readLine(); - if (l != null && l.contains("musl")) { return true; } - } catch(Exception e) { + try (Process p = pb.start()) { + BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream())); + String l = b.readLine(); + return (l != null && l.contains("musl")); + } catch (Exception e) { + e.printStackTrace(); + } } return false; } diff --git a/test/lib/jdk/test/lib/util/ZipUtils.java b/test/lib/jdk/test/lib/util/ZipUtils.java new file mode 100644 index 00000000000..a1568e51cc1 --- /dev/null +++ b/test/lib/jdk/test/lib/util/ZipUtils.java @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.test.lib.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.FileChannel; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.EnumSet; +import java.util.HexFormat; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +/** + * This class consists exclusively of static utility methods that are useful + * for creating and manipulating ZIP files. + */ +public final class ZipUtils { + // Some ZipFile constants for manipulating the 'End of central directory record' (END header) + private static final int ENDHDR = ZipFile.ENDHDR; // End of central directory record size + private static final int ENDSIZ = ZipFile.ENDSIZ; // Offset of CEN size field within ENDHDR + private static final int ENDOFF = ZipFile.ENDOFF; // Offset of CEN offset field within ENDHDR + // Expected message when CEN size does not match file size + public static final String INVALID_CEN_BAD_SIZE = "invalid END header (bad central directory size)"; + // Expected message when CEN offset is too large + public static final String INVALID_CEN_BAD_OFFSET = "invalid END header (bad central directory offset)"; + // Expected message when CEN size is too large + public static final String INVALID_CEN_SIZE_TOO_LARGE = "invalid END header (central directory size too large)"; + // Expected message when total entry count is too large + public static final String INVALID_BAD_ENTRY_COUNT = "invalid END header (total entries count too large)"; + + private ZipUtils() { } + + /** + * Create an ZIP file with a single entry, then modify the CEN size + * in the 'End of central directory record' (END header) to the given size. + * + * The CEN is optionally "inflated" with trailing zero bytes such that + * its actual size matches the one stated in the END header. + * + * The CEN offset is optiontially adjusted by the given amount + * + * The resulting ZIP is technically not valid, but it does allow us + * to test that large or invalid CEN sizes are rejected + * @param cenSize the CEN size to put in the END record + * @param inflateCen if true, zero-pad the CEN to the desired size + * @param cenOffAdjust Adjust the CEN offset field of the END record with this amount + * @throws IOException if an error occurs + */ + public static Path zipWithModifiedEndRecord(int cenSize, + boolean inflateCen, + int cenOffAdjust, + Path zip) throws IOException { + // A byte buffer for reading the END + ByteBuffer buffer = ByteBuffer.wrap(templateZip()).order(ByteOrder.LITTLE_ENDIAN); + + // Offset of the END header + int endOffset = buffer.limit() - ENDHDR; + + // Modify the CEN size + int sizeOffset = endOffset + ENDSIZ; + int currentCenSize = buffer.getInt(sizeOffset); + buffer.putInt(sizeOffset, cenSize); + + // Optionally modify the CEN offset + if (cenOffAdjust != 0) { + int offOffset = endOffset + ENDOFF; + int currentCenOff = buffer.getInt(offOffset); + buffer.putInt(offOffset, currentCenOff + cenOffAdjust); + } + // When creating a sparse file, the file must not already exit + Files.deleteIfExists(zip); + + // Open a FileChannel for writing a sparse file + EnumSet options = EnumSet.of(StandardOpenOption.CREATE_NEW, + StandardOpenOption.WRITE, + StandardOpenOption.SPARSE); + + try (FileChannel channel = FileChannel.open(zip, options)) { + // Write everything up to END + channel.write(buffer.slice(0, buffer.limit() - ENDHDR)); + if (inflateCen) { + // Inject "empty bytes" to make the actual CEN size match the END + int injectBytes = cenSize - currentCenSize; + channel.position(channel.position() + injectBytes); + } + // Write the modified END + channel.write(buffer.slice(buffer.limit() - ENDHDR, ENDHDR)); + } + return zip; + } + + /** + * Create a small Zip64 ZIP file, then modify the Zip64 END header + * with a possibly very large total entry count + * + * @param zip file to write to + * @param totalEntries the number of entries wanted in the Zip64 END header + * @return the modified ZIP file + * @throws IOException if an unexpeced IO error occurs + */ + public static Path zip64WithModifiedTotalEntries(Path zip, long totalEntries) throws IOException { + /** + * A small ZIP using the ZIP64 format. + * + * ZIP created using: "echo -n hello | zip zip64.zip -" + * Hex encoded using: "cat zip64.zip | xxd -ps" + * + * The file has the following structure: + * + * 0000 LOCAL HEADER #1 04034B50 + * 0004 Extract Zip Spec 2D '4.5' + * 0005 Extract OS 00 'MS-DOS' + * 0006 General Purpose Flag 0000 + * 0008 Compression Method 0000 'Stored' + * 000A Last Mod Time 5947AB78 'Mon Oct 7 21:27:48 2024' + * 000E CRC 363A3020 + * 0012 Compressed Length FFFFFFFF + * 0016 Uncompressed Length FFFFFFFF + * 001A Filename Length 0001 + * 001C Extra Length 0014 + * 001E Filename '-' + * 001F Extra ID #0001 0001 'ZIP64' + * 0021 Length 0010 + * 0023 Uncompressed Size 0000000000000006 + * 002B Compressed Size 0000000000000006 + * 0033 PAYLOAD hello. + * + * 0039 CENTRAL HEADER #1 02014B50 + * 003D Created Zip Spec 1E '3.0' + * 003E Created OS 03 'Unix' + * 003F Extract Zip Spec 2D '4.5' + * 0040 Extract OS 00 'MS-DOS' + * 0041 General Purpose Flag 0000 + * 0043 Compression Method 0000 'Stored' + * 0045 Last Mod Time 5947AB78 'Mon Oct 7 21:27:48 2024' + * 0049 CRC 363A3020 + * 004D Compressed Length 00000006 + * 0051 Uncompressed Length FFFFFFFF + * 0055 Filename Length 0001 + * 0057 Extra Length 000C + * 0059 Comment Length 0000 + * 005B Disk Start 0000 + * 005D Int File Attributes 0001 + * [Bit 0] 1 Text Data + * 005F Ext File Attributes 11B00000 + * 0063 Local Header Offset 00000000 + * 0067 Filename '-' + * 0068 Extra ID #0001 0001 'ZIP64' + * 006A Length 0008 + * 006C Uncompressed Size 0000000000000006 + * + * 0074 ZIP64 END CENTRAL DIR 06064B50 + * RECORD + * 0078 Size of record 000000000000002C + * 0080 Created Zip Spec 1E '3.0' + * 0081 Created OS 03 'Unix' + * 0082 Extract Zip Spec 2D '4.5' + * 0083 Extract OS 00 'MS-DOS' + * 0084 Number of this disk 00000000 + * 0088 Central Dir Disk no 00000000 + * 008C Entries in this disk 0000000000000001 + * 0094 Total Entries 0000000000000001 + * 009C Size of Central Dir 000000000000003B + * 00A4 Offset to Central dir 0000000000000039 + * + * 00AC ZIP64 END CENTRAL DIR 07064B50 + * LOCATOR + * 00B0 Central Dir Disk no 00000000 + * 00B4 Offset to Central dir 0000000000000074 + * 00BC Total no of Disks 00000001 + * + * 00C0 END CENTRAL HEADER 06054B50 + * 00C4 Number of this disk 0000 + * 00C6 Central Dir Disk no 0000 + * 00C8 Entries in this disk 0001 + * 00CA Total Entries 0001 + * 00CC Size of Central Dir 0000003B + * 00D0 Offset to Central Dir FFFFFFFF + * 00D4 Comment Length 0000 + */ + + byte[] zipBytes = HexFormat.of().parseHex(""" + 504b03042d000000000078ab475920303a36ffffffffffffffff01001400 + 2d010010000600000000000000060000000000000068656c6c6f0a504b01 + 021e032d000000000078ab475920303a3606000000ffffffff01000c0000 + 00000001000000b011000000002d010008000600000000000000504b0606 + 2c000000000000001e032d00000000000000000001000000000000000100 + 0000000000003b000000000000003900000000000000504b060700000000 + 740000000000000001000000504b050600000000010001003b000000ffff + ffff0000 + """.replaceAll("\n","")); + + // Buffer to manipulate the above ZIP + ByteBuffer buf = ByteBuffer.wrap(zipBytes).order(ByteOrder.LITTLE_ENDIAN); + // Offset of the 'total entries' in the 'ZIP64 END CENTRAL DIR' record + // Update ZIP64 entry count to a value which cannot possibly fit in the small CEN + buf.putLong(0x94, totalEntries); + // The corresponding END field needs the ZIP64 magic value + buf.putShort(0xCA, (short) 0xFFFF); + // Write the ZIP to disk + Files.write(zip, zipBytes); + return zip; + } + + /** + * Produce a byte array of a ZIP with a single entry + * + * @throws IOException if an error occurs + */ + private static byte[] templateZip() throws IOException { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + try (ZipOutputStream zo = new ZipOutputStream(bout)) { + ZipEntry entry = new ZipEntry("duke.txt"); + zo.putNextEntry(entry); + zo.write("duke".getBytes(StandardCharsets.UTF_8)); + } + return bout.toByteArray(); + } +} diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/Float16OperationsBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/Float16OperationsBenchmark.java index ebbfbb01cc6..cbfe9958924 100644 --- a/test/micro/org/openjdk/bench/jdk/incubator/vector/Float16OperationsBenchmark.java +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/Float16OperationsBenchmark.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package org.openjdk.bench.java.lang; +package org.openjdk.bench.jdk.incubator.vector; import java.util.stream.IntStream; import java.util.concurrent.TimeUnit;