Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
eee7d9c
8362582: GHA: Increase bundle retention time to deal with infra overl…
shipilev Jul 22, 2025
602018d
8202667: java/awt/Debug/DumpOnKey/DumpOnKey.java times out on Windows
GoeLin Jul 22, 2025
cfddb16
8282147: [TESTBUG] waitForIdle after creating frame in JSpinnerMouseA…
GoeLin Jul 22, 2025
e97a8fa
8300207: Add a pre-check for the number of canonical equivalent permu…
GoeLin Jul 22, 2025
0c923e8
8303525: Refactor/cleanup open/test/jdk/javax/rmi/ssl/SSLSocketParame…
GoeLin Jul 22, 2025
4be1e87
8335131: Test "javax/swing/JColorChooser/Test6977726.java" failed on …
GoeLin Jul 22, 2025
36b9eba
8249825: Tests sun/security/ssl/SSLSocketImpl/SetClientMode.java and …
GoeLin Jul 22, 2025
eedad33
8327838: Convert java/awt/FileDialog/MultipleMode/MultipleMode.html a…
GoeLin Jul 23, 2025
e120d5f
8328030: Convert javax/swing/text/GlyphView/4984669/bug4984669.java a…
GoeLin Jul 23, 2025
9b3765f
8327972: Convert java/awt/FileDialog/SaveFileNameOverrideTest/SaveFil…
GoeLin Jul 23, 2025
1799d23
8327826: Convert javax/swing/border/Test4243289.java applet test to main
GoeLin Jul 23, 2025
c159a0c
8352896: LambdaExpr02.java runs wrong test class
Jul 24, 2025
4b4cfe7
8286171: HttpClient/2 : Expect:100-Continue blocks indefinitely when …
GoeLin Jul 24, 2025
bbbe85c
8316580: HttpClient with StructuredTaskScope does not close when a ta…
GoeLin Jul 24, 2025
e236cad
8357672: Extreme font sizes can cause font substitution
GoeLin Jul 24, 2025
1400595
8317808: HTTP/2 stream cancelImpl may leave subscriber registered
GoeLin Jul 24, 2025
d2dad32
8362839: [21u] Problem list more tests that fail in 21 and would be f…
GoeLin Jul 24, 2025
86711b2
Merge remote-tracking branch 'upstream/master' into upstream-sync
actions-user Jul 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/build-jtreg/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,4 @@ runs:
with:
name: bundles-jtreg-${{ steps.version.outputs.value }}
path: jtreg/installed
retention-days: 1
retention-days: 5
2 changes: 1 addition & 1 deletion .github/actions/upload-bundles/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,5 @@ runs:
with:
name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }}
path: bundles
retention-days: 1
retention-days: 5
if: steps.bundles.outputs.bundles-found == 'true'
37 changes: 32 additions & 5 deletions src/java.base/share/classes/java/util/regex/Pattern.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -1090,6 +1090,10 @@ public static Pattern compile(String regex) {
*
* @throws PatternSyntaxException
* If the expression's syntax is invalid
*
* @implNote If {@link #CANON_EQ} is specified and the number of combining
* marks for any character is too large, an {@link java.lang.OutOfMemoryError}
* is thrown.
*/
public static Pattern compile(String regex, int flags) {
return new Pattern(regex, flags);
Expand Down Expand Up @@ -1123,6 +1127,13 @@ public String toString() {
* The character sequence to be matched
*
* @return A new matcher for this pattern
*
* @implNote When a {@link Pattern} is deserialized, compilation is deferred
* until a direct or indirect invocation of this method. Thus, if a
* deserialized pattern has {@link #CANON_EQ} among its flags and the number
* of combining marks for any character is too large, an
* {@link java.lang.OutOfMemoryError} is thrown,
* as in {@link #compile(String, int)}.
*/
public Matcher matcher(CharSequence input) {
if (!compiled) {
Expand Down Expand Up @@ -1596,14 +1607,30 @@ private static String[] producePermutations(String input) {
return result;
}

int length = 1;
/*
* Since
* 12! = 479_001_600 < Integer.MAX_VALUE
* 13! = 6_227_020_800 > Integer.MAX_VALUE
* the computation of n! using int arithmetic will overflow iff
* n < 0 or n > 12
*
* Here, nCodePoints! is computed in the next for-loop below.
* As nCodePoints >= 0, the computation overflows iff nCodePoints > 12.
* In that case, throw OOME to simulate length > Integer.MAX_VALUE.
*/
int nCodePoints = countCodePoints(input);
for(int x=1; x<nCodePoints; x++)
length = length * (x+1);
if (nCodePoints > 12) {
throw new OutOfMemoryError("Pattern too complex");
}

/* Compute length = nCodePoints! */
int length = 1;
for (int x = 2; x <= nCodePoints; ++x) {
length *= x;
}
String[] temp = new String[length];

int combClass[] = new int[nCodePoints];
int[] combClass = new int[nCodePoints];
for(int x=0, i=0; x<nCodePoints; x++) {
int c = Character.codePointAt(input, i);
combClass[x] = getClass(c);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ public class FileFontStrike extends PhysicalStrike {
this.disposer = new FontStrikeDisposer(fileFont, desc);
initGlyphCache();
pScalerContext = NullFontScaler.getNullScalerContext();
SunFontManager.getInstance().deRegisterBadFont(fileFont);
return;
}
/* First, see if native code should be used to create the glyph.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,6 @@ Java_sun_font_FreetypeFontScaler_createScalerContextNative(

if (context == NULL) {
free(context);
invalidateJavaScaler(env, scaler, NULL);
return (jlong) 0;
}
(*env)->GetDoubleArrayRegion(env, matrix, 0, 4, dmat);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,8 +464,8 @@ private CompletableFuture<Response> expectContinue(ExchangeImpl<T> ex) {
"Unable to handle 101 while waiting for 100");
return MinimalFuture.failedFuture(failed);
}
return exchImpl.readBodyAsync(this::ignoreBody, false, parentExecutor)
.thenApply(v -> r1);
exchImpl.expectContinueFailed(rcode);
return MinimalFuture.completedFuture(r1);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,4 +260,8 @@ HttpBodySubscriberWrapper<T> createResponseSubscriber(HttpResponse.BodyHandler<T
// Needed to handle cancellation during the upgrade from
// Http1Exchange to Stream
void upgraded() { }

// Called when server returns non 100 response to
// an Expect-Continue
void expectContinueFailed(int rcode) { }
}
Original file line number Diff line number Diff line change
Expand Up @@ -863,4 +863,14 @@ final HttpClientImpl client() {
String dbgString() {
return "Http1Exchange";
}

@Override
void expectContinueFailed(int rcode) {
var response = this.response;
if (response != null) {
// Sets a flag which closes the connection locally when
// onFinished() is called
response.closeWhenFinished();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class Http1Response<T> {
private final Http1AsyncReceiver asyncReceiver;
private volatile EOFException eof;
private volatile BodyParser bodyParser;
private volatile boolean closeWhenFinished;
// max number of bytes of (fixed length) body to ignore on redirect
private static final int MAX_IGNORE = 1024;

Expand Down Expand Up @@ -404,7 +405,11 @@ public <U> CompletableFuture<U> readBody(HttpResponse.BodySubscriber<U> p,

private void onFinished() {
asyncReceiver.clear();
if (return2Cache) {
if (closeWhenFinished) {
if (debug.on())
debug.log("Closing Connection when finished");
connection.close();
} else if (return2Cache) {
Log.logTrace("Attempting to return connection to the pool: {0}", connection);
// TODO: need to do something here?
// connection.setAsyncCallbacks(null, null, null);
Expand All @@ -416,6 +421,10 @@ private void onFinished() {
}
}

void closeWhenFinished() {
closeWhenFinished = true;
}

HttpHeaders responseHeaders() {
return headers;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,23 +279,25 @@ public String toString() {
}
}

static void registerPending(PendingRequest pending) {
static <T> CompletableFuture<T> registerPending(PendingRequest pending, CompletableFuture<T> res) {
// shortcut if cf is already completed: no need to go through the trouble of
// registering it
if (pending.cf.isDone()) return;
if (pending.cf.isDone()) return res;

var client = pending.client;
var cf = pending.cf;
var id = pending.id;
boolean added = client.pendingRequests.add(pending);
// this may immediately remove `pending` from the set is the cf is already completed
pending.ref = cf.whenComplete((r,t) -> client.pendingRequests.remove(pending));
var ref = res.whenComplete((r,t) -> client.pendingRequests.remove(pending));
pending.ref = ref;
assert added : "request %d was already added".formatted(id);
// should not happen, unless the selector manager has already
// exited abnormally
if (client.selmgr.isClosed()) {
pending.abort(client.selmgr.selectorClosedException());
}
return ref;
}

static void abortPendingRequests(HttpClientImpl client, Throwable reason) {
Expand Down Expand Up @@ -558,8 +560,9 @@ public boolean registerSubscriber(HttpBodySubscriberWrapper<?> subscriber) {
if (debug.on()) {
debug.log("body subscriber registered: " + count);
}
return true;
}
return true;
return false;
}
}
}
Expand Down Expand Up @@ -875,8 +878,9 @@ private void debugCompleted(String tag, long startNanos, HttpRequest req) {
cf = sendAsync(req, responseHandler, null, null);
return cf.get();
} catch (InterruptedException ie) {
if (cf != null )
if (cf != null) {
cf.cancel(true);
}
throw ie;
} catch (ExecutionException e) {
final Throwable throwable = e.getCause();
Expand Down Expand Up @@ -991,19 +995,23 @@ private void debugCompleted(String tag, long startNanos, HttpRequest req) {
(b,t) -> debugCompleted("ClientImpl (async)", start, userRequest));
}

// makes sure that any dependent actions happen in the CF default
// executor. This is only needed for sendAsync(...), when
// exchangeExecutor is non-null.
if (exchangeExecutor != null) {
res = res.whenCompleteAsync((r, t) -> { /* do nothing */}, ASYNC_POOL);
}

// The mexCf is the Cf we need to abort if the SelectorManager thread
// is aborted.
PendingRequest pending = new PendingRequest(id, requestImpl, mexCf, mex, this);
registerPending(pending);
return res;
} catch(Throwable t) {
res = registerPending(pending, res);

if (exchangeExecutor != null) {
// makes sure that any dependent actions happen in the CF default
// executor. This is only needed for sendAsync(...), when
// exchangeExecutor is non-null.
return res.isDone() ? res
: res.whenCompleteAsync((r, t) -> { /* do nothing */}, ASYNC_POOL);
} else {
// make a defensive copy that can be safely canceled
// by the caller
return res.isDone() ? res : res.copy();
}
} catch (Throwable t) {
requestUnreference();
debugCompleted("ClientImpl (async)", start, userRequest);
throw t;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class MultiExchange<T> implements Cancelable {
Exchange<T> previous;
volatile Throwable retryCause;
volatile boolean expiredOnce;
volatile HttpResponse<T> response = null;
volatile HttpResponse<T> response;

// Maximum number of times a request will be retried/redirected
// for any reason
Expand Down Expand Up @@ -274,11 +274,19 @@ public void cancel(IOException cause) {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
boolean cancelled = this.cancelled;
boolean firstCancel = false;
if (!cancelled && mayInterruptIfRunning) {
if (interrupted.get() == null) {
interrupted.compareAndSet(null,
firstCancel = interrupted.compareAndSet(null,
new CancellationException("Request cancelled"));
}
if (debug.on()) {
if (firstCancel) {
debug.log("multi exchange recording: " + interrupted.get());
} else {
debug.log("multi exchange recorded: " + interrupted.get());
}
}
this.cancelled = true;
var exchange = getExchange();
if (exchange != null) {
Expand Down Expand Up @@ -360,17 +368,30 @@ private CompletableFuture<HttpResponse<T>> handleNoBody(Response r, Exchange<T>
}).exceptionallyCompose(this::whenCancelled);
}

// returns a CancellationExcpetion that wraps the given cause
// if cancel(boolean) was called, the given cause otherwise
private Throwable wrapIfCancelled(Throwable cause) {
CancellationException interrupt = interrupted.get();
if (interrupt == null) return cause;

var cancel = new CancellationException(interrupt.getMessage());
// preserve the stack trace of the original exception to
// show where the call to cancel(boolean) came from
cancel.setStackTrace(interrupt.getStackTrace());
cancel.initCause(Utils.getCancelCause(cause));
return cancel;
}

// if the request failed because the multi exchange was cancelled,
// make sure the reported exception is wrapped in CancellationException
private CompletableFuture<HttpResponse<T>> whenCancelled(Throwable t) {
CancellationException x = interrupted.get();
if (x != null) {
// make sure to fail with CancellationException if cancel(true)
// was called.
t = x.initCause(Utils.getCancelCause(t));
var x = wrapIfCancelled(t);
if (x instanceof CancellationException) {
if (debug.on()) {
debug.log("MultiExchange interrupted with: " + t.getCause());
debug.log("MultiExchange interrupted with: " + x.getCause());
}
}
return MinimalFuture.failedFuture(t);
return MinimalFuture.failedFuture(x);
}

static class NullSubscription implements Flow.Subscription {
Expand Down
16 changes: 12 additions & 4 deletions src/java.net.http/share/classes/jdk/internal/net/http/Stream.java
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ private void schedule() {
if (debug.on()) debug.log("subscribing user subscriber");
subscriber.onSubscribe(userSubscription);
}
while (!inputQ.isEmpty()) {
while (!inputQ.isEmpty() && errorRef.get() == null) {
Http2Frame frame = inputQ.peek();
if (frame instanceof ResetFrame) {
inputQ.remove();
Expand Down Expand Up @@ -310,6 +310,13 @@ private boolean consumed(DataFrame df) {
return endStream;
}

@Override
void expectContinueFailed(int rcode) {
// Have to mark request as sent, due to no request body being sent in the
// event of a 417 Expectation Failed or some other non 100 response code
requestSent();
}

// This method is called by Http2Connection::decrementStreamCount in order
// to make sure that the stream count is decremented only once for
// a given stream.
Expand Down Expand Up @@ -409,6 +416,10 @@ private void sendDataFrame(DataFrame frame) {
// pushes entire response body into response subscriber
// blocking when required by local or remote flow control
CompletableFuture<T> receiveData(BodySubscriber<T> bodySubscriber, Executor executor) {
// ensure that the body subscriber will be subscribed and onError() is
// invoked
pendingResponseSubscriber = bodySubscriber;

// We want to allow the subscriber's getBody() method to block so it
// can work with InputStreams. So, we offload execution.
responseBodyCF = ResponseSubscribers.getBodyAsync(executor, bodySubscriber,
Expand All @@ -419,9 +430,6 @@ CompletableFuture<T> receiveData(BodySubscriber<T> bodySubscriber, Executor exec
responseBodyCF.completeExceptionally(t);
}

// ensure that the body subscriber will be subscribed and onError() is
// invoked
pendingResponseSubscriber = bodySubscriber;
sched.runOrSchedule(); // in case data waiting already to be processed, or error

return responseBodyCF;
Expand Down
7 changes: 7 additions & 0 deletions test/hotspot/jtreg/ProblemList.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,17 @@ gc/g1/logging/TestG1LoggingFailure.java 8169634 generic-all
gc/g1/humongousObjects/TestHeapCounters.java 8178918 generic-all
gc/shenandoah/TestAllocIntArrays.java#aggressive 8309622 generic-all
gc/shenandoah/TestAllocIntArrays.java#iu-aggressive 8309622 generic-all
gc/shenandoah/TestAllocObjectArrays.java#aggressive 8309622 generic-all
gc/shenandoah/TestAllocObjectArrays.java#iu-aggressive 8309622 generic-all
gc/shenandoah/TestJcmdHeapDump.java#aggressive 8309622 generic-all
gc/shenandoah/TestJcmdHeapDump.java#iu-aggressive 8309622 generic-all
gc/shenandoah/TestSieveObjects.java#aggressive 8309622 generic-all
gc/shenandoah/TestSieveObjects.java#iu-aggressive 8309622 generic-all
gc/stress/CriticalNativeStress.java#id1 8312028 generic-all
gc/stress/gclocker/TestExcessGCLockerCollections.java 8229120 generic-all
gc/stress/gclocker/TestGCLockerWithParallel.java 8180622 generic-all
gc/stress/gclocker/TestGCLockerWithG1.java 8180622 generic-all
gc/stress/gcold/TestGCOldWithShenandoah.java#aggressive 8309622 generic-all
gc/stress/gcold/TestGCOldWithShenandoah.java#iu-aggressive 8309622 generic-all
gc/stress/TestJNIBlockFullGC/TestJNIBlockFullGC.java 8192647 generic-all

Expand Down
1 change: 0 additions & 1 deletion test/jdk/ProblemList.txt
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,6 @@ java/awt/font/TextLayout/LigatureCaretTest.java 8266312 generic-all
java/awt/image/VolatileImage/CustomCompositeTest.java 8199002 windows-all,linux-all
java/awt/image/VolatileImage/GradientPaints.java 8199003 linux-all
java/awt/JAWT/JAWT.sh 8197798 windows-all,linux-all
java/awt/Debug/DumpOnKey/DumpOnKey.java 8202667 windows-all
java/awt/Focus/WindowUpdateFocusabilityTest/WindowUpdateFocusabilityTest.java 8339929 linux-all
java/awt/datatransfer/ConstructFlavoredObjectTest/ConstructFlavoredObjectTest.java 8202860 linux-all
java/awt/FileDialog/FilenameFilterTest/FilenameFilterTest.java 8202882 linux-all
Expand Down
Loading