Merge branch 'openjdk:master' into pr-jdk-8380425

This commit is contained in:
Simon Tooke 2026-06-08 15:10:59 -04:00 committed by GitHub
commit 490bbb1e44
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
45 changed files with 3085 additions and 413 deletions

View File

@ -109,7 +109,7 @@ endif
EMPTY :=
SPACE := $(EMPTY) $(EMPTY)
COMMA := ,
DNF_ARCHS := $(subst $(SPACE),$(COMMA),$(RPM_ARCHS))
DNF_ARCHS := $(foreach arch,$(RPM_ARCHS),--arch $(arch))
# Specify a dummy installation root, otherwise dnf will run into
# problems trying to reconcile with the local/system state
@ -123,7 +123,7 @@ DNF_DOWNLOAD_FLAGS := \
--disablerepo='*' \
$(DNF_REPOS) \
--resolve \
--archlist $(DNF_ARCHS) \
$(DNF_ARCHS) \
--forcearch $(RPM_ARCH) \
--installroot $(DNF_DUMMY_INSTALL_ROOT) \
--releasever $(BASE_OS_VERSION) \

View File

@ -243,6 +243,16 @@ static LPVOID virtualAllocExNuma(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSiz
return result;
}
void* os::win32::lookup_kernelbase_symbol(const char* name) {
// Pass a small ebuf so dll_load logs failures, but don't use it here to avoid redundancy.
char ebuf[1024];
static void* const handle = os::dll_load("KernelBase", ebuf, sizeof(ebuf));
if (handle == nullptr) {
return nullptr;
}
return os::dll_lookup(handle, name);
}
// Logging wrapper for MapViewOfFileEx
static LPVOID mapViewOfFileEx(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap, LPVOID lpBaseAddress) {
@ -3250,9 +3260,9 @@ char* os::map_memory_to_file(char* base, size_t size, int fd) {
assert(fd != -1, "File descriptor is not valid");
HANDLE fh = (HANDLE)_get_osfhandle(fd);
HANDLE fileMapping = CreateFileMapping(fh, nullptr, PAGE_READWRITE,
HANDLE file_mapping = CreateFileMapping(fh, nullptr, PAGE_READWRITE,
(DWORD)(size >> 32), (DWORD)(size & 0xFFFFFFFF), nullptr);
if (fileMapping == nullptr) {
if (file_mapping == nullptr) {
if (GetLastError() == ERROR_DISK_FULL) {
vm_exit_during_initialization(err_msg("Could not allocate sufficient disk space for Java heap"));
}
@ -3263,9 +3273,9 @@ char* os::map_memory_to_file(char* base, size_t size, int fd) {
return nullptr;
}
LPVOID addr = mapViewOfFileEx(fileMapping, FILE_MAP_WRITE, 0, 0, size, base);
LPVOID addr = mapViewOfFileEx(file_mapping, FILE_MAP_WRITE, 0, 0, size, base);
CloseHandle(fileMapping);
CloseHandle(file_mapping);
return (char*)addr;
}
@ -3278,40 +3288,75 @@ char* os::replace_existing_mapping_with_file_mapping(char* base, size_t size, in
return map_memory_to_file(base, size, fd);
}
// VirtualAlloc2 / MapViewOfFile3 (Windows 1803+). Resolved in os::init_2() via lookup_kernelbase_symbol.
os::win32::VirtualAlloc2Fn os::win32::VirtualAlloc2 = nullptr;
os::win32::MapViewOfFile3Fn os::win32::MapViewOfFile3 = nullptr;
static bool is_VirtualAlloc2_supported() {
return os::win32::VirtualAlloc2 != nullptr;
}
static bool is_MapViewOfFile3_supported() {
return os::win32::MapViewOfFile3 != nullptr;
}
// Multiple threads can race in this code but it's not possible to unmap small sections of
// virtual space to get requested alignment, like posix-like os's.
// Windows prevents multiple thread from remapping over each other so this loop is thread-safe.
static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int file_desc, MemTag mem_tag) {
static char* reserve_memory_aligned(size_t size, size_t alignment, MemTag mem_tag) {
assert(is_aligned(alignment, os::vm_allocation_granularity()),
"Alignment must be a multiple of allocation granularity (page size)");
"Alignment must be a multiple of allocation granularity");
assert(is_aligned(size, os::vm_allocation_granularity()),
"Size must be a multiple of allocation granularity (page size)");
"Size must be a multiple of allocation granularity");
size_t extra_size = size + alignment;
assert(extra_size >= size, "overflow, size is too large to allow alignment");
char* aligned_base = nullptr;
static const int max_attempts = 20;
constexpr int max_attempts = 20;
for (int attempt = 0; attempt < max_attempts && aligned_base == nullptr; attempt ++) {
char* extra_base = file_desc != -1 ? os::map_memory_to_file(extra_size, file_desc, mem_tag) :
os::reserve_memory(extra_size, mem_tag);
char* extra_base = os::reserve_memory(extra_size, mem_tag);
if (extra_base == nullptr) {
return nullptr;
}
// Do manual alignment
aligned_base = align_up(extra_base, alignment);
os::release_memory(extra_base, extra_size);
if (file_desc != -1) {
os::unmap_memory(extra_base, extra_size);
} else {
os::release_memory(extra_base, extra_size);
// A racing thread may have taken this region instead of us, which is why we loop and retry.
aligned_base = os::attempt_reserve_memory_at(aligned_base, size, mem_tag);
}
assert(aligned_base != nullptr,
"Did not manage to reserve after %d attempts (size %zu, alignment %zu)", max_attempts, size, alignment);
return aligned_base;
}
// Similar to reserve_memory_aligned, other reservation/mapping requests can race with this function.
static char* map_memory_aligned(size_t size, size_t alignment, int file_desc, MemTag mem_tag) {
assert(is_aligned(alignment, os::vm_allocation_granularity()),
"Alignment must be a multiple of allocation granularity");
assert(is_aligned(size, os::vm_allocation_granularity()),
"Size must be a multiple of allocation granularity");
size_t extra_size = size + alignment;
assert(extra_size >= size, "overflow, size is too large to allow alignment");
char* aligned_base = nullptr;
constexpr int max_attempts = 20;
for (int attempt = 0; attempt < max_attempts && aligned_base == nullptr; attempt ++) {
char* extra_base = os::map_memory_to_file(extra_size, file_desc, mem_tag);
if (extra_base == nullptr) {
return nullptr;
}
aligned_base = align_up(extra_base, alignment);
os::unmap_memory(extra_base, extra_size);
// Attempt to map, into the just vacated space, the slightly smaller aligned area.
// Which may fail, hence the loop.
aligned_base = file_desc != -1 ? os::attempt_map_memory_to_file_at(aligned_base, size, file_desc, mem_tag) :
os::attempt_reserve_memory_at(aligned_base, size, mem_tag);
// A racing thread may have taken this region instead of us, which is why we loop and retry.
aligned_base = os::attempt_map_memory_to_file_at(aligned_base, size, file_desc, mem_tag);
}
assert(aligned_base != nullptr,
@ -3320,6 +3365,84 @@ static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int fi
return aligned_base;
}
// MapViewOfFile3 supports alignment natively.
static char* map_memory_aligned_va2(size_t size, size_t alignment, int file_desc, MemTag mem_tag) {
assert(file_desc != -1, "File descriptor should not be -1");
assert(is_aligned(alignment, os::vm_allocation_granularity()),
"Alignment must be a multiple of allocation granularity");
assert(is_aligned(size, os::vm_allocation_granularity()),
"Size must be a multiple of allocation granularity");
MEM_ADDRESS_REQUIREMENTS requirements = {0};
requirements.Alignment = alignment;
MEM_EXTENDED_PARAMETER param = {0};
param.Type = MemExtendedParameterAddressRequirements;
param.Pointer = &requirements;
char* aligned_base = nullptr;
// File-backed aligned mapping.
HANDLE fh = (HANDLE)_get_osfhandle(file_desc);
HANDLE file_mapping = CreateFileMapping(fh, nullptr, PAGE_READWRITE,(DWORD)(size >> 32), (DWORD)(size & 0xFFFFFFFF), nullptr);
DWORD err = GetLastError();
if (file_mapping != nullptr) {
aligned_base = (char*)os::win32::MapViewOfFile3(
file_mapping,
GetCurrentProcess(),
nullptr, // let the system choose an aligned address
0, // offset
size,
0, // no special allocation type flags
PAGE_READWRITE,
&param, 1);
err = GetLastError();
CloseHandle(file_mapping);
}
if (aligned_base != nullptr) {
assert(is_aligned(aligned_base, alignment), "Result must be aligned");
MemTracker::record_virtual_memory_reserve_and_commit(aligned_base, size, CALLER_PC, mem_tag);
return aligned_base;
}
log_trace(os)("Aligned allocation via MapViewOfFile3 failed, falling back to retry loop. GetLastError->%lu.", err);
return map_memory_aligned(size, alignment, file_desc, mem_tag);
}
// VirtualAlloc2 supports alignment natively.
static char* reserve_memory_aligned_va2(size_t size, size_t alignment, MemTag mem_tag) {
assert(is_aligned(alignment, os::vm_allocation_granularity()),
"Alignment must be a multiple of allocation granularity");
assert(is_aligned(size, os::vm_allocation_granularity()),
"Size must be a multiple of allocation granularity");
MEM_ADDRESS_REQUIREMENTS requirements = {0};
requirements.Alignment = alignment;
MEM_EXTENDED_PARAMETER param = {0};
param.Type = MemExtendedParameterAddressRequirements;
param.Pointer = &requirements;
char* aligned_base = nullptr;
// Anonymous aligned reservation.
aligned_base = (char*)os::win32::VirtualAlloc2(
GetCurrentProcess(),
nullptr, // let the system choose an aligned address
size,
MEM_RESERVE,
PAGE_READWRITE,
&param, 1);
if (aligned_base != nullptr) {
assert(is_aligned(aligned_base, alignment), "Result must be aligned");
MemTracker::record_virtual_memory_reserve(aligned_base, size, CALLER_PC, mem_tag);
return aligned_base;
}
log_trace(os)("Aligned allocation via VirtualAlloc2 failed, falling back to retry loop. GetLastError->%lu.", GetLastError());
return reserve_memory_aligned(size, alignment, mem_tag);
}
size_t os::commit_memory_limit() {
BOOL is_in_job_object = false;
BOOL res = IsProcessInJob(GetCurrentProcess(), nullptr, &is_in_job_object);
@ -3367,11 +3490,17 @@ size_t os::reserve_memory_limit() {
char* os::reserve_memory_aligned(size_t size, size_t alignment, MemTag mem_tag, bool exec) {
// exec can be ignored
return map_or_reserve_memory_aligned(size, alignment, -1/* file_desc */, mem_tag);
if (is_VirtualAlloc2_supported()) {
return reserve_memory_aligned_va2(size, alignment, mem_tag);
}
return reserve_memory_aligned(size, alignment, mem_tag);
}
char* os::map_memory_to_file_aligned(size_t size, size_t alignment, int fd, MemTag mem_tag) {
return map_or_reserve_memory_aligned(size, alignment, fd, mem_tag);
if (is_MapViewOfFile3_supported()) {
return map_memory_aligned_va2(size, alignment, fd, mem_tag);
}
return map_memory_aligned(size, alignment, fd, mem_tag);
}
char* os::pd_reserve_memory(size_t bytes, bool exec) {
@ -4588,21 +4717,21 @@ jint os::init_2(void) {
// Lookup SetThreadDescription - the docs state we must use runtime-linking of
// kernelbase.dll, so that is what we do.
HINSTANCE _kernelbase = LoadLibrary(TEXT("kernelbase.dll"));
if (_kernelbase != nullptr) {
_SetThreadDescription =
reinterpret_cast<SetThreadDescriptionFnPtr>(
GetProcAddress(_kernelbase,
"SetThreadDescription"));
_SetThreadDescription = reinterpret_cast<SetThreadDescriptionFnPtr>(
os::win32::lookup_kernelbase_symbol("SetThreadDescription"));
#ifdef ASSERT
_GetThreadDescription =
reinterpret_cast<GetThreadDescriptionFnPtr>(
GetProcAddress(_kernelbase,
"GetThreadDescription"));
_GetThreadDescription = reinterpret_cast<GetThreadDescriptionFnPtr>(
os::win32::lookup_kernelbase_symbol("GetThreadDescription"));
#endif
}
log_info(os, thread)("The SetThreadDescription API is%s available.", _SetThreadDescription == nullptr ? " not" : "");
// Prepare KernelBase APIs (VirtualAlloc2, MapViewOfFile3) if available (Windows version 1803).
os::win32::VirtualAlloc2 = reinterpret_cast<os::win32::VirtualAlloc2Fn>(
os::win32::lookup_kernelbase_symbol("VirtualAlloc2"));
os::win32::MapViewOfFile3 = reinterpret_cast<os::win32::MapViewOfFile3Fn>(
os::win32::lookup_kernelbase_symbol("MapViewOfFile3"));
log_debug(os)("VirtualAlloc2 is%s available.", os::win32::VirtualAlloc2 == nullptr ? " not" : "");
log_debug(os)("MapViewOfFile3 is%s available.", os::win32::MapViewOfFile3 == nullptr ? " not" : "");
return JNI_OK;
}

View File

@ -109,6 +109,19 @@ class os::win32 {
// load dll from Windows system directory or Windows directory
static HINSTANCE load_Windows_dll(const char* name, char *ebuf, int ebuflen);
// Resolve a symbol from KernelBase.dll, returns nullptr if not found.
static void* lookup_kernelbase_symbol(const char* name);
// VirtualAlloc2 (since Windows version 1803)
// Resolved from KernelBase during os::init_2() or nullptr if unavailable.
typedef PVOID (WINAPI *VirtualAlloc2Fn)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, MEM_EXTENDED_PARAMETER*, ULONG);
static VirtualAlloc2Fn VirtualAlloc2;
// MapViewOfFile3 (since Windows version 1803)
// Resolved from KernelBase during os::init_2() or nullptr if unavailable.
typedef PVOID (WINAPI *MapViewOfFile3Fn)(HANDLE, HANDLE, PVOID, ULONG64, SIZE_T, ULONG, ULONG, MEM_EXTENDED_PARAMETER*, ULONG);
static MapViewOfFile3Fn MapViewOfFile3;
private:
static void initialize_performance_counter();

View File

@ -31,7 +31,10 @@
#include "memory/metaspaceClosure.hpp"
#include "memory/resourceArea.hpp"
#include "oops/instanceKlass.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/timerTrace.hpp"
#include "utilities/concurrentHashTable.inline.hpp"
#include "utilities/concurrentHashTableTasks.inline.hpp"
#include "utilities/ostream.hpp"
#include "utilities/tableStatistics.hpp"
@ -239,10 +242,24 @@ void Dictionary::verify() {
}
void Dictionary::print_table_statistics(outputStream* st, const char* table_name) {
static TableStatistics ts;
TableStatistics stats;
auto sz = [&] (InstanceKlass** val) {
return sizeof(**val);
};
ts = _table->statistics_get(Thread::current(), sz, ts);
ts.print(st, table_name);
Thread* thread = Thread::current();
ConcurrentTable::StatisticsTask sts(_table);
if (!sts.prepare(thread)) {
st->print_cr("Failed to take statistics");
return;
}
TraceTime timer("GetStatistics", TRACETIME_LOG(Debug, perf));
while (sts.do_task(thread, sz)) {
sts.pause(thread);
if (thread->is_Java_thread()) {
ThreadBlockInVM tbivm(JavaThread::cast(thread));
}
sts.cont(thread);
}
stats = sts.done(thread);
stats.print(st, table_name);
}

View File

@ -66,7 +66,6 @@ class ShenandoahFreeSet;
class ShenandoahConcurrentMark;
class ShenandoahFullGC;
class ShenandoahMonitoringSupport;
class ShenandoahPacer;
class ShenandoahReferenceProcessor;
class ShenandoahUncommitThread;
class ShenandoahVerifier;
@ -534,7 +533,6 @@ private:
ShenandoahCollectorPolicy* _shenandoah_policy;
ShenandoahMode* _gc_mode;
ShenandoahFreeSet* _free_set;
ShenandoahPacer* _pacer;
ShenandoahVerifier* _verifier;
ShenandoahPhaseTimings* _phase_timings;
@ -559,7 +557,6 @@ public:
ShenandoahCollectorPolicy* shenandoah_policy() const { return _shenandoah_policy; }
ShenandoahMode* mode() const { return _gc_mode; }
ShenandoahFreeSet* free_set() const { return _free_set; }
ShenandoahPacer* pacer() const { return _pacer; }
ShenandoahPhaseTimings* phase_timings() const { return _phase_timings; }

View File

@ -654,17 +654,20 @@ public:
// VM.systemdictionary -verbose: for dumping the system dictionary table
//
class VM_DumpHashtable : public VM_Operation {
public:
enum DumpKind {
DumpSymbols,
DumpStrings,
DumpSysDict
};
private:
outputStream* _out;
int _which;
DumpKind _which;
bool _verbose;
public:
enum {
DumpSymbols = 1 << 0,
DumpStrings = 1 << 1,
DumpSysDict = 1 << 2 // not implemented yet
};
VM_DumpHashtable(outputStream* out, int which, bool verbose) {
VM_DumpHashtable(outputStream* out, DumpKind which, bool verbose) {
_out = out;
_which = which;
_verbose = verbose;

View File

@ -534,11 +534,6 @@ class ConcurrentHashTable : public CHeapObj<MT> {
template <typename EVALUATE_FUNC, typename DELETE_FUNC>
void bulk_delete(Thread* thread, EVALUATE_FUNC& eval_f, DELETE_FUNC& del_f);
// Gets statistics if available, if not return old one. Item sizes are calculated with
// VALUE_SIZE_FUNC.
template <typename VALUE_SIZE_FUNC>
TableStatistics statistics_get(Thread* thread, VALUE_SIZE_FUNC& vs_f, TableStatistics old);
// Moves all nodes from this table to to_cht with new hash code.
// Must be done at a safepoint.
void rehash_nodes_to(Thread* thread, ConcurrentHashTable<CONFIG, MT>* to_cht);

View File

@ -1266,22 +1266,6 @@ inline TableStatistics ConcurrentHashTable<CONFIG, MT>::
}
}
template <typename CONFIG, MemTag MT>
template <typename VALUE_SIZE_FUNC>
inline TableStatistics ConcurrentHashTable<CONFIG, MT>::
statistics_get(Thread* thread, VALUE_SIZE_FUNC& vs_f, TableStatistics old)
{
if (!try_resize_lock(thread)) {
return old;
}
InternalTable* table = get_table();
NumberSeq summary;
size_t literal_bytes = 0;
internal_statistics_range(thread, 0, table->_size, vs_f, summary, literal_bytes);
return internal_statistics_epilog(thread, summary, literal_bytes);
}
template <typename CONFIG, MemTag MT>
inline void ConcurrentHashTable<CONFIG, MT>::
rehash_nodes_to(Thread* thread, ConcurrentHashTable<CONFIG, MT>* to_cht)

View File

@ -84,9 +84,9 @@ import sun.util.locale.provider.LocaleProviderAdapter;
* Note: these examples are from CLDR, there could be different results from other locale providers.
* <p>
* Alternatively, Locale, Type, and/or Style independent instances
* can be created with {@link #getInstance(String[])}. The String array to the
* method specifies the delimiting patterns for the start/middle/end portion of
* the formatted string, as well as optional specialized patterns for two or three
* can be created with {@link #getInstance(String[])}. The String array passed to the
* method specifies the delimiting patterns for the {@code start}/{@code middle}/{@code end}
* portion of the formatted string, as well as optional specialized patterns for two or three
* elements. Refer to the method description for more detail.
* <p>
* On parsing, if some ambiguity is found in the input string, such as delimiting
@ -121,7 +121,8 @@ public final class ListFormat extends Format {
/**
* The array of five pattern Strings. Each element corresponds to the Unicode LDML's
* `listPatternsPart` type, i.e, start/middle/end/two/three.
* {@code listPatternPart} type, i.e,
* {@code start}/{@code middle}/{@code end}/{@code two}/{@code three}.
* @serial
*/
private final String[] patterns;
@ -153,6 +154,7 @@ public final class ListFormat extends Format {
var pattern = patterns[START];
var placeholderPositions = findPlaceholders(pattern);
if (placeholderPositions != null &&
placeholderPositions[2] == -1 &&
placeholderPositions[1] + PLACEHOLDER_LENGTH == pattern.length()) {
startBefore = pattern.substring(0, placeholderPositions[0]);
startBetween = pattern.substring(placeholderPositions[0] + PLACEHOLDER_LENGTH,
@ -164,6 +166,7 @@ public final class ListFormat extends Format {
pattern = patterns[MIDDLE];
placeholderPositions = findPlaceholders(pattern);
if (placeholderPositions != null &&
placeholderPositions[2] == -1 &&
placeholderPositions[0] == 0 &&
placeholderPositions[1] + PLACEHOLDER_LENGTH == pattern.length()) {
middleBetween = pattern.substring(placeholderPositions[0] + PLACEHOLDER_LENGTH,
@ -174,7 +177,9 @@ public final class ListFormat extends Format {
pattern = patterns[END];
placeholderPositions = findPlaceholders(pattern);
if (placeholderPositions != null && placeholderPositions[0] == 0) {
if (placeholderPositions != null &&
placeholderPositions[2] == -1 &&
placeholderPositions[0] == 0) {
endBetween = pattern.substring(placeholderPositions[0] + PLACEHOLDER_LENGTH,
placeholderPositions[1]);
endAfter = pattern.substring(placeholderPositions[1] + PLACEHOLDER_LENGTH);
@ -185,7 +190,8 @@ public final class ListFormat extends Format {
// Validate two/three patterns, if given. Otherwise, generate them
pattern = patterns[TWO];
if (!pattern.isEmpty()) {
if (findPlaceholders(pattern) == null) {
placeholderPositions = findPlaceholders(pattern);
if (placeholderPositions == null || placeholderPositions[2] >= 0) {
throw new IllegalArgumentException("pattern for two is incorrect: " + pattern);
}
} else {
@ -245,36 +251,43 @@ public final class ListFormat extends Format {
* instead of letting the runtime provide appropriate patterns for the {@code Locale},
* {@code Type}, or {@code Style}.
* <p>
* The patterns array should contain five String patterns, each corresponding to the Unicode LDML's
* {@code listPatternPart}, i.e., "start", "middle", "end", two element, and three element patterns
* in this order. Each pattern contains "{0}" and "{1}" (and "{2}" for the three element pattern)
* placeholders that are substituted with the passed input strings on formatting.
* If the length of the patterns array is not 5, an {@code IllegalArgumentException}
* is thrown.
* The patterns array should contain five String patterns, each corresponding
* to the Unicode LDML's {@code listPatternPart}, i.e., {@code start},
* {@code middle}, {@code end}, {@code two} element, and {@code three}
* element patterns in this order. Each pattern contains "{0}" and "{1}"
* (and "{2}" for the {@code three} element pattern) placeholders that are
* substituted with the passed input strings on formatting. If the length of
* the patterns array is not 5, an {@code IllegalArgumentException} is thrown.
* <p>
* Each pattern string is first parsed as follows. Literals in parentheses, such as
* "start_before", are optional:
* <blockquote><pre>
* {@snippet :
* start := (start_before){0}start_between{1}
* middle := {0}middle_between{1}
* end := {0}end_between{1}(end_after)
* two := (two_before){0}two_between{1}(two_after)
* three := (three_before){0}three_between1{1}three_between2{2}(three_after)
* </pre></blockquote>
* If two or three pattern string is empty, it falls back to
* {@code "(start_before){0}end_between{1}(end_after)"},
* {@code "(start_before){0}start_between{1}end_between{2}(end_after)"} respectively.
* If parsing of any pattern string for start, middle, end, two, or three fails,
* }
* If the {@code two} or {@code three} pattern string is empty, it falls back to
* {@snippet :
* (start_before){0}end_between{1}(end_after)
* (start_before){0}start_between{1}end_between{2}(end_after)
* }
* respectively.
* If parsing of any pattern string for {@code start}, {@code middle},
* {@code end}, {@code two}, or {@code three} fails, including duplicate
* placeholders, "{2}" in patterns other than the {@code three} element
* pattern, or any use of "{" or "}" other than "{0}", "{1}", or "{2}",
* it throws an {@code IllegalArgumentException}.
* <p>
* On formatting, the input string list with {@code n} elements substitutes above
* placeholders based on the number of elements:
* <blockquote><pre>
* {@snippet :
* n = 1: {0}
* n = 2: parsed pattern for "two"
* n = 3: parsed pattern for "three"
* n > 3: (start_before){0}start_between{1}middle_between{2} ... middle_between{m}end_between{n}(end_after)
* </pre></blockquote>
* }
* As an example, the following table shows a pattern array which is equivalent to
* {@code STANDARD} type, {@code FULL} style in US English:
* <table class="striped">
@ -664,15 +677,37 @@ public final class ListFormat extends Format {
/**
* {@return the positions of the "{0}", "{1}", and "{2}" placeholders in the
* given pattern string, or null if the pattern is invalid}
* Only "{0}", "{1}", or "{2}" placeholders are allowed. Any other use of
* curly braces is not allowed.
*
* The returned array contains -1 for "{2}" if that placeholder is absent.
*
* @param pattern pattern string to parse
*/
private static int[] findPlaceholders(String pattern) {
var positions = new int[3];
for (int i = 0; i < positions.length; i++) {
positions[i] = pattern.indexOf("{" + i + "}");
var positions = new int[] {-1, -1, -1};
for (int i = 0; i < pattern.length(); i++) {
var ch = pattern.charAt(i);
if (ch == '{') {
if (i + PLACEHOLDER_LENGTH > pattern.length() ||
pattern.charAt(i + 1) < '0' ||
pattern.charAt(i + 1) > '2' ||
pattern.charAt(i + 2) != '}') {
return null;
}
// Check for duplicate placeholders
var index = pattern.charAt(i + 1) - '0';
if (positions[index] != -1) {
return null;
}
positions[index] = i;
i += PLACEHOLDER_LENGTH - 1;
} else if (ch == '}') {
return null;
}
}
// Check the existence and order of the placeholders

View File

@ -418,19 +418,15 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
for (;;) {
if ((s = status) < 0)
break;
else if (interrupts < 0) {
s = ABNORMAL; // interrupted and not done
break;
}
else if (Thread.interrupted()) {
if (!ForkJoinPool.poolIsStopping(pool))
interrupts = interruptible ? -1 : 1;
else {
interrupts = 1; // re-assert if cleared
if (ForkJoinPool.poolIsStopping(pool)) {
try {
cancel(true);
} catch (Throwable ignore) {
}
} catch (Throwable ignore) { }
}
if ((interrupts = interruptible ? -1 : 1) < 0) {
s = ABNORMAL;
break;
}
}
else if (deadline != 0L) {

View File

@ -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
@ -351,4 +351,9 @@ class Http2ClientImpl {
public boolean stopping() {
return stopping;
}
// getConnections() is used only by tests.
Map<String, Http2Connection> getConnections() {
return connections;
}
}

View File

@ -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
@ -52,7 +52,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Function;
import java.util.function.Supplier;
@ -1610,16 +1609,37 @@ class Http2Connection implements Closeable {
return frames;
}
// Dedicated cache for headers encoding ByteBuffer.
// Dedicated reusable ByteBuffer for headers encoding.
// There can be no concurrent access to this buffer as all access to this buffer
// and its content happen within a single critical code block section protected
// by the sendLock. / (see sendFrame())
// private final ByteBufferPool headerEncodingPool = new ByteBufferPool();
// by the sendlock (see sendFrame()).
private ByteBuffer cachedHeaderBuffer;
// getCachedHeaderBuffer() is used only by tests and it should not be
// called in source code without also holding `sendlock`.
ByteBuffer getCachedHeaderBuffer() {
return cachedHeaderBuffer;
}
private ByteBuffer getHeaderBuffer(int size) {
ByteBuffer buf = ByteBuffer.allocate(size);
buf.limit(size);
return buf;
assert sendlock.isHeldByCurrentThread() : "current thread is not holding sendlock";
if (cachedHeaderBuffer == null || cachedHeaderBuffer.capacity() < size) {
cachedHeaderBuffer = ByteBuffer.allocate(size);
return cachedHeaderBuffer;
}
cachedHeaderBuffer.clear();
cachedHeaderBuffer.limit(size);
return cachedHeaderBuffer;
}
private static ByteBuffer copyBuffer(ByteBuffer buffer) {
buffer.flip();
ByteBuffer copy = ByteBuffer.allocate(buffer.remaining());
copy.put(buffer);
copy.flip();
return copy;
}
/*
@ -1634,8 +1654,8 @@ class Http2Connection implements Closeable {
* encoding in HTTP/2...
*/
private List<ByteBuffer> encodeHeadersImpl(int bufferSize, HttpHeaders... headers) {
ByteBuffer buffer = getHeaderBuffer(bufferSize);
List<ByteBuffer> buffers = new ArrayList<>();
ByteBuffer buffer = getHeaderBuffer(bufferSize);
for (HttpHeaders header : headers) {
for (Map.Entry<String, List<String>> e : header.map().entrySet()) {
String lKey = e.getKey().toLowerCase(Locale.US);
@ -1644,16 +1664,17 @@ class Http2Connection implements Closeable {
hpackOut.header(lKey, value);
while (!hpackOut.encode(buffer)) {
if (!buffer.hasRemaining()) {
buffer.flip();
buffers.add(buffer);
buffer = getHeaderBuffer(bufferSize);
ByteBuffer copy = copyBuffer(buffer);
buffers.add(copy);
buffer.clear();
buffer.limit(bufferSize);
}
}
}
}
}
buffer.flip();
buffers.add(buffer);
ByteBuffer copy = copyBuffer(buffer);
buffers.add(copy);
return buffers;
}
@ -1710,7 +1731,7 @@ class Http2Connection implements Closeable {
}
}
private final Lock sendlock = new ReentrantLock();
private final ReentrantLock sendlock = new ReentrantLock();
void sendFrame(Http2Frame frame) {
try {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2024, 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
@ -58,8 +58,8 @@ import java.util.ServiceLoader;
* for example, ships with attach providers that use the package name <i>"sun"</i>
* (for historical reasons). The
* <i>type</i> typically corresponds to the attach mechanism. For example, an
* implementation that uses the Doors inter-process communication mechanism
* might use the type <i>"doors"</i>. The purpose of the name and type is to
* implementation that uses the UNIX Domain Socket inter-process communication mechanism
* might use the type <i>"socket"</i>. The purpose of the name and type is to
* identify providers in environments where there are multiple providers
* installed.
*

View File

@ -137,6 +137,26 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
.title(title)));
}
/**
* Returns a label for the given element to be used the table of contents sidebar.
*
* @param executableElement method or constructor
* @return the link label
*/
protected Content getTOCLabel(ExecutableElement executableElement) {
var signature = utils.makeSignature(executableElement, typeElement, false, true);
var label = new ContentBuilder(Text.of(utils.getSimpleName(executableElement)));
// Insert line break opportunity before first parameter.
if (signature.length() > 2) {
label.add(Text.of(signature.substring(0, 1)))
.add(HtmlTree.WBR())
.add(Text.of(signature.substring(1)));
} else {
label.add(signature);
}
return label;
}
/**
* Adds the generic type parameters.
*

View File

@ -119,9 +119,7 @@ public class ConstructorWriter extends AbstractExecutableMemberWriter {
constructorContent.add(div);
memberList.add(getMemberListItem(constructorContent));
writer.tableOfContents.addLink(htmlIds.forMember(currentConstructor).getFirst(),
Text.of(utils.getSimpleName(constructor)
+ utils.makeSignature(currentConstructor, typeElement, false, true)),
TableOfContents.Level.SECOND);
getTOCLabel(currentConstructor), TableOfContents.Level.SECOND);
}
Content constructorDetails = getConstructorDetails(constructorDetailsHeader, memberList);
target.add(constructorDetails);

View File

@ -118,9 +118,7 @@ public class MethodWriter extends AbstractExecutableMemberWriter {
methodContent.add(div);
memberList.add(writer.getMemberListItem(methodContent));
writer.tableOfContents.addLink(htmlIds.forMember(currentMethod).getFirst(),
Text.of(utils.getSimpleName(method)
+ utils.makeSignature(currentMethod, typeElement, false, true)),
TableOfContents.Level.SECOND);
getTOCLabel(currentMethod), TableOfContents.Level.SECOND);
}
Content methodDetails = getMethodDetails(methodDetailsHeader, memberList);
detailsList.add(methodDetails);

View File

@ -82,6 +82,8 @@
/* Search input colors */
--search-input-background-color: #ffffff;
--search-input-text-color: #000000;
--search-border-light-color: #eaeaea;
--search-border-dark-color: #a6a6a6;
--search-input-placeholder-color: #757575;
--overlay-background: rgba(153, 169, 183, 0.3);
/* Highlight color for active search tag target */
@ -107,23 +109,23 @@
:root[data-theme="theme-dark"] {
--body-text-color: #e8e8e8;
--block-text-color: #e8e8e8;
--body-background-color: #1f2124;
--body-background-color: #202226;
--section-background-color: var(--body-background-color);
--detail-background-color: var(--body-background-color);
--code-background-color: #303940;
--mark-background-color: #313131;
--detail-block-color: #31363c;
--navbar-background-color: #395A6F;
--navbar-background-color: #406074;
--navbar-text-color: #ffffff;
--subnav-background-color: #3d454d;
--subnav-background-color: #434c54;
--subnav-link-color: #d8dcdf;
--member-heading-background-color: var(--subnav-background-color);
--selected-background-color: #f8981d;
--selected-text-color: #253441;
--selected-link-color: #4a698a;
--table-header-color: #38444d;
--even-row-color: #222528;
--odd-row-color: #2d3135;
--even-row-color: #282c2f;
--odd-row-color: #33383b;
--title-color: #fff;
--link-color: #94badb;
--link-color-active: #e8a351;
@ -138,8 +140,10 @@
--border-color: #444444;
--table-border-color: #717171;
--tab-border-radius: 2px 2px 0 0;
--search-input-background-color: #303030;
--search-input-background-color: #202224;
--search-input-text-color: #d0d0d0;
--search-border-light-color: #505050;
--search-border-dark-color: #000000;
--search-input-placeholder-color: #979797;
--overlay-background: rgba(0, 0, 0, 0.45);
--search-tag-background-color: #c6c61e;
@ -192,7 +196,7 @@ body {
width:100%;
}
main [id] {
scroll-margin-top: calc(var(--nav-height) + 6px);
scroll-margin-top: calc(var(--nav-height) + 14px);
}
div.main-grid {
max-width: var(--max-content-width);
@ -246,6 +250,9 @@ h1, h2, h3, h4, h5, h6, div.member-signature, div.member-signature > span {
ul {
list-style-type:disc;
}
main li {
margin-top: 4px;
}
tt {
font-family:var(--code-font-family);
}
@ -486,12 +493,7 @@ body.class-declaration-page .details h3 {
}
body.class-declaration-page section.detail:target > h3,
body.class-declaration-page section.detail > h3:target {
background-color: var(--navbar-background-color);
color: var(--navbar-text-color);
}
body.class-declaration-page section.detail:target > h3 > a.anchor-link > img,
body.class-declaration-page section.detail > h3:target > a.anchor-link > img {
filter: invert(100%) brightness(160%);
box-shadow: -4px 0 0 rgb(from var(--link-color) r g b / 0.7);
}
h1 > sup {
font-size: small;
@ -522,6 +524,9 @@ section.class-description > div.horizontal-scroll > :is(dl, ol, ul, p, div, bloc
section.class-description > div.horizontal-scroll > :last-child > :is(li, dd):last-child {
margin-bottom:4px;
}
dl.notes {
margin-top: 14.2px;
}
dl.notes > dt {
font-family: var(--body-font-family);
font-size:0.856em;
@ -661,9 +666,12 @@ a.current-selection {
}
nav.toc a {
display: block;
padding: 8px;
padding: 7px 8px;
overflow: hidden;
text-overflow: ellipsis;
text-wrap: balance;
text-indent: 0.5em hanging;
line-height: 1.35;
}
nav.toc ol.toc-list ol.toc-list a {
padding-left: 24px;
@ -737,11 +745,13 @@ ul.tag-list li {
display: inline;
}
ul.tag-list li:not(:last-child):after,
ul.tag-list-long li:not(:last-child):after
{
ul.tag-list-long li:not(:last-child):after {
content: ", ";
white-space: pre-wrap;
}
ul.tag-list-long > li {
margin-top: 1px;
}
ul.preview-feature-list {
list-style: none;
margin:0;
@ -940,6 +950,9 @@ div.checkboxes > label > input {
.col-first, .col-second, .col-constructor-name {
overflow: auto;
}
.col-constructor-name, .method-summary .col-second {
text-indent: 0.5em hanging;
}
body:not(.class-declaration-page) .col-first a:link,
.col-summary-item-name a:link {
font-weight:bold;
@ -957,6 +970,12 @@ div.block {
font-size:var(--block-font-size);
font-family:var(--block-font-family);
line-height:var(--block-line-height);
display: block;
margin:0 10px 5px 0;
color:var(--block-text-color);
}
section.detail div.block {
margin-bottom: 14.4px;
}
.module-signature,
.package-signature,
@ -1006,11 +1025,6 @@ div.block {
color:var(--source-linenumber-color, green);
padding:0 30px 0 0;
}
.block {
display:block;
margin:0 10px 5px 0;
color:var(--block-text-color);
}
.deprecated-label, .description-from-type-label, .implementation-label, .member-name-link,
.package-hierarchy-label, .type-name-label, .type-name-link, .search-tag-link, .preview-label,
.restricted-label {
@ -1075,15 +1089,16 @@ input[type="text"] {
background-image:var(--glass-svg);
background-size:13px;
background-repeat:no-repeat;
background-position:3px 4px;
background-position:3px 5px;
background-color: var(--search-input-background-color);
color: var(--search-input-text-color);
border-color: var(--border-color);
border-style:solid;
border-color: var(--search-border-dark-color) var(--search-border-light-color) var(--search-border-light-color) var(--search-border-dark-color);
border-radius: 4px;
padding-left:20px;
padding-right: 18px;
font-size: var(--nav-font-size);
height: 19px;
height: 20px;
}
input#page-search-input {
width: calc(180px + 10vw);
@ -1585,8 +1600,7 @@ button.snippet-copy span {
table.borderless,
table.plain,
table.striped {
margin-top: 10px;
margin-bottom: 10px;
margin: 14px 0;
}
table.borderless > caption,
table.plain > caption,
@ -1780,6 +1794,9 @@ table.striped > tbody > tr > th {
main {
padding: 10px 12px;
}
main [id] {
scroll-margin-top: calc(var(--nav-height) + 10px);
}
body {
-webkit-text-size-adjust: none;
}

View File

@ -1277,16 +1277,22 @@ TEST_VM(os, map_unmap_memory) {
TEST_VM(os, map_memory_to_file_aligned) {
const char* letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const size_t size = strlen(letters) + 1;
const size_t content_size = strlen(letters) + 1;
const size_t granularity = os::vm_allocation_granularity();
const size_t alignments[] = { granularity, 2 * granularity, 4 * granularity, 16 * granularity, 1 * M };
int fd = os::open("map_memory_to_file.txt", O_RDWR | O_CREAT, 0666);
EXPECT_TRUE(fd > 0);
EXPECT_TRUE(os::write(fd, letters, size));
ASSERT_TRUE(os::write(fd, letters, content_size));
char* result = os::map_memory_to_file_aligned(os::vm_allocation_granularity(), os::vm_allocation_granularity(), fd, mtTest);
ASSERT_NOT_NULL(result);
EXPECT_EQ(strcmp(letters, result), 0);
os::unmap_memory(result, os::vm_allocation_granularity());
const size_t size = granularity;
for (size_t alignment : alignments) {
char* result = os::map_memory_to_file_aligned(size, alignment, fd, mtTest);
ASSERT_NOT_NULL(result) << "Mapping failed for alignment=" << alignment;
EXPECT_TRUE(is_aligned(result, alignment)) << "Failed to aligned to " << alignment;
EXPECT_EQ(strcmp(letters, result), 0) << "Text mismatch at alignment=" << alignment;
os::unmap_memory(result, size);
}
::close(fd);
}
@ -1297,3 +1303,36 @@ TEST_VM(os, dll_load_null_error_buf) {
void* lib = os::dll_load("NoSuchLib", nullptr, 0);
ASSERT_NULL(lib);
}
TEST_VM(os, reserve_memory_aligned_basic) {
const size_t granularity = os::vm_allocation_granularity();
const size_t alignments[] = { granularity, 2 * granularity, 4 * granularity, 16 * granularity };
for (size_t alignment : alignments) {
const size_t size = alignment;
char* result = os::reserve_memory_aligned(size, alignment, mtTest);
ASSERT_NE(result, (char*)nullptr) << "reserve_memory_aligned failed for alignment=" << alignment;
EXPECT_TRUE(is_aligned(result, alignment)) << "Result " << result << " not aligned to " << alignment;
ASSERT_TRUE(os::commit_memory(result, size, false));
memset(result, 0xCD, size);
EXPECT_EQ((unsigned char)result[0], 0xCD);
os::release_memory(result, size);
}
}
TEST_VM(os, reserve_memory_aligned_large) {
const size_t alignment = 1 * M;
const size_t size = alignment;
char* result = os::reserve_memory_aligned(size, alignment, mtTest);
ASSERT_NE(result, (char*)nullptr);
EXPECT_TRUE(is_aligned(result, alignment));
ASSERT_TRUE(os::commit_memory(result, size, false));
memset(result, 0xEF, size);
EXPECT_EQ((unsigned char)result[size - 1], 0xEF);
os::release_memory(result, size);
}

View File

@ -103,7 +103,6 @@ runtime/os/TestTracePageSizes.java#compiler-options 8267460 linux-aarch64
runtime/os/TestTracePageSizes.java#G1 8267460 linux-aarch64
runtime/os/TestTracePageSizes.java#Parallel 8267460 linux-aarch64
runtime/os/TestTracePageSizes.java#Serial 8267460 linux-aarch64
runtime/StackGuardPages/TestStackGuardPagesNative.java 8303612 linux-all
runtime/ErrorHandling/MachCodeFramesInErrorFile.java 8313315 linux-ppc64le
runtime/NMT/VirtualAllocCommitMerge.java 8309698 linux-s390x
runtime/Thread/TestAlwaysPreTouchStacks.java 8383372 macosx-aarch64
@ -139,6 +138,8 @@ serviceability/sa/ClhsdbThreadContext.java 8356704 windows-x64
serviceability/jvmti/stress/StackTrace/NotSuspended/GetStackTraceNotSuspendedStressTest.java 8315980 linux-all,windows-x64
serviceability/jvmti/GetModulesInfo/JvmtiGetAllModulesTest.java 8385679 generic-all
#############################################################################
# :hotspot_misc

View File

@ -64,7 +64,7 @@ public class TestPrintMethodData {
private static final Generator<Long> GEN_LONG = Generators.G.longs();
private static final int SIZE = 1024;
static void main(String[] args) throws Exception {
public static void main(String[] args) throws Exception {
long[] longs = new long[SIZE];
Generators.G.fill(GEN_LONG, longs);

View File

@ -56,17 +56,13 @@ static jmp_buf context;
static volatile int _last_si_code = -1;
static volatile int _failures = 0;
static volatile int _rec_count = 0; // Number of allocations to hit stack guard page
static volatile int _kp_rec_count = 0; // Kept record of rec_count, for retrying
static volatile int _previous_rec_count = 0; // Kept record of rec_count, for retrying
static int _peek_value = 0; // Used for accessing memory to cause SIGSEGV
pid_t gettid() {
return (pid_t) syscall(SYS_gettid);
}
static void handler(int sig, siginfo_t *si, void *unused) {
_last_si_code = si->si_code;
printf("Got SIGSEGV(%d) at address: 0x%lx\n",si->si_code, (long) si->si_addr);
longjmp(context, 1);
siglongjmp(context, 1);
}
static char* altstack = NULL;
@ -159,8 +155,16 @@ void *run_java_overflow (void *p) {
void do_overflow(){
volatile int *p = NULL;
if (_kp_rec_count == 0 || _rec_count < _kp_rec_count) {
for(;;) {
if (_previous_rec_count == 0) {
// We need to find the appropriate depth to probe into
for (;;) {
_rec_count++;
p = (int*)alloca(128);
_peek_value = p[0]; // Peek
}
} else {
while (_rec_count < _previous_rec_count) {
// This is our second round, we can do exactly 1 less allocation
_rec_count++;
p = (int*)alloca(128);
_peek_value = p[0]; // Peek
@ -168,19 +172,19 @@ void do_overflow(){
}
}
void *run_native_overflow(void *p) {
void *run_native_overflow(void *is_other_thread) {
// Test that stack guard page is correctly set for initial and non initial thread
// and correctly removed for the initial thread
volatile int res;
printf("run_native_overflow %ld\n", (long) gettid());
printf("run_native_overflow, %s", *(int *)is_other_thread ? "in other thread\n" : "in initial thread\n");
call_method_on_jvm("printAlive");
// Initialize statics used in do_overflow
_kp_rec_count = 0;
_previous_rec_count = 0;
_rec_count = 0;
set_signal_handler();
if (! setjmp(context)) {
if (! sigsetjmp(context, 1)) {
do_overflow();
}
@ -194,7 +198,7 @@ void *run_native_overflow(void *p) {
exit(7);
}
if (getpid() != gettid()) {
if (*(int *)is_other_thread == 1) {
// For non-initial thread we don't unmap the region but call os::uncommit_memory and keep PROT_NONE
// so if host has enough swap space we will get the same SEGV with code SEGV_ACCERR(2) trying
// to access it as if the guard page is present.
@ -204,11 +208,11 @@ void *run_native_overflow(void *p) {
}
// Limit depth of recursion for second run. It can't exceed one for first run.
_kp_rec_count = _rec_count;
_previous_rec_count = _rec_count;
_rec_count = 0;
set_signal_handler();
if (! setjmp(context)) {
if (!sigsetjmp(context, 1)) {
do_overflow();
}
@ -314,8 +318,8 @@ int main (int argc, const char** argv) {
if (strcmp(argv[1], "test_native_overflow_initial") == 0) {
printf("\nTesting NATIVE_OVERFLOW\n");
printf("Testing stack guard page behaviour for initial thread\n");
run_native_overflow(NULL);
int is_other_thread = 0;
run_native_overflow(&is_other_thread);
exit((_failures > 0) ? 1 : 0);
}
@ -324,11 +328,11 @@ int main (int argc, const char** argv) {
init_thread_or_die(&thr, &thread_attr);
printf("\nTesting NATIVE_OVERFLOW\n");
printf("Testing stack guard page behaviour for other thread\n");
pthread_create(&thr, &thread_attr, run_native_overflow, NULL);
int is_other_thread = 1;
pthread_create(&thr, &thread_attr, run_native_overflow, &is_other_thread);
pthread_join(thr, NULL);
exit((_failures > 0) ? 1 : 0);
// Other-thread test cannot increase _failure count
exit(0);
}
fprintf(stderr, "Test ERROR. Unknown parameter %s\n", ((argc > 1) ? argv[1] : "none"));

View File

@ -79,7 +79,10 @@ import java.util.concurrent.CountDownLatch;
import java.util.stream.Stream;
import java.util.stream.Collectors;
import jdk.test.lib.thread.VThreadRunner;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.Arguments;
@ -96,6 +99,12 @@ class KlassInit {
private static final CountDownLatch finishPutStatic = new CountDownLatch(1);
private static final CountDownLatch finishFailedInit = new CountDownLatch(1);
@BeforeAll
static void setup() {
// need >=2 carriers for testing pinning
VThreadRunner.ensureParallelism(2);
}
/**
* Test that threads blocked waiting for klass to be initialized
* on invokestatic bytecode release the carrier.

View File

@ -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
@ -26,6 +26,9 @@ import java.lang.reflect.Field;
import java.net.http.HttpClient;
import java.util.Objects;
import java.util.Set;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Map;
public final class HttpClientImplAccess {
@ -64,4 +67,29 @@ public final class HttpClientImplAccess {
openedConnections.setAccessible(true);
return (Set<?>) openedConnections.get(clientImpl);
}
/**
* Returns all connections in the client's HTTP/2 pool.
*/
public static Collection<?> getHttp2Connections(final HttpClient client) {
Objects.requireNonNull(client, "client");
final HttpClientImpl clientImpl = impl(client);
if (clientImpl == null) {
throw new IllegalStateException("Unsupported HttpClient implementation");
}
Http2ClientImpl client2 = clientImpl.client2();
Map<String, Http2Connection> connections = client2.getConnections();
return connections.values();
}
/**
* Returns the cached header encoding buffer for the given Http2Connection.
*/
public static ByteBuffer getCachedHeaderBuffer(final Object conn) {
// The argument to this method is of type Object and not
// Http2Connection because callers outside the module cannot reference
// the package-private Http2Connection class.
Objects.requireNonNull(conn, "conn");
return ((Http2Connection) conn).getCachedHeaderBuffer();
}
}

View File

@ -0,0 +1,139 @@
/*
* 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.
*/
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.nio.ByteBuffer;
import java.util.Collection;
import javax.net.ssl.SSLContext;
import static java.net.http.HttpClient.Version.HTTP_2;
import jdk.httpclient.test.lib.common.HttpServerAdapters;
import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestServer;
import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestExchange;
import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestHandler;
import jdk.internal.net.http.HttpClientImplAccess;
import jdk.test.lib.net.URIBuilder;
import jdk.test.lib.net.SimpleSSLContext;
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.*;
/*
* @test
* @bug 8383248
* @summary Verifies that Http2Connection.cachedHeaderBuffer is reused
* across multiple requests on the same connection.
* @library /test/lib /test/jdk/java/net/httpclient/lib
* /test/jdk/java/net/httpclient/access
* @build java.net.http/jdk.internal.net.http.HttpClientImplAccess
* jdk.httpclient.test.lib.common.HttpServerAdapters
* jdk.test.lib.net.SimpleSSLContext
* @run junit/othervm
* ${test.main.class}
*/
public class HeaderEncodingBufferReuseTest implements HttpServerAdapters {
static String httpUri;
static SSLContext sslContext;
static HttpTestServer testServer;
@BeforeAll
static void init() throws Exception {
sslContext = SimpleSSLContext.findSSLContext();
testServer = HttpTestServer.create(HTTP_2, sslContext);
testServer.addHandler(new OkHandler(), "/test");
testServer.start();
httpUri = URIBuilder.newBuilder()
.scheme("https")
.loopback()
.port(testServer.getAddress().getPort())
.path("/test")
.build()
.toString();
}
@AfterAll
static void teardown() {
testServer.stop();
}
@Test
void test() throws Exception {
try (HttpClient client = HttpClient.newBuilder()
.proxy(HttpClient.Builder.NO_PROXY)
.version(HttpClient.Version.HTTP_2)
.sslContext(sslContext)
.build()) {
// Send an initial request to allocate the header encoding buffer.
assertEquals(200, send(client, httpUri, 2).statusCode());
Collection<?> connections = HttpClientImplAccess.getHttp2Connections(client);
assertEquals(1, connections.size());
Object conn = connections.iterator().next();
ByteBuffer cached = HttpClientImplAccess.getCachedHeaderBuffer(conn);
assertNotNull(cached);
// Send another request and verify the same buffer is reused.
assertEquals(200, send(client, httpUri, 2).statusCode());
connections = HttpClientImplAccess.getHttp2Connections(client);
assertEquals(1, connections.size());
assertSame(conn, connections.iterator().next());
assertSame(cached, HttpClientImplAccess.getCachedHeaderBuffer(conn));
// Verify that the buffer is reused when headers span multiple frames.
assertEquals(200, send(client, httpUri, 300).statusCode());
connections = HttpClientImplAccess.getHttp2Connections(client);
assertEquals(1, connections.size());
assertSame(conn, connections.iterator().next());
assertSame(cached, HttpClientImplAccess.getCachedHeaderBuffer(conn));
}
}
static HttpResponse<Void> send(HttpClient client, String uri, int headerCount) throws Exception {
HttpRequest.Builder builder = HttpRequest.newBuilder(URI.create(uri))
.POST(BodyPublishers.ofString("test"));
for (int i = 0; i < headerCount; i++) {
builder.header("X-Header-" + i, "value-" + "x".repeat(50) + "-" + i);
}
return client.send(builder.build(), BodyHandlers.discarding());
}
static class OkHandler implements HttpTestHandler {
@Override
public void handle(HttpTestExchange exchange) throws IOException {
exchange.sendResponseHeaders(200, 0);
exchange.getResponseBody().close();
}
}
}

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8041488 8316974 8318569 8306116 8385736
* @bug 8041488 8316974 8318569 8306116 8385736 8385834
* @summary Tests for ListFormat class
* @run junit TestListFormat
*/
@ -210,6 +210,10 @@ public class TestListFormat {
arguments(CUSTOM_PATTERNS_MINIMAL, SAMPLE2),
arguments(CUSTOM_PATTERNS_MINIMAL, SAMPLE3),
arguments(CUSTOM_PATTERNS_MINIMAL, SAMPLE4),
arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE1),
arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE2),
arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE3),
arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE4),
};
}
@ -237,13 +241,37 @@ public class TestListFormat {
};
}
private static Arguments[] getInstance_1Arg_InvalidLongPattern() {
private static final String ZERO_REPEAT = "{0}".repeat(100_000);
private static Arguments[] getInstance_1Arg_InvalidPlaceholder() {
return new Arguments[] {
arguments(0, "start pattern is incorrect:"),
arguments(1, "middle pattern is incorrect:"),
arguments(2, "end pattern is incorrect:"),
arguments(3, "pattern for two is incorrect:"),
arguments(4, "pattern for three is incorrect:"),
// Duplicate placeholders
arguments(0, "{0} {0} {1}", "start pattern is incorrect: {0} {0} {1}"),
arguments(0, "{0} {1} {1}", "start pattern is incorrect: {0} {1} {1}"),
arguments(0, "{0} {1} {2}", "start pattern is incorrect: {0} {1} {2}"),
arguments(1, "{0} {0} {1}", "middle pattern is incorrect: {0} {0} {1}"),
arguments(1, "{0} {1} {1}", "middle pattern is incorrect: {0} {1} {1}"),
arguments(1, "{0} {1} {2}", "middle pattern is incorrect: {0} {1} {2}"),
arguments(2, "{0} {0} {1}", "end pattern is incorrect: {0} {0} {1}"),
arguments(2, "{0} {1} {1}", "end pattern is incorrect: {0} {1} {1}"),
arguments(2, "{0} {1} {2}", "end pattern is incorrect: {0} {1} {2}"),
arguments(3, "{0} {0} {1}", "pattern for two is incorrect: {0} {0} {1}"),
arguments(3, "{0} {1} {1}", "pattern for two is incorrect: {0} {1} {1}"),
arguments(3, "{0} {1} {2}", "pattern for two is incorrect: {0} {1} {2}"),
arguments(4, "{0} {2} {1}", "pattern for three is incorrect: {0} {2} {1}"),
arguments(4, "{0} {0} {1} {2}", "pattern for three is incorrect: {0} {0} {1} {2}"),
arguments(4, "{0} {1} {1} {2}", "pattern for three is incorrect: {0} {1} {1} {2}"),
arguments(4, "{0} {1} {2} {2}", "pattern for three is incorrect: {0} {1} {2} {2}"),
arguments(4, ZERO_REPEAT + " {1} {2}", "pattern for three is incorrect: " + ZERO_REPEAT + " {1} {2}"),
// invalid placeholders
arguments(0, "{0} {1} {", "start pattern is incorrect: {0} {1} {"),
arguments(0, "{0} {1} }", "start pattern is incorrect: {0} {1} }"),
arguments(3, "{0} {1} {3}", "pattern for two is incorrect: {0} {1} {3}"),
arguments(4, "{3} {0} {1}", "pattern for three is incorrect: {3} {0} {1}"),
arguments(4, "{333} {0} {1}", "pattern for three is incorrect: {333} {0} {1}"),
arguments(4, "{0} {1} {abc}", "pattern for three is incorrect: {0} {1} {abc}"),
arguments(4, "{0} {1} {2, number}", "pattern for three is incorrect: {0} {1} {2, number}"),
arguments(4, "{0} {1} {2} {3}", "pattern for three is incorrect: {0} {1} {2} {3}"),
};
}
@ -264,7 +292,7 @@ public class TestListFormat {
@ParameterizedTest
@MethodSource
void getInstance_1Arg_InvalidLongPattern(int index, String expected) {
void getInstance_1Arg_InvalidPlaceholder(int index, String invalidPattern, String expected) {
var patterns = new String[]{
"{0}, {1}",
"{0}, {1}",
@ -272,13 +300,12 @@ public class TestListFormat {
"{0} and {1}",
"{0} {1} {2}"
};
patterns[index] = "{0}".repeat(100_000);
patterns[index] = invalidPattern;
// Ensures validation of invalid long patterns completes without timing out
var msg = assertThrows(IllegalArgumentException.class,
() -> ListFormat.getInstance(patterns))
.getMessage();
assertEquals(expected, msg.substring(0, Math.min(msg.length(), expected.length())));
assertEquals(expected, msg);
}
@ParameterizedTest

View File

@ -663,6 +663,23 @@ public class ForkJoinPoolTest extends JSR166TestCase {
}
}
public void testCallerInterruptedDuringSubmit() throws InterruptedException, ExecutionException {
final Thread submitter = Thread.currentThread();
final ExecutorService p = new ForkJoinPool(1);
try (PoolCleaner cleaner = cleaner(p)) {
for (int i = 0; i < 512; ++i) { // Enough repetitions such that any race condition is bound to materialize
try {
p.submit(submitter::interrupt).get();
// If we don't get an InterruptedException, then the current thread should be interrupted
assertTrue(Thread.interrupted());
} catch (InterruptedException e) {
// If we do get an InterruptedException, then the current thread should not be interrupted
assertTrue(!Thread.interrupted());
}
}
}
}
/**
* get of submit(callable) throws ExecutionException if callable
* throws exception

View File

@ -0,0 +1,145 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please 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
* @key headful
* @summary Checkbox Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main CheckboxTest
*/
import java.awt.AWTException;
import java.awt.Checkbox;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
public class CheckboxTest {
private static Checkbox checkbox;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "Checkbox Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, Checkbox";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
CheckboxTest checkboxTest = new CheckboxTest();
EventQueue.invokeAndWait(checkboxTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(checkboxTest::test);
} finally {
checkboxTest.dispose();
}
}
private void createGUI() {
frame = new Frame("Checkbox Test");
checkbox = new Checkbox("This is a checkbox", true);
checkbox.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
checkbox.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(checkbox);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyCheckboxAccessibility(
checkbox,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new CheckboxStateTester(
checkbox,
checkbox.getAccessibleContext().getAccessibleStateSet()
).testAll();
checkbox.setState(!checkbox.getState());
AccessibleTestUtils.verifyCheckboxAccessibility(
checkbox,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new CheckboxStateTester(
checkbox,
checkbox.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
private static final class CheckboxStateTester
extends AccessibleStateSetTester {
private final Checkbox checkbox;
private final AccessibleStateSet set;
private CheckboxStateTester(Checkbox checkbox, AccessibleStateSet set) {
super(checkbox, set);
this.checkbox = checkbox;
this.set = set;
}
@Override
public void testChecked() {
if (set.contains(AccessibleState.CHECKED)) {
if (!checkbox.getState()) {
throw new RuntimeException(
"AccessibleStateSet contains CHECKED but " +
"this component is not checked");
}
} else {
if (checkbox.getState()) {
throw new RuntimeException(
"AccessibleStateSet does not contain CHECKED " +
"but this component is checked");
}
}
}
}
}

View File

@ -0,0 +1,158 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please 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
* @key headful
* @summary Frame Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main FrameTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
public class FrameTest {
private static Frame frame;
private static final String ACCESSIBLE_NAME = "Frame Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, Frame";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
FrameTest frameTest = new FrameTest();
EventQueue.invokeAndWait(frameTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(frameTest::test);
} finally {
frameTest.dispose();
}
}
private void createGUI() {
frame = new Frame("Frame Test");
frame.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
frame.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyFrameAccessibility(
frame,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new FrameStateTester(
frame,
frame.getAccessibleContext().getAccessibleStateSet()
).testAll();
frame.setResizable(false);
AccessibleTestUtils.verifyFrameAccessibility(
frame,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new FrameStateTester(
frame,
frame.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
private static final class FrameStateTester
extends AccessibleStateSetTester {
private final Frame component;
private final AccessibleStateSet set;
private FrameStateTester(Frame frame, AccessibleStateSet set) {
super(frame, set);
this.component = frame;
this.set = set;
}
@Override
public void testResizable() {
if (set.contains(AccessibleState.RESIZABLE)) {
if (!component.isResizable()) {
throw new RuntimeException(
"AccessibleStateSet contains RESIZABLE but " +
"this component is not resizable");
}
} else {
if (component.isResizable()) {
throw new RuntimeException(
"AccessibleStateSet does not contain RESIZABLE " +
"but this component is resizable");
}
}
}
@Override
public void testActive() {
if (set.contains(AccessibleState.ACTIVE)) {
if (component.getFocusOwner() == null) {
throw new RuntimeException(
"AccessibleStateSet contains ACTIVE but " +
"this component is not active");
}
} else {
if (component.getFocusOwner() != null) {
throw new RuntimeException(
"AccessibleStateSet does not contain ACTIVE but " +
"this component is active");
}
}
}
}
}

View File

@ -0,0 +1,100 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please 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
* @key headful
* @summary Label Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main LabelTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
public class LabelTest {
private static Label label;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "Label Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, Label";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
LabelTest labelTest = new LabelTest();
EventQueue.invokeAndWait(labelTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(labelTest::test);
} finally {
labelTest.dispose();
}
}
private void createGUI() {
frame = new Frame("Label Test");
label = new Label("This is a label");
label.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
label.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(label);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyLabelAccessibility(
label,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new AccessibleStateSetTester(
label,
label.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
}

View File

@ -0,0 +1,157 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please 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
* @key headful
* @summary List Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main ListTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.List;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
public class ListTest {
private static List list;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "List Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, List";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
ListTest listTest = new ListTest();
EventQueue.invokeAndWait(listTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(listTest::test);
} finally {
listTest.dispose();
}
}
private void createGUI() {
frame = new Frame("List Test");
list = new List();
list.add("Mercury");
list.add("Venus");
list.add("Earth");
list.add("JavaSoft");
list.add("Mars");
list.add("Jupiter");
list.add("Saturn");
list.add("Uranus");
list.add("Neptune");
list.add("Pluto");
list.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
list.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(list);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyListAccessibility(
list,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new ListStateTester(
list,
list.getAccessibleContext().getAccessibleStateSet()
).testAll();
list.setMultipleMode(!list.isMultipleMode());
AccessibleTestUtils.verifyListAccessibility(
list,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new ListStateTester(
list,
list.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
private static final class ListStateTester
extends AccessibleStateSetTester {
private final List list;
private final AccessibleStateSet set;
private ListStateTester(List list, AccessibleStateSet set) {
super(list, set);
this.list = list;
this.set = set;
}
@Override
public void testMultiSelectable() {
if (set.contains(AccessibleState.MULTISELECTABLE)) {
if (!list.isMultipleMode()) {
throw new RuntimeException(
"AccessibleStateSet contains MULTISELECTABLE " +
"but this component is not multiselectable");
}
} else {
if (list.isMultipleMode()) {
throw new RuntimeException(
"AccessibleStateSet does not contain " +
"MULTISELECTABLE but this component is " +
"multiselectable");
}
}
}
}
}

View File

@ -0,0 +1,102 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please 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
* @key headful
* @summary MenuBar Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleMenuComponentTester
* @run main MenuBarTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
public class MenuBarTest {
private static MenuBar menuBar;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "Menu Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, MenuBar";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
MenuBarTest menuBarTest = new MenuBarTest();
EventQueue.invokeAndWait(menuBarTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(menuBarTest::test);
} finally {
menuBarTest.dispose();
}
}
private void createGUI() {
frame = new Frame("MenuBar Test");
menuBar = new MenuBar();
Menu menu = new Menu("Menu 1");
menu.add(new MenuItem("One"));
menu.add(new MenuItem("Two"));
menuBar.add(menu);
menuBar.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
menuBar.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.setMenuBar(menuBar);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyMenuBarAccessibility(
menuBar,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
}
}

View File

@ -0,0 +1,103 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please 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
* @key headful
* @summary MenuItem Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleMenuComponentTester
* @run main MenuItemTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
public class MenuItemTest {
private static MenuItem menuItem;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "MenuItem Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, MenuItem";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
MenuItemTest menuItemTest = new MenuItemTest();
EventQueue.invokeAndWait(menuItemTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(menuItemTest::test);
} finally {
menuItemTest.dispose();
}
}
private void createGUI() {
frame = new Frame("MenuItem Test");
MenuBar menuBar = new MenuBar();
Menu menu = new Menu("Menu");
menuItem = new MenuItem("This here's a MenuItem");
menu.add(menuItem);
menuBar.add(menu);
menuItem.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
menuItem.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.setMenuBar(menuBar);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyMenuItemAccessibility(
menuItem,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
}
}

View File

@ -0,0 +1,99 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please 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
* @key headful
* @summary Menu Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleMenuComponentTester
* @run main MenuTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
public class MenuTest {
private static Menu menu;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "Menu Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, Menu";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
MenuTest menuTest = new MenuTest();
EventQueue.invokeAndWait(menuTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(menuTest::test);
} finally {
menuTest.dispose();
}
}
private void createGUI() {
frame = new Frame("Menu Test");
MenuBar menuBar = new MenuBar();
menu = new Menu("File");
menuBar.add(menu);
menu.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
menu.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.setMenuBar(menuBar);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyMenuAccessibility(
menu,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
}
}

View File

@ -0,0 +1,105 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please 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
* @key headful
* @summary Panel Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main PanelTest
*/
import java.awt.AWTException;
import java.awt.Button;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
public class PanelTest {
private static Panel panel;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "Panel Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, Panel";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
PanelTest panelTest = new PanelTest();
EventQueue.invokeAndWait(panelTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(panelTest::test);
} finally {
panelTest.dispose();
}
}
private void createGUI() {
frame = new Frame("Panel Test");
panel = new Panel();
for (int i = 0; i < 5; i++) {
panel.add(new Button("Button #" + i));
}
panel.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
panel.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyPanelAccessibility(
panel,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new AccessibleStateSetTester(
panel,
panel.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
}

View File

@ -0,0 +1,100 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please 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
* @key headful
* @summary PopupMenu Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleMenuComponentTester
* @run main PopupMenuTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.PopupMenu;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
public class PopupMenuTest {
private static PopupMenu popupMenu;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "PopupMenu Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, PopupMenu";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
PopupMenuTest popupMenuTest = new PopupMenuTest();
EventQueue.invokeAndWait(popupMenuTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(popupMenuTest::test);
} finally {
popupMenuTest.dispose();
}
}
private void createGUI() {
frame = new Frame("PopupMenu Test");
popupMenu = new PopupMenu("PopupMenu");
popupMenu.add("Sleepy");
popupMenu.add("Happy");
popupMenu.add("Grumpy");
popupMenu.add("Dopey");
popupMenu.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
popupMenu.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(popupMenu);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyPopupMenuAccessibility(
popupMenu,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
}
}

View File

@ -0,0 +1,104 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please 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
* @key headful
* @summary ScrollPane Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main ScrollPaneTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Robot;
import java.awt.ScrollPane;
import java.lang.reflect.InvocationTargetException;
public class ScrollPaneTest {
private static ScrollPane scrollPane;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "ScrollPane Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, ScrollPane";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
ScrollPaneTest scrollPaneTest = new ScrollPaneTest();
EventQueue.invokeAndWait(scrollPaneTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(scrollPaneTest::test);
} finally {
scrollPaneTest.dispose();
}
}
private void createGUI() {
frame = new Frame("ScrollPane Test");
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
scrollPane = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);
scrollPane.setSize(frame.getSize().width, frame.getSize().height);
scrollPane.add(new Label("This is a label with quite a bit of text."));
scrollPane.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
scrollPane.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(scrollPane);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyScrollPaneAccessibility(
scrollPane,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new AccessibleStateSetTester(
scrollPane,
scrollPane.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
}

View File

@ -0,0 +1,155 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please 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
* @key headful
* @summary TextArea Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main TextAreaTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Robot;
import java.awt.TextArea;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.InvocationTargetException;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
public class TextAreaTest {
private static TextArea textArea;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "TextArea Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, TextArea";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
TextAreaTest textAreaTest = new TextAreaTest();
EventQueue.invokeAndWait(textAreaTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(textAreaTest::test);
} finally {
textAreaTest.dispose();
}
}
private void createGUI() {
frame = new Frame("TextAreaTest");
String TEXT_CONTENT = """
1. Test TextArea javax.accessibility methods
2. Test TextArea javax.accessibility setAccessibleName
3. Test TextArea javax.accessibility setAccessibleDescription
4. Test TextArea javax.accessibility setAccessibleStateSet
""";
textArea = new TextArea(TEXT_CONTENT, 24, 80);
textArea.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
textArea.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(textArea);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyTextAreaAccessibility(
textArea,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new TextStateTester(
textArea,
textArea.getAccessibleContext().getAccessibleStateSet()
).testAll();
textArea.setEditable(false);
AccessibleTestUtils.verifyTextAreaAccessibility(
textArea,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new TextStateTester(
textArea,
textArea.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
private static final class TextStateTester
extends AccessibleStateSetTester {
private final TextArea textArea;
private final AccessibleStateSet stateSet;
private TextStateTester(TextArea textArea,
AccessibleStateSet stateSet) {
super(textArea, stateSet);
this.textArea = textArea;
this.stateSet = stateSet;
}
@Override
public void testEditable() {
if (stateSet.contains(AccessibleState.EDITABLE)) {
if (!textArea.isEditable()) {
throw new RuntimeException(
"AccessibleStateSet contains EDITABLE but " +
"this component is not editable");
}
} else {
if (textArea.isEditable()) {
throw new RuntimeException(
"AccessibleStateSet does not contain EDITABLE " +
"but this component is editable");
}
}
}
}
}

View File

@ -0,0 +1,148 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please 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
* @key headful
* @summary TextField Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main TextFieldTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Robot;
import java.awt.TextField;
import java.lang.reflect.InvocationTargetException;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
public class TextFieldTest {
private static TextField textField;
private static Frame frame;
private static final String ACCESSIBLE_NAME = "TextField Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, TextField";
private static final String TEXT =
"I love Cheesy Poofs you love Cheesy Poofs if we didn't " +
"eat Cheesy Poofs we'd be lame!";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
TextFieldTest textFieldTest = new TextFieldTest();
EventQueue.invokeAndWait(textFieldTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(textFieldTest::test);
} finally {
textFieldTest.dispose();
}
}
private void createGUI() {
frame = new Frame("TextField Test");
textField = new TextField(TEXT, 80);
textField.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
textField.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
frame.add(textField);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyTextFieldAccessibility(
textField,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new TextStateTester(
textField,
textField.getAccessibleContext().getAccessibleStateSet()
).testAll();
textField.setEditable(false);
AccessibleTestUtils.verifyTextFieldAccessibility(
textField,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new TextStateTester(
textField,
textField.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
private static final class TextStateTester
extends AccessibleStateSetTester {
private final TextField textField;
private final AccessibleStateSet set;
private TextStateTester(TextField textField, AccessibleStateSet set) {
super(textField, set);
this.textField = textField;
this.set = set;
}
@Override
public void testEditable() {
if (set.contains(AccessibleState.EDITABLE)) {
if (!textField.isEditable()) {
throw new RuntimeException(
"AccessibleStateSet contains EDITABLE but " +
"this component is not editable");
}
} else {
if (textField.isEditable()) {
throw new RuntimeException(
"AccessibleStateSet does not contain EDITABLE " +
"but this component is editable");
}
}
}
}
}

View File

@ -0,0 +1,129 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please 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
* @key headful
* @summary Window Accessibility test.
* @library ../../swing/regtesthelpers/accessibility/
* @build AccessibleTestUtils AccessibleComponentTester AccessibleStateSetTester
* @run main WindowTest
*/
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Robot;
import java.awt.Window;
import java.lang.reflect.InvocationTargetException;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
public class WindowTest {
private static Window window;
private static final String ACCESSIBLE_NAME = "Window Test";
private static final String ACCESSIBLE_DESCRIPTION =
"Regression Test: javax.accessibility, Window";
public static void main(String[] args) throws InterruptedException,
InvocationTargetException, AWTException {
WindowTest windowTest = new WindowTest();
EventQueue.invokeAndWait(windowTest::createGUI);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(5000);
try {
EventQueue.invokeAndWait(windowTest::test);
} finally {
windowTest.dispose();
}
}
private void createGUI() {
window = new Window(new Frame("Frame"));
window.setSize(300, 300);
window.setLocationRelativeTo(null);
window.getAccessibleContext().setAccessibleName(ACCESSIBLE_NAME);
window.getAccessibleContext().setAccessibleDescription(
ACCESSIBLE_DESCRIPTION);
window.setVisible(true);
}
private void dispose() throws InterruptedException,
InvocationTargetException {
EventQueue.invokeAndWait(() -> {
if (window != null) {
window.dispose();
}
});
}
private void test() {
AccessibleTestUtils.verifyWindowAccessibility(
window,
ACCESSIBLE_NAME,
ACCESSIBLE_DESCRIPTION
);
new WindowStateTester(
window,
window.getAccessibleContext().getAccessibleStateSet()
).testAll();
}
private static final class WindowStateTester
extends AccessibleStateSetTester {
private final Window window;
private final AccessibleStateSet set;
private WindowStateTester(Window window, AccessibleStateSet set) {
super(window, set);
this.window = window;
this.set = set;
}
@Override
public void testActive() {
if (set.contains(AccessibleState.ACTIVE)) {
if (window.getFocusOwner() == null) {
throw new RuntimeException(
"AccessibleStateSet contains ACTIVE but " +
"this component is not active");
}
} else {
if (window.getFocusOwner() != null) {
throw new RuntimeException(
"AccessibleStateSet does not contain ACTIVE " +
"but this component is active");
}
}
}
}
}

View File

@ -0,0 +1,114 @@
/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please 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.Font;
import java.awt.MenuComponent;
import javax.accessibility.AccessibleComponent;
public class AccessibleMenuComponentTester {
private final AccessibleComponent acomp;
private final MenuComponent comp;
public AccessibleMenuComponentTester(MenuComponent menuComponent,
AccessibleComponent ac) {
if (menuComponent == null) {
throw new RuntimeException("MenuComponent should not be null");
}
if (ac == null) {
throw new RuntimeException("AccessibleComponent should not be null");
}
this.comp = menuComponent;
this.acomp = ac;
}
// The only method supported by MenuComponents is getFont(). Everything
// else should return null.
public void test() {
testGetBackground();
testGetBounds();
testGetCursor();
testGetFont();
testGetForeground();
testGetLocation();
testGetLocationOnScreen();
testGetSize();
testIsEnabled();
testIsFocusTraversable();
testIsShowing();
testIsVisible();
}
public void testGetBackground() {
}
public void testGetBounds() {
}
public void testGetCursor() {
}
public void testGetFont() {
Font accessibleFont = acomp.getFont();
Font componentFont = comp.getFont();
if (componentFont == null) {
if (accessibleFont != null) {
throw new RuntimeException(
"MenuComponent.getFont returned null but " +
"AccessibleComponent.getFont did not");
}
} else if (!componentFont.equals(accessibleFont)) {
throw new RuntimeException(
"AccessibleComponent.getFont does not match " +
"MenuComponent.getFont");
}
}
public void testGetForeground() {
}
public void testGetLocation() {
}
public void testGetLocationOnScreen() {
}
public void testGetSize() {
}
public void testIsEnabled() {
}
public void testIsFocusTraversable() {
}
public void testIsShowing() {
}
public void testIsVisible() {
}
}

View File

@ -22,17 +22,33 @@
*/
import java.awt.Button;
import java.awt.Checkbox;
import java.awt.Choice;
import java.awt.Component;
import java.awt.Frame;
import java.awt.Label;
import java.awt.List;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuComponent;
import java.awt.MenuItem;
import java.awt.Panel;
import java.awt.PopupMenu;
import java.awt.Scrollbar;
import java.awt.ScrollPane;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.Window;
import java.util.Locale;
import java.util.Objects;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleAction;
import javax.accessibility.AccessibleComponent;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleSelection;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleText;
import javax.accessibility.AccessibleValue;
@ -51,32 +67,22 @@ public final class AccessibleTestUtils {
boolean expectSelection,
boolean expectText,
boolean expectValue) {
Objects.requireNonNull(context, "AccessibleContext must not be null");
assertExpectedString(
"getAccessibleName",
expectedName,
context.getAccessibleName()
);
assertExpectedString("getAccessibleName",
expectedName, context.getAccessibleName());
assertExpectedString("getAccessibleDescription",
expectedDescription, context.getAccessibleDescription());
assertExpectedString(
"getAccessibleDescription",
expectedDescription,
context.getAccessibleDescription()
);
AccessibleRole actualRole = context.getAccessibleRole();
if (actualRole == null) {
throw new RuntimeException("getAccessibleRole returned null");
}
if (expectedRole != null) {
AccessibleRole actualRole = context.getAccessibleRole();
if (actualRole == null) {
throw new RuntimeException("getAccessibleRole returned null");
}
if (!expectedRole.equals(actualRole)) {
throw new RuntimeException(String.format(
"getAccessibleRole returned [%s]; expected [%s]",
actualRole, expectedRole
));
}
if (!expectedRole.equals(actualRole)) {
throw new RuntimeException(
"getAccessibleRole returned [" + actualRole +
"]; expected [" + expectedRole + "]");
}
AccessibleStateSet stateSet = context.getAccessibleStateSet();
@ -84,10 +90,14 @@ public final class AccessibleTestUtils {
throw new RuntimeException("getAccessibleStateSet returned null");
}
assertPresence("getAccessibleAction", expectAction, context.getAccessibleAction());
assertPresence("getAccessibleSelection", expectSelection, context.getAccessibleSelection());
assertPresence("getAccessibleText", expectText, context.getAccessibleText());
assertPresence("getAccessibleValue", expectValue, context.getAccessibleValue());
assertPresence("getAccessibleAction",
expectAction, context.getAccessibleAction());
assertPresence("getAccessibleSelection",
expectSelection, context.getAccessibleSelection());
assertPresence("getAccessibleText",
expectText, context.getAccessibleText());
assertPresence("getAccessibleValue",
expectValue, context.getAccessibleValue());
}
public static void verifyAWTComponentAccessibility(
@ -99,10 +109,13 @@ public final class AccessibleTestUtils {
boolean expectSelection,
boolean expectText,
boolean expectValue) {
Objects.requireNonNull(component, "Component under test must not be null");
Objects.requireNonNull(component, "Component must not be null");
AccessibleContext context = component.getAccessibleContext();
if (context == null) {
throw new RuntimeException("getAccessibleContext returned null");
}
verifyAccessibleContextCommon(
context,
expectedName,
@ -111,12 +124,12 @@ public final class AccessibleTestUtils {
expectAction,
expectSelection,
expectText,
expectValue
);
expectValue);
assertLocaleMatches(component, context);
AccessibleComponent accessibleComponent = context.getAccessibleComponent();
AccessibleComponent accessibleComponent =
context.getAccessibleComponent();
if (accessibleComponent == null) {
throw new RuntimeException("getAccessibleComponent returned null");
}
@ -124,101 +137,10 @@ public final class AccessibleTestUtils {
new AccessibleComponentTester(component, accessibleComponent).test();
}
public static void verifyChoiceAccessibility(
Choice choice,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(choice, "Choice must not be null");
verifyAWTComponentAccessibility(
choice,
expectedName,
expectedDescription,
AccessibleRole.COMBO_BOX,
true,
false,
false,
false
);
AccessibleContext context = choice.getAccessibleContext();
AccessibleAction action = context.getAccessibleAction();
if (action == null) {
throw new RuntimeException("getAccessibleAction should not return null for Choice");
}
AccessibleValue value = context.getAccessibleValue();
if (value != null) {
throw new RuntimeException("getAccessibleValue should return null for Choice");
}
}
public static void verifyScrollbarAccessibility(
Scrollbar scrollbar,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(scrollbar, "Scrollbar must not be null");
verifyAWTComponentAccessibility(
scrollbar,
expectedName,
expectedDescription,
AccessibleRole.SCROLL_BAR,
false,
false,
false,
true
);
AccessibleValue value = scrollbar.getAccessibleContext().getAccessibleValue();
if (value == null) {
throw new RuntimeException("getAccessibleValue should not return null for Scrollbar");
}
assertIntValueEquals(
"getCurrentAccessibleValue",
scrollbar.getValue(),
value.getCurrentAccessibleValue()
);
assertIntValueEquals(
"getMinimumAccessibleValue",
scrollbar.getMinimum(),
value.getMinimumAccessibleValue()
);
assertIntValueEquals(
"getMaximumAccessibleValue",
scrollbar.getMaximum(),
value.getMaximumAccessibleValue()
);
if (!value.setCurrentAccessibleValue(Integer.valueOf(5))) {
throw new RuntimeException("setCurrentAccessibleValue(5) returned false for Scrollbar");
}
assertIntValueEquals(
"getCurrentAccessibleValue after setCurrentAccessibleValue(5)",
5,
value.getCurrentAccessibleValue()
);
if (scrollbar.getValue() != 5) {
throw new RuntimeException(
"setCurrentAccessibleValue(5) did not update Scrollbar.getValue(); actual value: "
+ scrollbar.getValue()
);
}
}
public static void verifyButtonAccessibility(
Button button,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(button, "Button must not be null");
verifyAWTComponentAccessibility(
@ -229,106 +151,576 @@ public final class AccessibleTestUtils {
true,
false,
false,
true
);
true);
AccessibleContext context = button.getAccessibleContext();
verifyClickAction(context, "Button");
verifyZeroAccessibleValue(context, "Button");
}
public static void verifyCheckboxAccessibility(
Checkbox checkbox,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(checkbox, "Checkbox must not be null");
verifyAWTComponentAccessibility(
checkbox,
expectedName,
expectedDescription,
AccessibleRole.CHECK_BOX,
true,
false,
false,
true);
}
public static void verifyChoiceAccessibility(
Choice choice,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(choice, "Choice must not be null");
verifyAWTComponentAccessibility(
choice,
expectedName,
expectedDescription,
AccessibleRole.COMBO_BOX,
true,
false,
false,
false);
}
public static void verifyFrameAccessibility(
Frame frame,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(frame, "Frame must not be null");
verifyAWTComponentAccessibility(
frame,
expectedName,
expectedDescription,
AccessibleRole.FRAME,
false,
false,
false,
false);
}
public static void verifyLabelAccessibility(
Label label,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(label, "Label must not be null");
verifyAWTComponentAccessibility(
label,
expectedName,
expectedDescription,
AccessibleRole.LABEL,
false,
false,
false,
false);
}
public static void verifyListAccessibility(
List list,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(list, "List must not be null");
verifyAWTComponentAccessibility(
list,
expectedName,
expectedDescription,
AccessibleRole.LIST,
false,
true,
false,
false);
verifyListChildren(list);
}
public static void verifyPanelAccessibility(
Panel panel,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(panel, "Panel must not be null");
verifyAWTComponentAccessibility(
panel,
expectedName,
expectedDescription,
AccessibleRole.PANEL,
false,
false,
false,
false);
verifyContainerChildren(panel, "Panel");
}
public static void verifyScrollbarAccessibility(
Scrollbar scrollbar,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(scrollbar, "Scrollbar must not be null");
verifyAWTComponentAccessibility(
scrollbar,
expectedName,
expectedDescription,
AccessibleRole.SCROLL_BAR,
false,
false,
false,
true);
AccessibleValue value =
scrollbar.getAccessibleContext().getAccessibleValue();
assertIntValueEquals(
"getCurrentAccessibleValue",
scrollbar.getValue(),
value.getCurrentAccessibleValue());
assertIntValueEquals(
"getMinimumAccessibleValue",
scrollbar.getMinimum(),
value.getMinimumAccessibleValue());
assertIntValueEquals(
"getMaximumAccessibleValue",
scrollbar.getMaximum(),
value.getMaximumAccessibleValue());
if (!value.setCurrentAccessibleValue(Integer.valueOf(5))) {
throw new RuntimeException(
"setCurrentAccessibleValue should not return false " +
"for Scrollbar");
}
assertIntValueEquals(
"getCurrentAccessibleValue after setCurrentAccessibleValue(5)",
5,
value.getCurrentAccessibleValue());
if (scrollbar.getValue() != 5) {
throw new RuntimeException(
"setCurrentAccessibleValue should change the Scrollbar " +
"value");
}
}
public static void verifyScrollPaneAccessibility(
ScrollPane scrollPane,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(scrollPane, "ScrollPane must not be null");
verifyAWTComponentAccessibility(
scrollPane,
expectedName,
expectedDescription,
AccessibleRole.SCROLL_PANE,
false,
false,
false,
false);
}
public static void verifyTextAreaAccessibility(
TextArea textArea,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(textArea, "TextArea must not be null");
verifyAWTComponentAccessibility(
textArea,
expectedName,
expectedDescription,
AccessibleRole.TEXT,
false,
false,
true,
false);
}
public static void verifyTextFieldAccessibility(
TextField textField,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(textField, "TextField must not be null");
verifyAWTComponentAccessibility(
textField,
expectedName,
expectedDescription,
AccessibleRole.TEXT,
false,
false,
true,
false);
}
public static void verifyWindowAccessibility(
Window window,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(window, "Window must not be null");
verifyAWTComponentAccessibility(
window,
expectedName,
expectedDescription,
AccessibleRole.WINDOW,
false,
false,
false,
false);
}
public static void verifyMenuAccessibility(
Menu menu,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(menu, "Menu must not be null");
verifyMenuComponentAccessibility(
menu,
expectedName,
expectedDescription,
AccessibleRole.MENU,
true,
true,
false,
true,
"Menu");
AccessibleContext context = menu.getAccessibleContext();
verifyClickAction(context, "Menu");
verifyZeroAccessibleValue(context, "Menu");
}
public static void verifyMenuBarAccessibility(
MenuBar menuBar,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(menuBar, "MenuBar must not be null");
verifyMenuComponentAccessibility(
menuBar,
expectedName,
expectedDescription,
AccessibleRole.MENU_BAR,
false,
true,
false,
false,
"MenuBar");
}
public static void verifyMenuItemAccessibility(
MenuItem menuItem,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(menuItem, "MenuItem must not be null");
verifyMenuComponentAccessibility(
menuItem,
expectedName,
expectedDescription,
AccessibleRole.MENU_ITEM,
true,
true,
false,
true,
"MenuItem");
AccessibleContext context = menuItem.getAccessibleContext();
verifyClickAction(context, "MenuItem");
verifyZeroAccessibleValue(context, "MenuItem");
}
public static void verifyPopupMenuAccessibility(
PopupMenu popupMenu,
String expectedName,
String expectedDescription) {
Objects.requireNonNull(popupMenu, "PopupMenu must not be null");
verifyMenuComponentAccessibility(
popupMenu,
expectedName,
expectedDescription,
AccessibleRole.POPUP_MENU,
true,
true,
false,
true,
"PopupMenu");
AccessibleContext context = popupMenu.getAccessibleContext();
verifyClickAction(context, "PopupMenu");
verifyZeroAccessibleValue(context, "PopupMenu");
}
private static void verifyMenuComponentAccessibility(
MenuComponent menuComponent,
String expectedName,
String expectedDescription,
AccessibleRole expectedRole,
boolean expectAction,
boolean expectSelection,
boolean expectText,
boolean expectValue,
String componentName) {
Objects.requireNonNull(menuComponent,
componentName + " must not be null");
AccessibleContext context = menuComponent.getAccessibleContext();
if (context == null) {
throw new RuntimeException("getAccessibleContext returned null");
}
verifyAccessibleContextCommon(
context,
expectedName,
expectedDescription,
expectedRole,
expectAction,
expectSelection,
expectText,
expectValue);
AccessibleComponent accessibleComponent =
context.getAccessibleComponent();
if (accessibleComponent == null) {
throw new RuntimeException("getAccessibleComponent returned null");
}
new AccessibleMenuComponentTester(
menuComponent, accessibleComponent).test();
}
private static void verifyClickAction(AccessibleContext context,
String componentName) {
AccessibleAction action = context.getAccessibleAction();
if (action == null) {
throw new RuntimeException("getAccessibleAction should not return null for Button");
throw new RuntimeException(
"getAccessibleAction should not return null for " +
componentName);
}
int actionCount = action.getAccessibleActionCount();
if (actionCount != 1) {
throw new RuntimeException(
"getAccessibleActionCount should return 1 for Button; got " + actionCount
);
"getAccessibleActionCount returned the wrong number for " +
componentName);
}
String actionDescription = action.getAccessibleActionDescription(0);
if (!"click".equals(actionDescription)) {
throw new RuntimeException(
"getAccessibleActionDescription(0) should return \"click\" for Button; got ["
+ actionDescription + "]"
);
"getAccessibleActionDescription returned the wrong " +
"description for " + componentName);
}
}
private static void verifyZeroAccessibleValue(AccessibleContext context,
String componentName) {
AccessibleValue value = context.getAccessibleValue();
if (value == null) {
throw new RuntimeException("getAccessibleValue should not return null for Button");
throw new RuntimeException(
"getAccessibleValue should not return null for " +
componentName);
}
assertIntValueEquals("getCurrentAccessibleValue", 0, value.getCurrentAccessibleValue());
assertIntValueEquals("getMinimumAccessibleValue", 0, value.getMinimumAccessibleValue());
assertIntValueEquals("getMaximumAccessibleValue", 0, value.getMaximumAccessibleValue());
assertIntValueEquals(
"getCurrentAccessibleValue",
0,
value.getCurrentAccessibleValue());
assertIntValueEquals(
"getMinimumAccessibleValue",
0,
value.getMinimumAccessibleValue());
assertIntValueEquals(
"getMaximumAccessibleValue",
0,
value.getMaximumAccessibleValue());
if (value.setCurrentAccessibleValue(Integer.valueOf(5))) {
throw new RuntimeException(
"setCurrentAccessibleValue(5) should return false for Button"
);
"setCurrentAccessibleValue should return false for " +
componentName);
}
assertIntValueEquals(
"getCurrentAccessibleValue after setCurrentAccessibleValue(5)",
0,
value.getCurrentAccessibleValue()
);
value.getCurrentAccessibleValue());
}
private static void assertExpectedString(String methodName, String expected, String actual) {
private static void verifyListChildren(List list) {
AccessibleContext context = list.getAccessibleContext();
int childCount = context.getAccessibleChildrenCount();
if (childCount != list.getItemCount()) {
throw new RuntimeException(
"getAccessibleChildrenCount returned an incorrect value " +
"for List");
}
for (int i = 0; i < childCount; i++) {
Accessible child = context.getAccessibleChild(i);
if (child == null) {
throw new RuntimeException(
"getAccessibleChild returned null for child " + i);
}
AccessibleContext childContext = child.getAccessibleContext();
if (childContext == null) {
throw new RuntimeException(
"getAccessibleContext returned null for List child " +
i);
}
if (childContext.getAccessibleRole() != AccessibleRole.LIST_ITEM) {
throw new RuntimeException(
"The AccessibleRole of AccessibleAWTListChild is " +
"incorrect for child " + i);
}
if (childContext.getAccessibleIndexInParent() != i) {
throw new RuntimeException(
"getAccessibleIndexInParent returned an incorrect " +
"value for AccessibleAWTListChild " + i);
}
AccessibleStateSet childStateSet =
childContext.getAccessibleStateSet();
if (childStateSet == null) {
throw new RuntimeException(
"getAccessibleStateSet returned null for List child " +
i);
}
boolean accessibleSelected =
childStateSet.contains(AccessibleState.SELECTED);
boolean listSelected = list.isIndexSelected(i);
if (accessibleSelected != listSelected) {
throw new RuntimeException(
"getAccessibleStateSet reports that list item " + i +
(accessibleSelected ? " is " : " is not ") +
"selected but List reports that it " +
(listSelected ? "is" : "is not") + " selected");
}
}
}
private static void verifyContainerChildren(Component component,
String componentName) {
AccessibleContext context = component.getAccessibleContext();
int childCount = context.getAccessibleChildrenCount();
if (childCount != component.getAccessibleContext()
.getAccessibleChildrenCount()) {
throw new RuntimeException(
"getAccessibleChildrenCount returned an incorrect value " +
"for " + componentName);
}
for (int i = 0; i < childCount; i++) {
Accessible child = context.getAccessibleChild(i);
if (child == null) {
throw new RuntimeException(
"getAccessibleChild returned null for " +
componentName + " child " + i);
}
AccessibleContext childContext = child.getAccessibleContext();
if (childContext == null) {
throw new RuntimeException(
"getAccessibleContext returned null for " +
componentName + " child " + i);
}
}
}
private static void assertExpectedString(String methodName,
String expected,
String actual) {
if (expected == null) {
throw new RuntimeException("Excepted value is null. Provide " +
"excepted value");
throw new RuntimeException(
"Expected value for " + methodName + " should not be null");
}
if (actual == null) {
throw new RuntimeException(methodName + " returned null; expected" +
" [" + expected + "]");
throw new RuntimeException(
methodName + " returned null; expected [" + expected + "]");
}
if (!expected.equals(actual)) {
throw new RuntimeException(methodName + " returned [" + actual +
"]; expected [" + expected + "]");
throw new RuntimeException(
methodName + " returned [" + actual +
"]; expected [" + expected + "]");
}
}
private static void assertPresence(String methodName, boolean expectedPresent, Object value) {
private static void assertPresence(String methodName,
boolean expectedPresent,
Object value) {
if (expectedPresent && value == null) {
throw new RuntimeException(methodName + " returned null but was expected");
throw new RuntimeException(
methodName + " returned null but should not");
}
if (!expectedPresent && value != null) {
throw new RuntimeException(methodName + " returned non-null but " +
"was expected to be null");
throw new RuntimeException(
methodName + " returned non-null but should return null");
}
}
private static void assertLocaleMatches(Component component, AccessibleContext context) {
private static void assertLocaleMatches(Component component,
AccessibleContext context) {
Locale componentLocale = component.getLocale();
Locale accessibleLocale = context.getLocale();
if (componentLocale == null) {
throw new RuntimeException("Component.getLocale returned null");
}
if (accessibleLocale == null) {
throw new RuntimeException("AccessibleContext.getLocale returned null");
throw new RuntimeException(
"AccessibleContext.getLocale returned null");
}
if (!componentLocale.equals(accessibleLocale)) {
throw new RuntimeException(String.format(
"AccessibleContext.getLocale returned [%s], but Component" +
".getLocale returned [%s]",
accessibleLocale, componentLocale
));
throw new RuntimeException(
"AccessibleContext.getLocale returned [" +
accessibleLocale + "], but Component.getLocale returned [" +
componentLocale + "]");
}
}
private static void assertIntValueEquals(String methodName, int expected, Number actual) {
private static void assertIntValueEquals(String methodName,
int expected,
Number actual) {
if (actual == null) {
throw new RuntimeException(methodName + " returned null; expected [" + expected + "]");
throw new RuntimeException(
methodName + " returned null; expected [" + expected + "]");
}
if (actual.intValue() != expected) {
throw new RuntimeException(
methodName + " returned [" + actual + "]; expected [" + expected + "]"
);
methodName + " returned [" + actual +
"]; expected [" + expected + "]");
}
}
}

View File

@ -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
@ -32,13 +32,15 @@
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import jdk.test.lib.security.SecurityUtils;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.Utils;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.security.SecurityUtils;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
@ -50,29 +52,32 @@ import javax.net.ssl.SSLHandshakeException;
public class DisabledCipherSuitesNotNegotiated {
private static final String TLS_PROTOCOL = "TLSv1.2";
private static volatile int serverPort = 0;
private static volatile Exception serverException = null;
private static final CountDownLatch waitForServer = new CountDownLatch(1);
private static final int WAIT_FOR_SERVER_SECS = 5;
private static final int WAIT_FOR_SERVER_SECS = (int)Utils.adjustTimeout(5);
private static final String DISABLED_CIPHERSUITE = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
private static final String DISABLED_CIPHER_WILDCARD = "TLS_ECDH*WITH_AES_256_GCM_*";
private static volatile Exception serverException = null;
private static void runServer(boolean disabledInClient) throws Exception {
SSLContext ctx = SSLContext.getInstance(TLS_PROTOCOL);
ctx.init(null, null, null);
SSLServerSocketFactory factory = ctx.getServerSocketFactory();
InetAddress address = InetAddress.getLoopbackAddress();
System.out.println("SERVER listening on " + address);
try(SSLServerSocket serverSocket = (SSLServerSocket)factory
.createServerSocket(0, -1, InetAddress.getLoopbackAddress())) {
serverPort = serverSocket.getLocalPort();
waitForServer.countDown();
.createServerSocket(0, -1, address)) {
if (disabledInClient) {
// set cipher suite to disabled ciphersuite
serverSocket.setEnabledCipherSuites(new String[]{DISABLED_CIPHERSUITE});
}
try(SSLSocket clientSocket = (SSLSocket) serverSocket.accept()) {
serverPort = serverSocket.getLocalPort();
serverSocket.setSoTimeout(WAIT_FOR_SERVER_SECS * 3000);
waitForServer.countDown();
try(SSLSocket clientSocket = (SSLSocket)serverSocket.accept()) {
try {
clientSocket.getInputStream().readAllBytes();
throw new Exception("SERVER: The expected handshake exception was not thrown.");
@ -88,7 +93,9 @@ public class DisabledCipherSuitesNotNegotiated {
SSLContext ctx = SSLContext.getInstance(TLS_PROTOCOL);
ctx.init(null, null, null);
SSLSocketFactory factory = ctx.getSocketFactory();
try(SSLSocket socket = (SSLSocket)factory.createSocket("localhost", portNumber)) {
InetAddress address = InetAddress.getLoopbackAddress();
System.out.println("CLIENT: Connecting to " + address);
try(SSLSocket socket = (SSLSocket)factory.createSocket(address, portNumber)) {
if (!disableInClient) {
socket.setEnabledCipherSuites(new String[]{DISABLED_CIPHERSUITE});
}
@ -104,42 +111,7 @@ public class DisabledCipherSuitesNotNegotiated {
public static void main(String [] args) throws Exception {
if (args.length == 1) {
// run server-side
final boolean disabledInClient = args[0].equals("client");
if (!disabledInClient) {
SecurityUtils.addToDisabledTlsAlgs(DISABLED_CIPHER_WILDCARD);
}
try(ExecutorService executorService = Executors.newSingleThreadExecutor()) {
executorService.submit(() -> {
try {
runServer(disabledInClient);
} catch (Exception exc) {
System.out.println("Server Exception:");
exc.printStackTrace(System.out);
serverException = exc;
throw new RuntimeException(exc);
}
});
if (!waitForServer.await(WAIT_FOR_SERVER_SECS, TimeUnit.SECONDS)) {
throw new Exception("Server did not start within " +
WAIT_FOR_SERVER_SECS + " seconds.");
}
System.out.printf("Server listening on port %d.%nStarting client process...",
serverPort);
OutputAnalyzer oa = ProcessTools.executeProcess(
ProcessTools.createTestJavaProcessBuilder("DisabledCipherSuitesNotNegotiated",
"" + disabledInClient, "" + serverPort));
oa.shouldHaveExitValue(0);
System.out.println("Client output:");
System.out.println(oa.getOutput());
if (serverException != null) {
throw new Exception ("Server-side threw an unexpected exception: "
+ serverException);
}
}
runTest(args[0].equals("client"));
} else if (args.length == 2) {
// run client-side
@ -147,6 +119,7 @@ public class DisabledCipherSuitesNotNegotiated {
if (disabledInClient) {
SecurityUtils.addToDisabledTlsAlgs(DISABLED_CIPHER_WILDCARD);
}
runClient(Boolean.parseBoolean(args[0]), Integer.parseInt(args[1]));
} else {
@ -155,4 +128,48 @@ public class DisabledCipherSuitesNotNegotiated {
}
}
private static void runTest(final boolean disabledInClient) throws Exception {
try(ExecutorService executorService = Executors.newSingleThreadExecutor()) {
Future<?> serverThread = executorService.submit(() -> {
try {
if (!disabledInClient) {
SecurityUtils.addToDisabledTlsAlgs(DISABLED_CIPHER_WILDCARD);
}
runServer(disabledInClient);
} catch (Exception exc) {
serverException = exc;
}
});
if (!waitForServer.await(WAIT_FOR_SERVER_SECS, TimeUnit.SECONDS)) {
throw new Exception("Server did not start within " +
WAIT_FOR_SERVER_SECS + " seconds.");
}
System.out.printf("Server listening on port %d.%nStarting client process...",
serverPort);
OutputAnalyzer oa = ProcessTools.executeProcess(
ProcessTools.createTestJavaProcessBuilder(
"DisabledCipherSuitesNotNegotiated",
"" + disabledInClient, "" + serverPort));
oa.waitFor();
serverThread.get();
System.out.printf("Client process return %d%nCLIENT OUTPUT%n%s%n",
oa.getExitValue(), oa.getOutput());
if (serverException != null) {
System.out.printf(
"Server thread threw an unexpected exception: %s%n",
serverException);
throw serverException;
} else if (oa.getExitValue() != 0) {
throw new Exception(String.format("Client exit code is non-zero (%d). "+
"Server did not throw an exception.",
oa.getExitValue()));
}
}
}
}

View File

@ -103,9 +103,9 @@ public class TestErasure extends JavadocTester {
checkOutput("Foo.html", true, """
<li><a href="#constructor-detail" tabindex="0">Constructor Details</a>
<ol class="toc-list">
<li><a href="#%3Cinit%3E(T)" tabindex="0">Foo(T)</a></li>
<li><a href="#%3Cinit%3E(X)" tabindex="0">Foo(T)</a></li>
<li><a href="#%3Cinit%3E(Y)" tabindex="0">Foo(T)</a></li>
<li><a href="#%3Cinit%3E(T)" tabindex="0">Foo(<wbr>T)</a></li>
<li><a href="#%3Cinit%3E(X)" tabindex="0">Foo(<wbr>T)</a></li>
<li><a href="#%3Cinit%3E(Y)" tabindex="0">Foo(<wbr>T)</a></li>
</ol>
</li>""");
checkOutput("index-all.html", true, """
@ -145,9 +145,9 @@ public class TestErasure extends JavadocTester {
checkOutput("Foo.html", true, """
<li><a href="#method-detail" tabindex="0">Method Details</a>
<ol class="toc-list">
<li><a href="#m(T)" tabindex="0">m(T)</a></li>
<li><a href="#m(X)" tabindex="0">m(T)</a></li>
<li><a href="#m(Y)" tabindex="0">m(T)</a></li>
<li><a href="#m(T)" tabindex="0">m(<wbr>T)</a></li>
<li><a href="#m(X)" tabindex="0">m(<wbr>T)</a></li>
<li><a href="#m(Y)" tabindex="0">m(<wbr>T)</a></li>
</ol>
</li>""");
checkOutput("index-all.html", true, """
@ -210,8 +210,8 @@ public class TestErasure extends JavadocTester {
checkOutput("Foo.html", true, """
<li><a href="#constructor-detail" tabindex="0">Constructor Details</a>
<ol class="toc-list">
<li><a href="#%3Cinit%3E(T)" tabindex="0">Foo(T)</a></li>
<li><a href="#%3Cinit%3E(X)" tabindex="0">Foo(T)</a></li>
<li><a href="#%3Cinit%3E(T)" tabindex="0">Foo(<wbr>T)</a></li>
<li><a href="#%3Cinit%3E(X)" tabindex="0">Foo(<wbr>T)</a></li>
</ol>
</li>""");
checkOutput("index-all.html", true, """
@ -242,8 +242,8 @@ public class TestErasure extends JavadocTester {
checkOutput("Foo.html", true, """
<li><a href="#method-detail" tabindex="0">Method Details</a>
<ol class="toc-list">
<li><a href="#m(T)" tabindex="0">m(T)</a></li>
<li><a href="#m(X)" tabindex="0">m(T)</a></li>
<li><a href="#m(T)" tabindex="0">m(<wbr>T)</a></li>
<li><a href="#m(X)" tabindex="0">m(<wbr>T)</a></li>
</ol>
</li>""");
checkOutput("index-all.html", true, """

View File

@ -25,7 +25,7 @@
* @test
* @bug 7025314 8023700 7198273 8025633 8026567 8081854 8196027 8182765
* 8196200 8196202 8223378 8258659 8261976 8320458 8329537 8350638
* 8342705 8371021 8373526
* 8342705 8371021 8373526 8384065
* @summary Make sure the Next/Prev Class links iterate through all types.
* Make sure the navagation is 2 columns, not 3.
* @library /tools/lib ../../lib
@ -172,6 +172,36 @@ public class TestNavigation extends JavadocTester {
tb.writeJavaFiles(src,
"""
package pkg1; public class A {
/**
* Empty ctor
*/
public A() {}
/**
* Single param ctor
*/
public A(int i) {}
/**
* A ctor with many params
*/
public A(int i, int j, int x, int y, String s, boolean b) {}
/**
* A method without parameters
*/
public void noParams() {}
/**
* A method with a single parameter
*/
public void oneParam(String s) {}
/**
* A method with lots of parameters
*/
public void manyParams(String s, int i, int j, boolean b, double d, double e) {}
/**
* Class with members.
*/
@ -217,6 +247,29 @@ public class TestNavigation extends JavadocTester {
"pkg1");
checkExit(Exit.OK);
checkOrder("pkg1/A.html",
"""
<ol class="toc-list" tabindex="-1">
<li><a href="#" tabindex="0">Description</a></li>
<li><a href="#nested-class-summary" tabindex="0">Nested Class Summary</a></li>
<li><a href="#constructor-summary" tabindex="0">Constructor Summary</a></li>
<li><a href="#method-summary" tabindex="0">Method Summary</a></li>
<li><a href="#constructor-detail" tabindex="0">Constructor Details</a>
<ol class="toc-list">
<li><a href="#%3Cinit%3E()" tabindex="0">A()</a></li>
<li><a href="#%3Cinit%3E(int)" tabindex="0">A(<wbr>int)</a></li>
<li><a href="#%3Cinit%3E(int,int,int,int,java.lang.String,boolean)" tabindex="0">A(<wbr>int, int, int, int, String, boolean)</a></li>
</ol>
</li>
<li><a href="#method-detail" tabindex="0">Method Details</a>
<ol class="toc-list">
<li><a href="#noParams()" tabindex="0">noParams()</a></li>
<li><a href="#oneParam(java.lang.String)" tabindex="0">oneParam(<wbr>String)</a></li>
<li><a href="#manyParams(java.lang.String,int,int,boolean,double,double)" tabindex="0">manyParams(<wbr>String, int, int, boolean, double, double)</a></li>
</ol>
</li>
</ol>""");
checkOrder("pkg1/A.X.html",
"""
<ol class="sub-nav-list">

View File

@ -288,7 +288,6 @@ public class TestStylesheet extends JavadocTester {
"field-summary",
"member-details",
"method-details",
"method-summary",
// the following provide the ability to optionally override components of the
// memberSignature structure
"name",