Java 27 and 26: runnable demos and captured output for every JEP, plus version lanes

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01B38FGKKam5SCGgwgduVAh3
This commit is contained in:
2026-09-21 15:08:50 +00:00
committed by Claude
co-authored by Claude Sonnet 5
commit f59c1de96d
152 changed files with 5049 additions and 0 deletions
@@ -0,0 +1,43 @@
# JEP 523: which collector does the JVM pick when you do not choose one?
# Same class files, same vendor (Amazon Corretto), same 2 GB memory limit. Only the JDK version and the CPU limit change.
=== amazoncorretto:26 --cpus=1 --memory=2g
$ docker run --rm --cpus=1 --memory=2g amazoncorretto:26 java -cp /app GcReport
java.version = 26.0.2.1
availableCpus = 1
maxHeapMB = 511
collector beans = Copy, MarkSweepCompact
UseG1GC = false (origin DEFAULT)
UseSerialGC = true (origin ERGONOMIC)
UseParallelGC = false (origin DEFAULT)
=== amazoncorretto:27 --cpus=1 --memory=2g
$ docker run --rm --cpus=1 --memory=2g amazoncorretto:27 java -cp /app GcReport
java.version = 27
availableCpus = 1
maxHeapMB = 512
collector beans = G1 Young Generation, G1 Concurrent GC, G1 Old Generation
UseG1GC = true (origin ERGONOMIC)
UseSerialGC = false (origin DEFAULT)
UseParallelGC = false (origin DEFAULT)
=== amazoncorretto:26 --cpus=2 --memory=2g
$ docker run --rm --cpus=2 --memory=2g amazoncorretto:26 java -cp /app GcReport
java.version = 26.0.2.1
availableCpus = 2
maxHeapMB = 512
collector beans = G1 Young Generation, G1 Concurrent GC, G1 Old Generation
UseG1GC = true (origin ERGONOMIC)
UseSerialGC = false (origin DEFAULT)
UseParallelGC = false (origin DEFAULT)
=== amazoncorretto:27 --cpus=2 --memory=2g
$ docker run --rm --cpus=2 --memory=2g amazoncorretto:27 java -cp /app GcReport
java.version = 27
availableCpus = 2
maxHeapMB = 512
collector beans = G1 Young Generation, G1 Concurrent GC, G1 Old Generation
UseG1GC = true (origin ERGONOMIC)
UseSerialGC = false (origin DEFAULT)
UseParallelGC = false (origin DEFAULT)
+43
View File
@@ -0,0 +1,43 @@
# The other half of the old rule: memory. The old heuristic wanted at least 2 CPUs AND about 1792 MB.
# With 2 CPUs the CPU half of the rule is satisfied, so only the memory limit differs between these runs.
=== amazoncorretto:26 --cpus=2 --memory=1g
$ docker run --rm --cpus=2 --memory=1g amazoncorretto:26 java -cp /app GcReport
java.version = 26.0.2.1
availableCpus = 2
maxHeapMB = 255
collector beans = Copy, MarkSweepCompact
UseG1GC = false (origin DEFAULT)
UseSerialGC = true (origin ERGONOMIC)
UseParallelGC = false (origin DEFAULT)
=== amazoncorretto:27 --cpus=2 --memory=1g
$ docker run --rm --cpus=2 --memory=1g amazoncorretto:27 java -cp /app GcReport
java.version = 27
availableCpus = 2
maxHeapMB = 256
collector beans = G1 Young Generation, G1 Concurrent GC, G1 Old Generation
UseG1GC = true (origin ERGONOMIC)
UseSerialGC = false (origin DEFAULT)
UseParallelGC = false (origin DEFAULT)
=== amazoncorretto:26 --cpus=2 --memory=2g
$ docker run --rm --cpus=2 --memory=2g amazoncorretto:26 java -cp /app GcReport
java.version = 26.0.2.1
availableCpus = 2
maxHeapMB = 512
collector beans = G1 Young Generation, G1 Concurrent GC, G1 Old Generation
UseG1GC = true (origin ERGONOMIC)
UseSerialGC = false (origin DEFAULT)
UseParallelGC = false (origin DEFAULT)
=== amazoncorretto:27 --cpus=2 --memory=2g
$ docker run --rm --cpus=2 --memory=2g amazoncorretto:27 java -cp /app GcReport
java.version = 27
availableCpus = 2
maxHeapMB = 512
collector beans = G1 Young Generation, G1 Concurrent GC, G1 Old Generation
UseG1GC = true (origin ERGONOMIC)
UseSerialGC = false (origin DEFAULT)
UseParallelGC = false (origin DEFAULT)
+11
View File
@@ -0,0 +1,11 @@
# The opt-out still works on 27: an explicit choice always wins over the JVM's.
=== amazoncorretto:27 --cpus=1 --memory=2g -XX:+UseSerialGC
$ docker run --rm --cpus=1 --memory=2g amazoncorretto:27 java -XX:+UseSerialGC -cp /app GcReport
java.version = 27
availableCpus = 1
maxHeapMB = 511
collector beans = Copy, MarkSweepCompact
UseG1GC = false (origin DEFAULT)
UseSerialGC = true (origin VM_CREATION)
UseParallelGC = false (origin DEFAULT)
+51
View File
@@ -0,0 +1,51 @@
# Allocation workload, 1 CPU / 2 GB container, 4000 batches x 50,000 objects, 3 runs per configuration (indicative, not a benchmark)
# 'default' means nobody passed a collector flag.
=== amazoncorretto:26 default run 1
wall time = 5980 ms
gc count / time = 1275 / 1831 ms
slowest batch = 115 ms
peak RSS = 557 MB
=== amazoncorretto:26 default run 2
wall time = 6145 ms
gc count / time = 1275 / 1872 ms
slowest batch = 142 ms
peak RSS = 557 MB
=== amazoncorretto:26 default run 3
wall time = 6402 ms
gc count / time = 1275 / 1861 ms
slowest batch = 129 ms
peak RSS = 557 MB
=== amazoncorretto:27 default run 1
wall time = 8196 ms
gc count / time = 140 / 1955 ms
slowest batch = 39 ms
peak RSS = 547 MB
=== amazoncorretto:27 default run 2
wall time = 8214 ms
gc count / time = 140 / 1970 ms
slowest batch = 41 ms
peak RSS = 547 MB
=== amazoncorretto:27 default run 3
wall time = 8432 ms
gc count / time = 140 / 2004 ms
slowest batch = 35 ms
peak RSS = 546 MB
=== amazoncorretto:27 -XX:+UseSerialGC run 1
wall time = 5306 ms
gc count / time = 1264 / 1669 ms
slowest batch = 125 ms
peak RSS = 557 MB
=== amazoncorretto:27 -XX:+UseSerialGC run 2
wall time = 4972 ms
gc count / time = 1264 / 1599 ms
slowest batch = 119 ms
peak RSS = 557 MB
=== amazoncorretto:27 -XX:+UseSerialGC run 3
wall time = 5698 ms
gc count / time = 1264 / 1713 ms
slowest batch = 128 ms
peak RSS = 557 MB
+51
View File
@@ -0,0 +1,51 @@
# Allocation workload, 1 CPU / 2 GB container, 400 batches x 50,000 objects, 3 runs per configuration (indicative, not a benchmark)
# 'default' means nobody passed a collector flag.
=== amazoncorretto:26 default run 1
wall time = 531 ms
gc count / time = 683 / 160 ms
slowest batch = 25 ms
peak RSS = 102 MB
=== amazoncorretto:26 default run 2
wall time = 536 ms
gc count / time = 683 / 165 ms
slowest batch = 22 ms
peak RSS = 103 MB
=== amazoncorretto:26 default run 3
wall time = 564 ms
gc count / time = 683 / 161 ms
slowest batch = 36 ms
peak RSS = 102 MB
=== amazoncorretto:27 default run 1
wall time = 1052 ms
gc count / time = 26 / 204 ms
slowest batch = 26 ms
peak RSS = 492 MB
=== amazoncorretto:27 default run 2
wall time = 974 ms
gc count / time = 26 / 192 ms
slowest batch = 25 ms
peak RSS = 492 MB
=== amazoncorretto:27 default run 3
wall time = 1041 ms
gc count / time = 26 / 234 ms
slowest batch = 36 ms
peak RSS = 492 MB
=== amazoncorretto:27 -XX:+UseSerialGC run 1
wall time = 528 ms
gc count / time = 668 / 147 ms
slowest batch = 23 ms
peak RSS = 98 MB
=== amazoncorretto:27 -XX:+UseSerialGC run 2
wall time = 522 ms
gc count / time = 668 / 157 ms
slowest batch = 27 ms
peak RSS = 98 MB
=== amazoncorretto:27 -XX:+UseSerialGC run 3
wall time = 588 ms
gc count / time = 668 / 157 ms
slowest batch = 48 ms
peak RSS = 97 MB
+41
View File
@@ -0,0 +1,41 @@
# JDK 27, G1 (the default), 1 CPU / 2 GB container, 400 batches, 2 runs per configuration
=== flags that differ between 26 and 27 (from -XX:+PrintFlagsFinal)
--- amazoncorretto:26
uint ConcGCThreads = 0 {product} {default}
uintx MaxHeapFreeRatio = 70 {manageable} {default}
size_t MaxHeapSize = 536870912 {product} {ergonomic}
uintx MinHeapFreeRatio = 40 {manageable} {default}
uint ParallelGCThreads = 0 {product} {default}
bool UseCompactObjectHeaders = false {product lp64_product} {default}
bool UseCompressedClassPointers = true {product} {default}
--- amazoncorretto:27
uint ConcGCThreads = 1 {product} {ergonomic}
uint G1IHOP = 45 {product} {default}
uintx MaxHeapFreeRatio = 100 {manageable} {default}
size_t MaxHeapSize = 536870912 {product} {ergonomic}
uintx MinHeapFreeRatio = 0 {manageable} {default}
uint ParallelGCThreads = 1 {product} {default}
bool UseCompactObjectHeaders = true {product lp64_product} {default}
=== amazoncorretto:27 flags: [none]
wall time = 1064 ms
gc count / time = 26 / 208 ms
peak RSS = 492 MB
wall time = 1078 ms
gc count / time = 26 / 202 ms
peak RSS = 493 MB
=== amazoncorretto:27 flags: [-XX:MinHeapFreeRatio=40 -XX:MaxHeapFreeRatio=70]
wall time = 1115 ms
gc count / time = 26 / 268 ms
peak RSS = 492 MB
wall time = 982 ms
gc count / time = 26 / 199 ms
peak RSS = 492 MB
=== amazoncorretto:27 flags: [-Xmx256m]
wall time = 976 ms
gc count / time = 37 / 240 ms
peak RSS = 294 MB
wall time = 957 ms
gc count / time = 37 / 261 ms
peak RSS = 294 MB
+82
View File
@@ -0,0 +1,82 @@
java.version = 26.0.2.1
# VM mode: 64 bits
# Compressed references (oops): 0-bit shift
# Compressed class pointers: 0-bit shift and 0x3E000000 base
# Object alignment: 8 bytes
# ref, bool, byte, char, shrt, int, flt, lng, dbl
# Field sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8
# Array base offsets: 16, 16, 16, 16, 16, 16, 16, 16, 16
=== java.lang.Object
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) N/A
8 4 (object header: class) N/A
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
=== Point { int x; int y; }
HeaderDemo$Point object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) N/A
8 4 (object header: class) N/A
12 4 int Point.x N/A
16 4 int Point.y N/A
20 4 (object alignment gap)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
=== Order { long id; int quantity; boolean paid; String customer; }
HeaderDemo$Order object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) N/A
8 4 (object header: class) N/A
12 4 int Order.quantity N/A
16 8 long Order.id N/A
24 1 boolean Order.paid N/A
25 3 (alignment/padding gap)
28 4 java.lang.String Order.customer N/A
Instance size: 32 bytes
Space losses: 3 bytes internal + 0 bytes external = 3 bytes total
=== java.lang.Long and java.lang.Integer (boxed values)
java.lang.Long object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 4 (object header: class) 0x001a15d0
12 4 (alignment/padding gap)
16 8 long Long.value 123456789
Instance size: 24 bytes
Space losses: 4 bytes internal + 0 bytes external = 4 bytes total
java.lang.Integer object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 4 (object header: class) 0x0019f570
12 4 int Integer.value 123456
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
=== int[3]
[I object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 4 (object header: class) 0x00174360
12 4 (array length) 3
16 12 int [I.<elements> N/A
28 4 (object alignment gap)
Instance size: 32 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
=== What it adds up to: one million objects
1,000,000 boxed Integer values in an ArrayList : 20,861,992 bytes
1,000,000 boxed Long values in an ArrayList : 28,861,992 bytes
1,000,000 Point objects in an ArrayList : 28,861,992 bytes
+79
View File
@@ -0,0 +1,79 @@
java.version = 27
# WARNING: Unable to attach Serviceability Agent. sun.jvm.hotspot.runtime.VM.isCompressedKlassPointersEnabled()
# VM mode: 64 bits
# Lilliput VM detected (experimental)
# Compressed references (oops): 3-bit shift
# Compressed class pointers: 3-bit shift
# WARNING | Compressed references base/shifts are guessed by the experiment!
# WARNING | Therefore, computed addresses are just guesses, and ARE NOT RELIABLE.
# WARNING | Make sure to attach Serviceability Agent to get the reliable addresses.
# Object alignment: 8 bytes
# ref, bool, byte, char, shrt, int, flt, lng, dbl
# Field sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8
# Array base offsets: 12, 12, 12, 12, 12, 12, 12, 16, 16
=== java.lang.Object
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) N/A
Instance size: 8 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
=== Point { int x; int y; }
HeaderDemo$Point object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) N/A
8 4 int Point.x N/A
12 4 int Point.y N/A
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
=== Order { long id; int quantity; boolean paid; String customer; }
HeaderDemo$Order object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) N/A
8 8 long Order.id N/A
16 4 int Order.quantity N/A
20 1 boolean Order.paid N/A
21 3 (alignment/padding gap)
24 4 java.lang.String Order.customer N/A
28 4 (object alignment gap)
Instance size: 32 bytes
Space losses: 3 bytes internal + 4 bytes external = 7 bytes total
=== java.lang.Long and java.lang.Integer (boxed values)
java.lang.Long object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x001aa80000000001 (Lilliput)
8 8 long Long.value 123456789
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Integer object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x001a840000000001 (Lilliput)
8 4 int Integer.value 123456
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
=== int[3]
[I object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0017840000000001 (Lilliput)
8 4 (array length) 3
12 12 int [I.<elements> N/A
Instance size: 24 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
=== What it adds up to: one million objects
1,000,000 boxed Integer values in an ArrayList : 20,861,984 bytes
1,000,000 boxed Long values in an ArrayList : 20,861,984 bytes
1,000,000 Point objects in an ArrayList : 20,861,984 bytes
+86
View File
@@ -0,0 +1,86 @@
java.version = 27
# WARNING: Unable to attach Serviceability Agent. sun.jvm.hotspot.runtime.VM.isCompressedKlassPointersEnabled()
# VM mode: 64 bits
# Compressed references (oops): 3-bit shift
# Compressed class pointers: 3-bit shift
# WARNING | Compressed references base/shifts are guessed by the experiment!
# WARNING | Therefore, computed addresses are just guesses, and ARE NOT RELIABLE.
# WARNING | Make sure to attach Serviceability Agent to get the reliable addresses.
# Object alignment: 8 bytes
# ref, bool, byte, char, shrt, int, flt, lng, dbl
# Field sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8
# Array base offsets: 16, 16, 16, 16, 16, 16, 16, 16, 16
=== java.lang.Object
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) N/A
8 4 (object header: class) N/A
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
=== Point { int x; int y; }
HeaderDemo$Point object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) N/A
8 4 (object header: class) N/A
12 4 int Point.x N/A
16 4 int Point.y N/A
20 4 (object alignment gap)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
=== Order { long id; int quantity; boolean paid; String customer; }
HeaderDemo$Order object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) N/A
8 4 (object header: class) N/A
12 4 int Order.quantity N/A
16 8 long Order.id N/A
24 1 boolean Order.paid N/A
25 3 (alignment/padding gap)
28 4 java.lang.String Order.customer N/A
Instance size: 32 bytes
Space losses: 3 bytes internal + 0 bytes external = 3 bytes total
=== java.lang.Long and java.lang.Integer (boxed values)
java.lang.Long object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000009 (non-biasable; age: 1)
8 4 (object header: class) 0x001aa208
12 4 (alignment/padding gap)
16 8 long Long.value 123456789
Instance size: 24 bytes
Space losses: 4 bytes internal + 0 bytes external = 4 bytes total
java.lang.Integer object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 4 (object header: class) 0x001a7db8
12 4 int Integer.value 123456
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
=== int[3]
[I object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 4 (object header: class) 0x00176c00
12 4 (array length) 3
16 12 int [I.<elements> N/A
28 4 (object alignment gap)
Instance size: 32 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
=== What it adds up to: one million objects
1,000,000 boxed Integer values in an ArrayList : 20,861,992 bytes
1,000,000 boxed Long values in an ArrayList : 28,861,992 bytes
1,000,000 Point objects in an ArrayList : 28,861,992 bytes
+11
View File
@@ -0,0 +1,11 @@
# WARNING: Unable to attach Serviceability Agent. sun.jvm.hotspot.runtime.VM.isCompressedKlassPointersEnabled()
Exception in thread "main" java.lang.RuntimeException: Cannot get the field offset, try with -Djol.magicFieldOffset=true
at org.openjdk.jol.vm.HotspotUnsafe.fieldOffset(HotspotUnsafe.java:533)
at org.openjdk.jol.layouters.CurrentLayouter.layout(CurrentLayouter.java:70)
at org.openjdk.jol.info.ClassLayout.parseClass(ClassLayout.java:72)
at org.openjdk.jol.info.ClassLayout.parseClass(ClassLayout.java:56)
at RecordProbe.main(RecordProbe.java:12)
Caused by: java.lang.UnsupportedOperationException: can't get field offset on a record class: private final int RecordProbe$Coordinates.lat
at jdk.unsupported/sun.misc.Unsafe.objectFieldOffset(Unsafe.java:903)
at org.openjdk.jol.vm.HotspotUnsafe.fieldOffset(HotspotUnsafe.java:526)
... 4 more
+9
View File
@@ -0,0 +1,9 @@
# WARNING: Unable to attach Serviceability Agent. sun.jvm.hotspot.runtime.VM.isCompressedKlassPointersEnabled()
RecordProbe$Coordinates object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) N/A
8 4 int Coordinates.lat N/A
12 4 int Coordinates.lon N/A
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
+31
View File
@@ -0,0 +1,31 @@
# Instance sizes in bytes, extracted from 10-, 11- and 12- transcripts
--- 10-headers-jdk26
=== java.lang.Object -> Instance size: 16 bytes
=== Point { int x; int y; } -> Instance size: 24 bytes
=== Order { long id; int quantity; boolean paid; String customer; } -> Instance size: 32 bytes
=== java.lang.Long and java.lang.Integer (boxed values) -> Instance size: 24 bytes
=== java.lang.Long and java.lang.Integer (boxed values) -> Instance size: 16 bytes
=== int[3] -> Instance size: 32 bytes
1,000,000 boxed Integer values in an ArrayList : 20,861,992 bytes
1,000,000 boxed Long values in an ArrayList : 28,861,992 bytes
1,000,000 Point objects in an ArrayList : 28,861,992 bytes
--- 11-headers-jdk27
=== java.lang.Object -> Instance size: 8 bytes
=== Point { int x; int y; } -> Instance size: 16 bytes
=== Order { long id; int quantity; boolean paid; String customer; } -> Instance size: 32 bytes
=== java.lang.Long and java.lang.Integer (boxed values) -> Instance size: 16 bytes
=== java.lang.Long and java.lang.Integer (boxed values) -> Instance size: 16 bytes
=== int[3] -> Instance size: 24 bytes
1,000,000 boxed Integer values in an ArrayList : 20,861,984 bytes
1,000,000 boxed Long values in an ArrayList : 20,861,984 bytes
1,000,000 Point objects in an ArrayList : 20,861,984 bytes
--- 12-headers-jdk27-opt-out
=== java.lang.Object -> Instance size: 16 bytes
=== Point { int x; int y; } -> Instance size: 24 bytes
=== Order { long id; int quantity; boolean paid; String customer; } -> Instance size: 32 bytes
=== java.lang.Long and java.lang.Integer (boxed values) -> Instance size: 24 bytes
=== java.lang.Long and java.lang.Integer (boxed values) -> Instance size: 16 bytes
=== int[3] -> Instance size: 32 bytes
1,000,000 boxed Integer values in an ArrayList : 20,861,992 bytes
1,000,000 boxed Long values in an ArrayList : 28,861,992 bytes
1,000,000 Point objects in an ArrayList : 28,861,992 bytes
+6
View File
@@ -0,0 +1,6 @@
$ javac --enable-preview --release 27 Dominated.java (JDK 27)
Dominated.java:9: error: this case label is dominated by a preceding case label
case int primitive -> "an int"; // dominated: every Integer is already caught above
^
1 error
exit=1
+16
View File
@@ -0,0 +1,16 @@
$ javac --enable-preview --release 26 Lazy26.java (JDK 26)
exit=0
$ javac --enable-preview --release 27 Lazy26.java (JDK 27)
Lazy26.java:12: error: cannot find symbol
if (!GREETING.isInitialized()) {
^
symbol: method isInitialized()
location: variable GREETING of type LazyConstant<String>
Lazy26.java:13: error: cannot find symbol
System.out.println("not yet: " + GREETING.orElse("<unset>"));
^
symbol: method orElse(String)
location: variable GREETING of type LazyConstant<String>
2 errors
exit=1
+19
View File
@@ -0,0 +1,19 @@
$ javac --enable-preview --release 26 Pem26Style.java (JDK 26)
exit=0
$ javac --enable-preview --release 27 Pem26Style.java (JDK 27)
Pem26Style.java:1: error: cannot find symbol
import java.security.DEREncodable;
^
symbol: class DEREncodable
location: package java.security
Pem26Style.java:20: error: cannot find symbol
PEMDecoder viaProvider = PEMDecoder.of().withFactory(provider); // 2
^
symbol: method withFactory(Provider)
location: class PEMDecoder
Pem26Style.java:22: error: incompatible types: byte[] cannot be converted to String
String base64Text = pem.content(); // 3
^
3 errors
exit=1
@@ -0,0 +1,19 @@
$ javac --enable-preview --release 26 StructuredScope26.java (JDK 26)
exit=0
$ javac --enable-preview --release 27 StructuredScope26.java (JDK 27)
StructuredScope26.java:12: error: wrong number of type arguments; required 3
try (StructuredTaskScope<String, List<String>> scope =
^
StructuredScope26.java:17: error: cannot find symbol
} catch (StructuredTaskScope.FailedException e) {
^
symbol: class FailedException
location: interface StructuredTaskScope
StructuredScope26.java:19: error: cannot find symbol
} catch (StructuredTaskScope.TimeoutException e) {
^
symbol: class TimeoutException
location: interface StructuredTaskScope
3 errors
exit=1
+14
View File
@@ -0,0 +1,14 @@
$ java --enable-preview StructuredDemo (JDK 27)
--- allSuccessfulOrThrow(): results as a List, failures as ExecutionException
results = [price=42, stock=7]
CHECK ok : join() returns the subtask results in fork order
caught java.util.concurrent.ExecutionException with cause java.lang.IllegalStateException: inventory service is down
CHECK ok : a failing subtask surfaces as ExecutionException(cause)
--- allSuccessfulOrThrow(Function): join() throws the exception type you choose
caught OrderFailed: order failed: inventory service is down
CHECK ok : the mapped exception wraps the original failure
--- withTimeout(...): what happens when the scope runs out of time
caught java.util.concurrent.ExecutionException
cause: java.util.concurrent.StructuredTaskScope$CancelledByTimeoutException
CHECK ok : a timeout is reported as CancelledByTimeoutException
exit=0
+22
View File
@@ -0,0 +1,22 @@
$ java --enable-preview LazyDemo (JDK 27)
--- a lazy constant computes once, on first use
toString before first get(): jdk.internal.lang.LazyConstantImpl@...[computing function=LazyDemo$$Lambda/0x...@...]
(loading settings on main)
toString after first get(): jdk.internal.lang.LazyConstantImpl@...[Settings[region=ap-south-1, poolSize=16]]
CHECK ok : get() returns the same instance every time
CHECK ok : the supplier ran exactly once
--- and once even when 64 threads race for it
CHECK ok : 64 racing threads triggered exactly one initialisation
--- List.ofLazy: each element is computed on first access
computed so far: 0
squares.get(3) = square(3)=9
squares.get(3) = square(3)=9 (second read)
CHECK ok : only element 3 was ever computed
--- Map.ofLazy: the keys are fixed, the values are computed on first access
lengths.get("gamma") = 5
CHECK ok : only the requested key's value was computed
--- Set.ofLazy (new in 27): membership is decided by a predicate, on demand
primes.contains(7) = true, primes.contains(6) = false
CHECK ok : the lazy set answers membership using the predicate
primes = [2, 3, 5, 7]
exit=0
+28
View File
@@ -0,0 +1,28 @@
$ java --enable-preview PrimitivePatterns (JDK 27)
--- instanceof <primitive>: an exact-conversion test, not a cast
100 instanceof byte = true
300 instanceof byte = false (a byte holds -128..127)
CHECK ok : 100 converts to byte exactly, 300 does not
binding: byte narrow = 100
16_777_216 instanceof float = true
16_777_217 instanceof float = false (float has a 24-bit significand)
CHECK ok : int to float is exact up to 2^24 and lossy after
--- switch on a long, with pattern labels and a guard
classify(0) = zero
classify(1) = one
classify(-7) = negative (-7)
classify(9000000000) = positive (9000000000)
CHECK ok : long switch dispatches on constants, then patterns
--- switch on an Object: an Integer matches 'case int'
describe(Integer 7) = an int 7
describe(Integer 5000) = a large int 5000
describe(Long 7) = a long 7
describe(Double 2.5) = a double 2.5
describe(String hello) = a String of length 5
describe(Character x) = something else: x
CHECK ok : an Integer 5000 matches case int with a guard
--- record pattern with a narrowing primitive component
Reading[celsius=36] -> fits in a byte: 36
Reading[celsius=4000] -> needs a full int: 4000
CHECK ok : Reading(byte c) matches 36 but not 4000
exit=0
+29
View File
@@ -0,0 +1,29 @@
$ java --enable-preview PemDemo (JDK 27)
--- public key, encoded
-----BEGIN PUBLIC KEY----- ... -----END PUBLIC KEY-----
--- private key, encoded
-----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY-----
CHECK ok : a PublicKey encodes as BEGIN PUBLIC KEY
CHECK ok : a PrivateKey encodes as BEGIN PRIVATE KEY (PKCS#8)
CHECK ok : the decoded public key equals the original
CHECK ok : the decoded private key equals the original
--- decode(String) returns whatever the header says it is
-----BEGIN PUBLIC KEY----- -> PublicKey (EC)
-----BEGIN PRIVATE KEY----- -> PrivateKey (EC)
--- encrypted private key
-----BEGIN ENCRYPTED PRIVATE KEY-----
CHECK ok : withEncryption produces ENCRYPTED PRIVATE KEY
decoded with no password: javax.crypto.EncryptedPrivateKeyInfo
CHECK ok : without a password you get the still-encrypted structure back
CHECK ok : with the password you get the original private key
--- PEM(type, byte[]) does NOT Base64-encode: the bytes go in as they are
-----BEGIN ANKURM DEMO-----
hello, pem
-----END ANKURM DEMO-----
CHECK ok : raw bytes appear verbatim between the header and footer
--- give it the Base64 text and it round-trips
-----BEGIN ANKURM DEMO-----
aGVsbG8sIHBlbQ==
-----END ANKURM DEMO-----
CHECK ok : type, Base64 text (content()) and decoded payload (decode()) all survive
exit=0
+7
View File
@@ -0,0 +1,7 @@
$ java --add-modules jdk.incubator.vector VectorDemo (JDK 27)
java.version = 27
preferred species = Species[float, 16, S_512_BIT] (16 float lanes, machine dependent)
scalar dot = 749999.6
vector dot = 749999.6
CHECK ok : vector and scalar dot products agree to within 0.1%
exit=0
+21
View File
@@ -0,0 +1,21 @@
# Who talks to whom: the key-exchange group each pairing actually negotiates (TLS 1.3, loopback)
=== client JDK 26 -> server JDK 26
client offered : "named groups": [x25519, secp256r1, secp384r1, secp521r1, x448, ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192]
server selected: x25519
handshake complete: TLSv1.3 TLS_AES_256_GCM_SHA384
=== client JDK 27 -> server JDK 27
client offered : "named groups": [X25519MLKEM768, x25519, secp256r1, secp384r1, secp521r1, x448, ffdhe2048, ffdhe3072, ffdhe4096]
server selected: X25519MLKEM768
handshake complete: TLSv1.3 TLS_AES_256_GCM_SHA384
=== client JDK 27 -> server JDK 26
client offered : "named groups": [X25519MLKEM768, x25519, secp256r1, secp384r1, secp521r1, x448, ffdhe2048, ffdhe3072, ffdhe4096]
server selected: x25519
handshake complete: TLSv1.3 TLS_AES_256_GCM_SHA384
=== client JDK 26 -> server JDK 27
client offered : "named groups": [x25519, secp256r1, secp384r1, secp521r1, x448, ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192]
server selected: x25519
handshake complete: TLSv1.3 TLS_AES_256_GCM_SHA384
+19
View File
@@ -0,0 +1,19 @@
# Size of the first TLS record (the ClientHello) each JDK sends
=== JDK 26
java.version = 26.0.2.1
record type = 0x16 (0x16 = handshake)
ClientHello record = 417 bytes (+5 byte record header)
fits one TCP segment = yes (1460-byte MSS on a 1500-byte MTU)
=== JDK 27
java.version = 27
record type = 0x16 (0x16 = handshake)
ClientHello record = 1573 bytes (+5 byte record header)
fits one TCP segment = NO (1460-byte MSS on a 1500-byte MTU)
=== JDK 27 with -Djdk.tls.namedGroups=x25519,secp256r1 (post-quantum group removed)
java.version = 27
record type = 0x16 (0x16 = handshake)
ClientHello record = 408 bytes (+5 byte record header)
fits one TCP segment = yes (1460-byte MSS on a 1500-byte MTU)
+6
View File
@@ -0,0 +1,6 @@
# Opting out on JDK 27: a client that does not offer the hybrid group
=== client JDK 27 with -Djdk.tls.namedGroups=x25519,secp256r1 -> server JDK 27
client offered : "named groups": [x25519, secp256r1]
server selected: x25519
handshake complete: TLSv1.3 TLS_AES_256_GCM_SHA384
+41
View File
@@ -0,0 +1,41 @@
# The process under test: java -Dapi.token=abc123 -Dregion=ap-south-1 ... Idle --password=hunter2 --user=ankur
# with DB_PASSWORD=hunter2 in the environment. Which of those values reach the recording?
=== jdk26-default
jvmArguments = "-Dapi.token=abc123 -Dregion=ap-south-1 -XX:StartFlightRecording:filename=<file>"
javaArguments = "Idle --password=hunter2 --user=ankur"
key = "region" value = "ap-south-1"
key = "api.token" value = "abc123"
key = "DB_PASSWORD" value = "hunter2"
=== jdk27-default
jvmArguments = "[REDACTED] -Dregion=ap-south-1 -XX:StartFlightRecording:filename=<file>"
javaArguments = "Idle [REDACTED] --user=ankur"
key = "region" value = "ap-south-1"
key = "api.token" value = "[REDACTED]"
key = "DB_PASSWORD" value = "[REDACTED]"
=== jdk27-own-list-replaces-defaults
-XX:FlightRecorderOptions:redact-argument=--user*,redact-key=region
jvmArguments = "-Dapi.token=abc123 -Dregion=[REDACTED] -XX:FlightRecorderOptions:redact-argument=[REDACTED],redact-key=region -XX:StartFlightRecording:filename=<file>"
javaArguments = "Idle --password=hunter2 [REDACTED]"
key = "region" value = "[REDACTED]"
key = "api.token" value = "abc123"
key = "DB_PASSWORD" value = "hunter2"
=== jdk27-plus-extends-defaults
-XX:FlightRecorderOptions:redact-argument=+--user*,redact-key=+region
jvmArguments = "[REDACTED] -Dregion=[REDACTED] -XX:FlightRecorderOptions:redact-argument=[REDACTED],redact-key=+region -XX:StartFlightRecording:filename=<file>"
javaArguments = "Idle [REDACTED] [REDACTED]"
key = "region" value = "[REDACTED]"
key = "api.token" value = "[REDACTED]"
key = "DB_PASSWORD" value = "[REDACTED]"
=== jdk27-none-disables-redaction
-XX:FlightRecorderOptions:redact-argument=none,redact-key=none
jvmArguments = "-Dapi.token=abc123 -Dregion=ap-south-1 -XX:FlightRecorderOptions:redact-argument=[REDACTED],redact-key=none -XX:StartFlightRecording:filename=<file>"
javaArguments = "Idle --password=hunter2 --user=ankur"
key = "region" value = "ap-south-1"
key = "api.token" value = "abc123"
key = "DB_PASSWORD" value = "hunter2"
+8
View File
@@ -0,0 +1,8 @@
# jdk.incubator.vector: what changed between 26 and 27 (JEP 529 was the 11th incubation in 26, JEP 537 is the 12th in 27)
## public classes removed
## public classes added
## public class changes
jdk.incubator.vector.VectorOperators
- public abstract class jdk.incubator.vector.VectorOperators {
+ public final class jdk.incubator.vector.VectorOperators {
+190
View File
@@ -0,0 +1,190 @@
# Public API removed/added/changed between JDK 26 and 27 (javap -public of every exported class; internal packages skipped)
## public classes removed
java.security.DEREncodable
java.util.concurrent.StructuredTaskScope$FailedException
java.util.concurrent.StructuredTaskScope$TimeoutException
## public classes added
com.sun.source.tree.VarTypeTree
java.security.BinaryEncodable
java.time.format.DateTimeFormatterPatternProvider
java.util.concurrent.StructuredTaskScope$CancelledByTimeoutException
javax.crypto.CryptoException
## public class changes
com.sun.source.tree.Tree$Kind
+ public static final com.sun.source.tree.Tree$Kind VAR_TYPE;
com.sun.source.tree.TreeVisitor
+ public abstract R visitVarType(com.sun.source.tree.VarTypeTree, P);
com.sun.source.util.DocSourcePositions
- public abstract long getEndPosition(com.sun.source.tree.CompilationUnitTree, com.sun.source.doctree.DocCommentTree, com.sun.source.doctree.DocTree);
- public abstract long getStartPosition(com.sun.source.tree.CompilationUnitTree, com.sun.source.doctree.DocCommentTree, com.sun.source.doctree.DocTree);
+ public abstract long getEndPosition(com.sun.source.doctree.DocCommentTree, com.sun.source.doctree.DocTree);
+ public abstract long getStartPosition(com.sun.source.doctree.DocCommentTree, com.sun.source.doctree.DocTree);
+ public default long getEndPosition(com.sun.source.tree.CompilationUnitTree, com.sun.source.doctree.DocCommentTree, com.sun.source.doctree.DocTree);
+ public default long getStartPosition(com.sun.source.tree.CompilationUnitTree, com.sun.source.doctree.DocCommentTree, com.sun.source.doctree.DocTree);
com.sun.source.util.SimpleTreeVisitor
+ public R visitVarType(com.sun.source.tree.VarTypeTree, P);
com.sun.source.util.SourcePositions
- public abstract long getEndPosition(com.sun.source.tree.CompilationUnitTree, com.sun.source.tree.Tree);
- public abstract long getStartPosition(com.sun.source.tree.CompilationUnitTree, com.sun.source.tree.Tree);
+ public abstract long getEndPosition(com.sun.source.tree.Tree);
+ public abstract long getStartPosition(com.sun.source.tree.Tree);
+ public default long getEndPosition(com.sun.source.tree.CompilationUnitTree, com.sun.source.tree.Tree);
+ public default long getStartPosition(com.sun.source.tree.CompilationUnitTree, com.sun.source.tree.Tree);
com.sun.source.util.TreeScanner
+ public R visitVarType(com.sun.source.tree.VarTypeTree, P);
java.awt.KeyboardFocusManager
- public static java.awt.KeyboardFocusManager getCurrentKeyboardFocusManager();
+ public static synchronized java.awt.KeyboardFocusManager getCurrentKeyboardFocusManager();
java.awt.geom.Arc2D
+ public java.awt.Rectangle getBounds();
java.lang.LazyConstant
- public abstract T orElse(T);
- public abstract boolean isInitialized();
java.lang.Math
+ public static double acosh(double);
+ public static double asinh(double);
+ public static double atanh(double);
java.lang.StrictMath
+ public static double acosh(double);
+ public static double asinh(double);
+ public static double atanh(double);
java.lang.String
+ public int encodedLength(java.nio.charset.Charset);
java.lang.classfile.ClassFile
+ public static final int JAVA_27_VERSION;
java.lang.classfile.instruction.IncrementInstruction
+ public static java.lang.classfile.instruction.IncrementInstruction of(java.lang.classfile.Opcode, int, int);
java.lang.foreign.MemorySegment
+ public abstract java.lang.String getString(long, java.nio.charset.Charset, long);
+ public static long copy(java.lang.String, java.nio.charset.Charset, int, java.lang.foreign.MemorySegment, long, int);
java.lang.foreign.SegmentAllocator
+ public default java.lang.foreign.MemorySegment allocateFrom(java.lang.String, java.nio.charset.Charset, int, int);
java.lang.reflect.ClassFileFormatVersion
+ public static final java.lang.reflect.ClassFileFormatVersion RELEASE_27;
java.lang.reflect.Executable
- public abstract java.lang.String toGenericString();
+ public java.lang.String toGenericString();
java.math.BigDecimal
+ public java.math.BigDecimal rootn(int, java.math.MathContext);
java.security.AsymmetricKey
- public interface java.security.AsymmetricKey extends java.security.Key,java.security.DEREncodable {
+ public interface java.security.AsymmetricKey extends java.security.Key,java.security.BinaryEncodable {
java.security.KeyPair
- public final class java.security.KeyPair implements java.io.Serializable,java.security.DEREncodable {
+ public final class java.security.KeyPair implements java.io.Serializable,java.security.BinaryEncodable {
java.security.KeyStore
+ public final java.time.Instant getCreationInstant(java.lang.String) throws java.security.KeyStoreException;
java.security.KeyStoreSpi
+ public java.time.Instant engineGetCreationInstant(java.lang.String);
java.security.PEM
- public final class java.security.PEM extends java.lang.Record implements java.security.DEREncodable {
+ public final class java.security.PEM implements java.security.BinaryEncodable {
- public final boolean equals(java.lang.Object);
- public final byte[] decode();
- public final int hashCode();
- public final java.lang.String toString();
- public java.lang.String content();
+ public byte[] content();
+ public byte[] decode();
+ public java.lang.String toString();
+ public java.security.PEM(java.lang.String, byte[]);
+ public java.security.PEM(java.lang.String, byte[], byte[]);
java.security.PEMDecoder
- public <S extends java.security.DEREncodable> S decode(java.io.InputStream, java.lang.Class<S>) throws java.io.IOException;
- public <S extends java.security.DEREncodable> S decode(java.lang.String, java.lang.Class<S>);
- public java.security.DEREncodable decode(java.io.InputStream) throws java.io.IOException;
- public java.security.DEREncodable decode(java.lang.String);
- public java.security.PEMDecoder withFactory(java.security.Provider);
+ public <S extends java.security.BinaryEncodable> S decode(java.io.InputStream, java.lang.Class<S>) throws java.io.IOException;
+ public <S extends java.security.BinaryEncodable> S decode(java.lang.String, java.lang.Class<S>);
+ public java.security.BinaryEncodable decode(java.io.InputStream) throws java.io.IOException;
+ public java.security.BinaryEncodable decode(java.lang.String);
+ public java.security.PEMDecoder withFactoriesOf(java.security.Provider);
java.security.PEMEncoder
- public byte[] encode(java.security.DEREncodable);
- public java.lang.String encodeToString(java.security.DEREncodable);
+ public byte[] encode(java.security.BinaryEncodable);
+ public java.lang.String encodeToString(java.security.BinaryEncodable);
java.security.cert.X509CRL
- public abstract class java.security.cert.X509CRL extends java.security.cert.CRL implements java.security.cert.X509Extension,java.security.DEREncodable {
+ public abstract class java.security.cert.X509CRL extends java.security.cert.CRL implements java.security.cert.X509Extension,java.security.BinaryEncodable {
java.security.cert.X509Certificate
- public abstract class java.security.cert.X509Certificate extends java.security.cert.Certificate implements java.security.cert.X509Extension,java.security.DEREncodable {
+ public abstract class java.security.cert.X509Certificate extends java.security.cert.Certificate implements java.security.cert.X509Extension,java.security.BinaryEncodable {
java.security.spec.PKCS8EncodedKeySpec
- public class java.security.spec.PKCS8EncodedKeySpec extends java.security.spec.EncodedKeySpec implements java.security.DEREncodable {
+ public class java.security.spec.PKCS8EncodedKeySpec extends java.security.spec.EncodedKeySpec implements java.security.BinaryEncodable {
java.security.spec.X509EncodedKeySpec
- public class java.security.spec.X509EncodedKeySpec extends java.security.spec.EncodedKeySpec implements java.security.DEREncodable {
+ public class java.security.spec.X509EncodedKeySpec extends java.security.spec.EncodedKeySpec implements java.security.BinaryEncodable {
java.util.EnumSet
+ public java.util.Spliterator<E> spliterator();
java.util.Locale
- public final java.lang.String getDisplayCountry();
- public final java.lang.String getDisplayLanguage();
- public final java.lang.String getDisplayName();
- public final java.lang.String getDisplayVariant();
+ public java.lang.String getDisplayCountry();
+ public java.lang.String getDisplayLanguage();
+ public java.lang.String getDisplayName();
+ public java.lang.String getDisplayVariant();
java.util.Set
+ public static <E> java.util.Set<E> ofLazy(java.util.Set<? extends E>, java.util.function.Predicate<? super E>);
java.util.concurrent.StructuredTaskScope
- public interface java.util.concurrent.StructuredTaskScope<T, R> extends java.lang.AutoCloseable {
+ public interface java.util.concurrent.StructuredTaskScope<T, R, R_X extends java.lang.Throwable> extends java.lang.AutoCloseable {
- public abstract R join() throws java.lang.InterruptedException;
- public static <T, R> java.util.concurrent.StructuredTaskScope<T, R> open(java.util.concurrent.StructuredTaskScope$Joiner<? super T, ? extends R>);
- public static <T, R> java.util.concurrent.StructuredTaskScope<T, R> open(java.util.concurrent.StructuredTaskScope$Joiner<? super T, ? extends R>, java.util.function.UnaryOperator<java.util.concurrent.StructuredTaskScope$Configuration>);
- public static <T> java.util.concurrent.StructuredTaskScope<T, java.lang.Void> open();
+ public abstract R join() throws R_X, java.lang.InterruptedException;
+ public static <T, R, R_X extends java.lang.Throwable> java.util.concurrent.StructuredTaskScope<T, R, R_X> open(java.util.concurrent.StructuredTaskScope$Joiner<? super T, ? extends R, R_X>);
+ public static <T, R, R_X extends java.lang.Throwable> java.util.concurrent.StructuredTaskScope<T, R, R_X> open(java.util.concurrent.StructuredTaskScope$Joiner<? super T, ? extends R, R_X>, java.util.function.UnaryOperator<java.util.concurrent.StructuredTaskScope$Configuration>);
+ public static <T> java.util.concurrent.StructuredTaskScope<T, java.lang.Void, java.util.concurrent.ExecutionException> open();
+ public static <T> java.util.concurrent.StructuredTaskScope<T, java.lang.Void, java.util.concurrent.ExecutionException> open(java.util.function.UnaryOperator<java.util.concurrent.StructuredTaskScope$Configuration>);
java.util.concurrent.StructuredTaskScope$Joiner
- public interface java.util.concurrent.StructuredTaskScope$Joiner<T, R> {
+ public interface java.util.concurrent.StructuredTaskScope$Joiner<T, R, R_X extends java.lang.Throwable> {
- public abstract R result() throws java.lang.Throwable;
- public default void onTimeout();
- public static <T> java.util.concurrent.StructuredTaskScope$Joiner<T, T> anySuccessfulOrThrow();
- public static <T> java.util.concurrent.StructuredTaskScope$Joiner<T, java.lang.Void> awaitAll();
- public static <T> java.util.concurrent.StructuredTaskScope$Joiner<T, java.lang.Void> awaitAllSuccessfulOrThrow();
- public static <T> java.util.concurrent.StructuredTaskScope$Joiner<T, java.util.List<T>> allSuccessfulOrThrow();
- public static <T> java.util.concurrent.StructuredTaskScope$Joiner<T, java.util.List<java.util.concurrent.StructuredTaskScope$Subtask<T>>> allUntil(java.util.function.Predicate<java.util.concurrent.StructuredTaskScope$Subtask<T>>);
+ public abstract R result() throws R_X;
+ public abstract R timeout() throws R_X;
+ public static <T, R_X extends java.lang.Throwable> java.util.concurrent.StructuredTaskScope$Joiner<T, T, R_X> anySuccessfulOrThrow(java.util.function.Function<java.lang.Throwable, R_X>);
+ public static <T, R_X extends java.lang.Throwable> java.util.concurrent.StructuredTaskScope$Joiner<T, java.lang.Void, R_X> awaitAllSuccessfulOrThrow(java.util.function.Function<java.lang.Throwable, R_X>);
+ public static <T, R_X extends java.lang.Throwable> java.util.concurrent.StructuredTaskScope$Joiner<T, java.util.List<T>, R_X> allSuccessfulOrThrow(java.util.function.Function<java.lang.Throwable, R_X>);
+ public static <T> java.util.concurrent.StructuredTaskScope$Joiner<T, T, java.util.concurrent.ExecutionException> anySuccessfulOrThrow();
+ public static <T> java.util.concurrent.StructuredTaskScope$Joiner<T, java.lang.Void, java.util.concurrent.ExecutionException> awaitAllSuccessfulOrThrow();
+ public static <T> java.util.concurrent.StructuredTaskScope$Joiner<T, java.util.List<T>, java.util.concurrent.ExecutionException> allSuccessfulOrThrow();
+ public static <T> java.util.concurrent.StructuredTaskScope$Joiner<T, java.util.List<java.util.concurrent.StructuredTaskScope$Subtask<T>>, java.lang.RuntimeException> allUntil(java.util.function.Predicate<? super java.util.concurrent.StructuredTaskScope$Subtask<T>>);
javax.crypto.EncryptedPrivateKeyInfo
- public class javax.crypto.EncryptedPrivateKeyInfo implements java.security.DEREncodable {
+ public class javax.crypto.EncryptedPrivateKeyInfo implements java.security.BinaryEncodable {
- public java.security.KeyPair getKeyPair(java.security.Key, java.security.Provider) throws java.security.NoSuchAlgorithmException, java.security.InvalidKeyException;
- public java.security.PrivateKey getKey(java.security.Key, java.security.Provider) throws java.security.NoSuchAlgorithmException, java.security.InvalidKeyException;
- public static javax.crypto.EncryptedPrivateKeyInfo encrypt(java.security.DEREncodable, char[]);
- public static javax.crypto.EncryptedPrivateKeyInfo encrypt(java.security.DEREncodable, char[], java.lang.String, java.security.spec.AlgorithmParameterSpec, java.security.Provider);
- public static javax.crypto.EncryptedPrivateKeyInfo encrypt(java.security.DEREncodable, java.security.Key, java.lang.String, java.security.spec.AlgorithmParameterSpec, java.security.Provider, java.security.SecureRandom);
+ public java.security.KeyPair getKeyPair(java.security.Key) throws java.security.NoSuchAlgorithmException, java.security.InvalidKeyException;
+ public java.security.PrivateKey getKey(java.security.Key) throws java.security.NoSuchAlgorithmException, java.security.InvalidKeyException;
+ public static javax.crypto.EncryptedPrivateKeyInfo encrypt(java.security.BinaryEncodable, char[]);
+ public static javax.crypto.EncryptedPrivateKeyInfo encrypt(java.security.BinaryEncodable, char[], java.lang.String, java.security.spec.AlgorithmParameterSpec, java.security.Provider);
+ public static javax.crypto.EncryptedPrivateKeyInfo encrypt(java.security.BinaryEncodable, java.security.Key, java.lang.String, java.security.spec.AlgorithmParameterSpec, java.security.Provider, java.security.SecureRandom);
javax.lang.model.SourceVersion
+ public static final javax.lang.model.SourceVersion RELEASE_27;
javax.swing.JEditorPane$JEditorPaneAccessibleHypertextSupport
+ public void changedUpdate(javax.swing.event.DocumentEvent);
+ public void insertUpdate(javax.swing.event.DocumentEvent);
+ public void removeUpdate(javax.swing.event.DocumentEvent);
jdk.incubator.vector.VectorOperators
- public abstract class jdk.incubator.vector.VectorOperators {
+ public final class jdk.incubator.vector.VectorOperators {
jdk.javadoc.doclet.Taglet
+ public default java.lang.String toString(java.util.List<? extends com.sun.source.doctree.DocTree>, javax.lang.model.element.Element, java.net.URI);
jdk.jfr.events.ContainerMemoryUsageEvent
+ public long hostMemoryUsage;
+197
View File
@@ -0,0 +1,197 @@
# Public API removed/added/changed between JDK 25 and 26
## public classes removed
java.applet.Applet
java.applet.Applet$AccessibleApplet
java.applet.AppletContext
java.applet.AppletStub
java.applet.AudioClip
java.beans.AppletInitializer
java.lang.StableValue
java.security.PEMRecord
javax.management.modelmbean.XMLParseException
javax.swing.JApplet
javax.swing.JApplet$AccessibleJApplet
## public classes added
java.lang.LazyConstant
java.net.http.HttpOption
java.net.http.HttpOption$Http3DiscoveryMode
java.net.http.HttpResponse$PushPromiseHandler$PushId
java.net.http.HttpResponse$PushPromiseHandler$PushId$Http3PushId
java.net.http.StreamLimitException
java.net.http.UnsupportedProtocolVersionException
java.security.PEM
javax.crypto.spec.HPKEParameterSpec
jdk.jfr.events.FinalFieldMutationEvent
jdk.jshell.SourceCodeAnalysis$CompletionContext
jdk.jshell.SourceCodeAnalysis$CompletionState
jdk.jshell.SourceCodeAnalysis$ElementSuggestion
jdk.jshell.SourceCodeAnalysis$ElementSuggestionConvertor
## public class changes
com.sun.net.httpserver.HttpExchange
+ public static final long RSPBODY_CHUNKED;
+ public static final long RSPBODY_EMPTY;
java.awt.Robot
+ public static final int DEFAULT_DELAY;
+ public static final int DEFAULT_STEP_LENGTH;
+ public synchronized void type(char);
+ public synchronized void type(int);
+ public void click();
+ public void click(int);
+ public void glide(int, int);
+ public void glide(int, int, int, int);
+ public void glide(int, int, int, int, int, int);
+ public void waitForIdle(int);
java.beans.Beans
- public static java.lang.Object instantiate(java.lang.ClassLoader, java.lang.String, java.beans.beancontext.BeanContext, java.beans.AppletInitializer) throws java.io.IOException, java.lang.ClassNotFoundException;
java.lang.Character$UnicodeBlock
+ public static final java.lang.Character$UnicodeBlock BERIA_ERFE;
+ public static final java.lang.Character$UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_J;
+ public static final java.lang.Character$UnicodeBlock MISCELLANEOUS_SYMBOLS_SUPPLEMENT;
+ public static final java.lang.Character$UnicodeBlock SHARADA_SUPPLEMENT;
+ public static final java.lang.Character$UnicodeBlock SIDETIC;
+ public static final java.lang.Character$UnicodeBlock TAI_YO;
+ public static final java.lang.Character$UnicodeBlock TANGUT_COMPONENTS_SUPPLEMENT;
+ public static final java.lang.Character$UnicodeBlock TOLONG_SIKI;
java.lang.Character$UnicodeScript
+ public static final java.lang.Character$UnicodeScript BERIA_ERFE;
+ public static final java.lang.Character$UnicodeScript SIDETIC;
+ public static final java.lang.Character$UnicodeScript TAI_YO;
+ public static final java.lang.Character$UnicodeScript TOLONG_SIKI;
java.lang.Process
- public abstract class java.lang.Process {
+ public abstract class java.lang.Process implements java.io.Closeable {
+ public void close() throws java.io.IOException;
java.lang.String
+ public boolean equalsFoldCase(java.lang.String);
+ public int compareToFoldCase(java.lang.String);
+ public static final java.util.Comparator<java.lang.String> UNICODE_CASEFOLD_ORDER;
java.lang.Thread
- public final void stop();
java.lang.classfile.ClassFile
+ public static final int JAVA_26_VERSION;
java.lang.management.MemoryMXBean
+ public default long getTotalGcCpuTime();
java.lang.reflect.ClassFileFormatVersion
+ public static final java.lang.reflect.ClassFileFormatVersion RELEASE_26;
java.math.BigInteger
+ public java.math.BigInteger rootn(int);
+ public java.math.BigInteger[] rootnAndRemainder(int);
java.net.MulticastSocket
- public byte getTTL() throws java.io.IOException;
- public void send(java.net.DatagramPacket, byte) throws java.io.IOException;
- public void setTTL(byte) throws java.io.IOException;
java.net.http.HttpClient$Version
+ public static final java.net.http.HttpClient$Version HTTP_3;
java.net.http.HttpRequest
+ public <T> java.util.Optional<T> getOption(java.net.http.HttpOption<T>);
java.net.http.HttpRequest$BodyPublishers
+ public static java.net.http.HttpRequest$BodyPublisher ofFileChannel(java.nio.channels.FileChannel, long, long) throws java.io.IOException;
java.net.http.HttpRequest$Builder
+ public default <T> java.net.http.HttpRequest$Builder setOption(java.net.http.HttpOption<T>, T);
java.net.http.HttpResponse$PushPromiseHandler
+ public default void applyPushPromise(java.net.http.HttpRequest, java.net.http.HttpRequest, java.net.http.HttpResponse$PushPromiseHandler$PushId, java.util.function.Function<java.net.http.HttpResponse$BodyHandler<T>, java.util.concurrent.CompletableFuture<java.net.http.HttpResponse<T>>>);
+ public default void notifyAdditionalPromise(java.net.http.HttpRequest, java.net.http.HttpResponse$PushPromiseHandler$PushId);
java.nio.ByteOrder
- public final class java.nio.ByteOrder {
+ public final class java.nio.ByteOrder extends java.lang.Enum<java.nio.ByteOrder> {
- public java.lang.String toString();
+ public static java.nio.ByteOrder valueOf(java.lang.String);
+ public static java.nio.ByteOrder[] values();
java.security.SecureRandom
+ public long nextLong();
java.sql.Array
- public interface java.sql.Array {
+ public interface java.sql.Array extends java.lang.AutoCloseable {
+ public default void close() throws java.sql.SQLException;
java.sql.Blob
- public interface java.sql.Blob {
+ public interface java.sql.Blob extends java.lang.AutoCloseable {
+ public default void close() throws java.sql.SQLException;
java.sql.Clob
- public interface java.sql.Clob {
+ public interface java.sql.Clob extends java.lang.AutoCloseable {
+ public default void close() throws java.sql.SQLException;
java.sql.Connection
+ public default boolean isSimpleIdentifier(java.lang.String) throws java.sql.SQLException;
+ public default java.lang.String enquoteIdentifier(java.lang.String, boolean) throws java.sql.SQLException;
+ public default java.lang.String enquoteLiteral(java.lang.String) throws java.sql.SQLException;
+ public default java.lang.String enquoteNCharLiteral(java.lang.String) throws java.sql.SQLException;
java.sql.JDBCType
+ public static final java.sql.JDBCType DECFLOAT;
+ public static final java.sql.JDBCType JSON;
java.sql.SQLXML
- public interface java.sql.SQLXML {
+ public interface java.sql.SQLXML extends java.lang.AutoCloseable {
+ public default void close() throws java.sql.SQLException;
java.sql.Types
+ public static final int DECFLOAT;
+ public static final int JSON;
java.time.Duration
+ public static final java.time.Duration MAX;
+ public static final java.time.Duration MIN;
java.time.Instant
+ public java.time.Instant plusSaturating(java.time.Duration);
java.util.Comparator
+ public default <U extends T> U max(U, U);
+ public default <U extends T> U min(U, U);
java.util.List
+ public static <E> java.util.List<E> ofLazy(int, java.util.function.IntFunction<? extends E>);
java.util.Locale$IsoCountryCode
- public abstract class java.util.Locale$IsoCountryCode extends java.lang.Enum<java.util.Locale$IsoCountryCode> {
+ public final class java.util.Locale$IsoCountryCode extends java.lang.Enum<java.util.Locale$IsoCountryCode> {
java.util.Map
+ public static <K, V> java.util.Map<K, V> ofLazy(java.util.Set<? extends K>, java.util.function.Function<? super K, ? extends V>);
java.util.UUID
+ public static java.util.UUID ofEpochMillis(long);
java.util.concurrent.StructuredTaskScope
- public static <T, R> java.util.concurrent.StructuredTaskScope<T, R> open(java.util.concurrent.StructuredTaskScope$Joiner<? super T, ? extends R>, java.util.function.Function<java.util.concurrent.StructuredTaskScope$Configuration, java.util.concurrent.StructuredTaskScope$Configuration>);
+ public static <T, R> java.util.concurrent.StructuredTaskScope<T, R> open(java.util.concurrent.StructuredTaskScope$Joiner<? super T, ? extends R>, java.util.function.UnaryOperator<java.util.concurrent.StructuredTaskScope$Configuration>);
java.util.concurrent.StructuredTaskScope$Joiner
- public default boolean onComplete(java.util.concurrent.StructuredTaskScope$Subtask<? extends T>);
- public default boolean onFork(java.util.concurrent.StructuredTaskScope$Subtask<? extends T>);
- public static <T> java.util.concurrent.StructuredTaskScope$Joiner<T, T> anySuccessfulResultOrThrow();
- public static <T> java.util.concurrent.StructuredTaskScope$Joiner<T, java.util.stream.Stream<java.util.concurrent.StructuredTaskScope$Subtask<T>>> allSuccessfulOrThrow();
- public static <T> java.util.concurrent.StructuredTaskScope$Joiner<T, java.util.stream.Stream<java.util.concurrent.StructuredTaskScope$Subtask<T>>> allUntil(java.util.function.Predicate<java.util.concurrent.StructuredTaskScope$Subtask<? extends T>>);
+ public default boolean onComplete(java.util.concurrent.StructuredTaskScope$Subtask<T>);
+ public default boolean onFork(java.util.concurrent.StructuredTaskScope$Subtask<T>);
+ public default void onTimeout();
+ public static <T> java.util.concurrent.StructuredTaskScope$Joiner<T, T> anySuccessfulOrThrow();
+ public static <T> java.util.concurrent.StructuredTaskScope$Joiner<T, java.util.List<T>> allSuccessfulOrThrow();
+ public static <T> java.util.concurrent.StructuredTaskScope$Joiner<T, java.util.List<java.util.concurrent.StructuredTaskScope$Subtask<T>>> allUntil(java.util.function.Predicate<java.util.concurrent.StructuredTaskScope$Subtask<T>>);
java.util.concurrent.ThreadLocalRandom
+ public double nextGaussian();
javax.crypto.EncryptedPrivateKeyInfo
- public java.security.PrivateKey getKey(char[]) throws java.security.GeneralSecurityException;
- public java.security.PrivateKey getKey(java.security.Key, java.security.Provider) throws java.security.GeneralSecurityException;
- public static javax.crypto.EncryptedPrivateKeyInfo encryptKey(java.security.PrivateKey, char[]);
- public static javax.crypto.EncryptedPrivateKeyInfo encryptKey(java.security.PrivateKey, char[], java.lang.String, java.security.spec.AlgorithmParameterSpec, java.security.Provider);
- public static javax.crypto.EncryptedPrivateKeyInfo encryptKey(java.security.PrivateKey, java.security.Key, java.lang.String, java.security.spec.AlgorithmParameterSpec, java.security.Provider, java.security.SecureRandom);
+ public java.security.KeyPair getKeyPair(char[]) throws java.security.NoSuchAlgorithmException, java.security.InvalidKeyException;
+ public java.security.KeyPair getKeyPair(java.security.Key, java.security.Provider) throws java.security.NoSuchAlgorithmException, java.security.InvalidKeyException;
+ public java.security.PrivateKey getKey(char[]) throws java.security.NoSuchAlgorithmException, java.security.InvalidKeyException;
+ public java.security.PrivateKey getKey(java.security.Key, java.security.Provider) throws java.security.NoSuchAlgorithmException, java.security.InvalidKeyException;
+ public static javax.crypto.EncryptedPrivateKeyInfo encrypt(java.security.DEREncodable, char[]);
+ public static javax.crypto.EncryptedPrivateKeyInfo encrypt(java.security.DEREncodable, char[], java.lang.String, java.security.spec.AlgorithmParameterSpec, java.security.Provider);
+ public static javax.crypto.EncryptedPrivateKeyInfo encrypt(java.security.DEREncodable, java.security.Key, java.lang.String, java.security.spec.AlgorithmParameterSpec, java.security.Provider, java.security.SecureRandom);
javax.imageio.spi.ServiceRegistry
- public void finalize() throws java.lang.Throwable;
javax.lang.model.SourceVersion
+ public static final javax.lang.model.SourceVersion RELEASE_26;
javax.management.modelmbean.DescriptorSupport
- public javax.management.modelmbean.DescriptorSupport(java.lang.String) throws javax.management.MBeanException, javax.management.RuntimeOperationsException, javax.management.modelmbean.XMLParseException;
- public synchronized java.lang.String toXMLString();
javax.swing.RepaintManager
- public void addDirtyRegion(java.applet.Applet, int, int, int, int);
jdk.incubator.vector.VectorOperators
- public static final jdk.incubator.vector.VectorOperators$Binary SUADD;
+ public static final jdk.incubator.vector.VectorOperators$Associative SUADD;
jdk.jpackage.main.Main
- public int execute(java.io.PrintWriter, java.io.PrintWriter, java.lang.String...);
- public static final java.util.ResourceBundle I18N;
- public static void main(java.lang.String...) throws java.lang.Exception;
+ public static void main(java.lang.String...);
jdk.jshell.SourceCodeAnalysis
+ public abstract <S> java.util.List<S> completionSuggestions(java.lang.String, int, jdk.jshell.SourceCodeAnalysis$ElementSuggestionConvertor<S>);
jdk.jshell.SourceCodeAnalysis$Documentation
+ public default int activeParameterIndex();
+54
View File
@@ -0,0 +1,54 @@
# JVM options that JDK 27 removed or renamed. Each runs 'java <option> -version' on 26 and on 27.
=== -noverify
JDK 26:
OpenJDK 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release.
OpenJDK 64-Bit Server VM Corretto-26.0.2.11.1 (build 26.0.2.1+11-FR, mixed mode, sharing)
JDK 27:
Unrecognized option: -noverify
Error: Could not create the Java Virtual Machine.
=== -Xverify:none
JDK 26:
OpenJDK 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release.
OpenJDK 64-Bit Server VM Corretto-26.0.2.11.1 (build 26.0.2.1+11-FR, mixed mode, sharing)
JDK 27:
Unrecognized verification option: -Xverify:none
Error: Could not create the Java Virtual Machine.
=== -noclassgc
JDK 26:
Warning: -noclassgc option is deprecated and may be removed in a future release.
OpenJDK 64-Bit Server VM Corretto-26.0.2.11.1 (build 26.0.2.1+11-FR, mixed mode, sharing)
JDK 27:
Unrecognized option: -noclassgc
Error: Could not create the Java Virtual Machine.
=== -XX:+UseCompressedClassPointers
JDK 26:
OpenJDK 64-Bit Server VM warning: Option UseCompressedClassPointers was deprecated in version 25.0 and will likely be removed in a future release.
OpenJDK 64-Bit Server VM Corretto-26.0.2.11.1 (build 26.0.2.1+11-FR, mixed mode, sharing)
JDK 27:
OpenJDK 64-Bit Server VM warning: Ignoring option UseCompressedClassPointers; support was removed in 27.0
OpenJDK 64-Bit Server VM Corretto-27.0.0.35.1 (build 27+35-FR, mixed mode, sharing)
=== -XX:InitiatingHeapOccupancyPercent=40
JDK 26:
OpenJDK 64-Bit Server VM Corretto-26.0.2.11.1 (build 26.0.2.1+11-FR, mixed mode, sharing)
JDK 27:
OpenJDK 64-Bit Server VM warning: Option InitiatingHeapOccupancyPercent was deprecated in version 27.0 and will likely be removed in a future release. Use option G1IHOP instead.
OpenJDK 64-Bit Server VM Corretto-27.0.0.35.1 (build 27+35-FR, mixed mode, sharing)
=== -XX:G1IHOP=40
JDK 26:
Unrecognized VM option 'G1IHOP=40'
Error: Could not create the Java Virtual Machine.
JDK 27:
OpenJDK 64-Bit Server VM Corretto-27.0.0.35.1 (build 27+35-FR, mixed mode, sharing)
=== -XX:+UnlockExperimentalVMOptions -XX:+UseGraalJIT (JVMCI and the Graal JIT hook were removed in 27)
JDK 26:
Cannot use JVMCI compiler: JVMCI compiler 'graal' specified by jvmci.Compiler not found
JDK 27:
Unrecognized VM option 'UseGraalJIT'
Error: Could not create the Java Virtual Machine.
+21
View File
@@ -0,0 +1,21 @@
# Behaviour changes that need no new API to observe
=== a script that pins the VFORK process launch mechanism
JDK 26: java -Djdk.lang.Process.launchMechanism=VFORK SpawnProbe
VFORK MODE DEPRECATED
The VFORK launch mechanism has been deprecated for being dangerous.
It will be removed in a future java version. Either remove the
JDK 27: java -Djdk.lang.Process.launchMechanism=VFORK SpawnProbe
The VFORK launch mechanism has been removed. Switching to FORK instead.
Please remove the jdk.lang.Process.launchMechanism property (preferred)
or use FORK mode instead (-Djdk.lang.Process.launchMechanism=FORK).
=== the legacy ISO 639 language codes property (iw, ji, in)
JDK 26: java -Djava.locale.useOldISOCodes=true Compat
java.version = 26.0.2.1
WARNING: The use of the system property "java.locale.useOldISOCodes" is deprecated. It will be removed in a future release of the JDK.
Locale("iw").language = iw (Hebrew; old code 'iw', current code 'he')
JDK 27: java -Djava.locale.useOldISOCodes=true Compat
java.version = 27
WARNING: The system property "java.locale.useOldISOCodes" is no longer supported. Any specified value will be ignored.
Locale("iw").language = he (Hebrew; old code 'iw', current code 'he')
+12
View File
@@ -0,0 +1,12 @@
# New public API in 27, each exercised once (found by diffing javap dumps, see 51-api-diff-26-to-27.txt)
Math.acosh(2) = 1.316958
Math.asinh(1) = 0.881374
Math.atanh(.5) = 0.549306
CHECK ok : acosh inverts cosh
"naïve café".length() = 10, encodedLength(UTF_8) = 12
CHECK ok : encodedLength matches getBytes().length without allocating the array
BigDecimal(27).rootn(3) = 3
CHECK ok : rootn(3) of 27 is 3
KeyStore.getCreationInstant("aes-key") returns an Instant: true
CHECK ok : KeyStore.getCreationInstant returns the entry's creation time as a java.time.Instant
CHECK ok : Set.ofLazy(Set, Predicate) exists (preview API)
+45
View File
@@ -0,0 +1,45 @@
# JEP 500: reflection writing to a final field, same class file behaviour on 25 and on 26
=== JDK 25 (class compiled --release 25)
field reads : 9090
port() returns : 8080
=== JDK 26, defaults
WARNING: Final field port in class FinalFieldMutation$Config has been mutated reflectively by class FinalFieldMutation in unnamed module @<hash> (file:<repo>/build/recap26/26/)
WARNING: Use --enable-final-field-mutation=ALL-UNNAMED to avoid a warning
WARNING: Mutating final fields will be blocked in a future release unless final field mutation is enabled
field reads : 9090
port() returns : 8080
=== JDK 26, --enable-final-field-mutation=ALL-UNNAMED (the opt-in the warning asks for)
field reads : 9090
port() returns : 8080
=== JDK 26, --illegal-final-field-mutation=deny (what a future default will look like)
setInt refused : class FinalFieldMutation (in unnamed module @<hash>) cannot set final field FinalFieldMutation$Config.port (in unnamed module @<hash>), unnamed module @<hash> is not allowed to mutate final fields
=== JDK 26, --illegal-final-field-mutation=debug (warning plus the offending stack trace)
Final field port in class FinalFieldMutation$Config has been mutated reflectively by class FinalFieldMutation in unnamed module @<hash> (file:<repo>/build/recap26/26/)
at java.base/java.lang.reflect.Field.postSetFinal(Field.java:1534)
at java.base/java.lang.reflect.Field.setFinal(Field.java:1449)
at java.base/java.lang.reflect.Field.setInt(Field.java:1134)
at FinalFieldMutation.main(FinalFieldMutation.java:22)
field reads : 9090
port() returns : 8080
=== JDK 26, JFR default settings, [no flag]: jfr print --events jdk.FinalFieldMutation
jdk.FinalFieldMutation
declaringClass = FinalFieldMutation$Config (classLoader = app)
fieldName = "port"
FinalFieldMutation.main(String[]) line: 22
events recorded: 1
=== JDK 26, JFR default settings, [--enable-final-field-mutation=ALL-UNNAMED]: jfr print --events jdk.FinalFieldMutation
jdk.FinalFieldMutation
declaringClass = FinalFieldMutation$Config (classLoader = app)
fieldName = "port"
FinalFieldMutation.main(String[]) line: 22
events recorded: 1
=== JDK 26, JFR default settings, [--illegal-final-field-mutation=deny]: jfr print --events jdk.FinalFieldMutation
events recorded: 0
+20
View File
@@ -0,0 +1,20 @@
# JEP 516: can the cache's archived heap objects be used? One row per (JDK, GC the cache was built under, GC at run time).
# 'heap objects' = the log says the archived module graph was used; 'unusable' = the JVM refused the whole cache.
JDK 25 cache built under G1 run under Serial -> heap objects used (full module graph: enabled)
JDK 25 cache built under G1 run under G1 -> heap objects used (full module graph: enabled)
JDK 25 cache built under G1 run under Z -> unusable: saved state of UseCompressedOops and UseCompressedClassPointers is different from runtime
JDK 25 cache built under Z run under Serial -> unusable: saved state of UseCompressedOops and UseCompressedClassPointers is different from runtime
JDK 25 cache built under Z run under G1 -> unusable: saved state of UseCompressedOops and UseCompressedClassPointers is different from runtime
JDK 25 cache built under Z run under Z -> cache used, heap objects NOT used (full module graph: disabled)
JDK 26 cache built under G1 run under Serial -> heap objects used (full module graph: enabled)
JDK 26 cache built under G1 run under G1 -> heap objects used (full module graph: enabled)
JDK 26 cache built under G1 run under Z -> unusable: saved state of UseCompressedOops and UseCompressedClassPointers is different from runtime
JDK 26 cache built under Z run under Serial -> unusable: saved state of UseCompressedOops and UseCompressedClassPointers is different from runtime
JDK 26 cache built under Z run under G1 -> unusable: saved state of UseCompressedOops and UseCompressedClassPointers is different from runtime
JDK 26 cache built under Z run under Z -> heap objects used (full module graph: enabled)
JDK 27 cache built under G1 run under Serial -> heap objects used (full module graph: enabled)
JDK 27 cache built under G1 run under G1 -> heap objects used (full module graph: enabled)
JDK 27 cache built under G1 run under Z -> unusable: saved state of UseCompressedOops (1) is different from runtime (0)
JDK 27 cache built under Z run under Serial -> unusable: saved state of UseCompressedOops (0) is different from runtime (1)
JDK 27 cache built under Z run under G1 -> unusable: saved state of UseCompressedOops (0) is different from runtime (1)
JDK 27 cache built under Z run under Z -> heap objects used (full module graph: enabled)
+7
View File
@@ -0,0 +1,7 @@
# Wall-clock ms for 'java -cp app.jar AotApp' (median of 9), no AOT cache vs cache built under the same GC. INDICATIVE: shared 2-CPU sandbox.
JDK 25 G1 no cache: 57 ms with cache: 37 ms
JDK 25 Z no cache: 83 ms with cache: 81 ms
JDK 26 G1 no cache: 59 ms with cache: 35 ms
JDK 26 Z no cache: 62 ms with cache: 40 ms
JDK 27 G1 no cache: 61 ms with cache: 36 ms
JDK 27 Z no cache: 63 ms with cache: 38 ms
+34
View File
@@ -0,0 +1,34 @@
# Source that compiled on 25 and does not on 26
=== recap26/src/broken/AppletGone.java
javac (JDK 25, --release 25): exit 0
<repo>/recap26/src/broken/AppletGone.java:5: warning: [removal] Applet in java.applet has been deprecated and marked for removal
public class AppletGone extends Applet {
^
1 warning
javac (JDK 26, --release 26): exit 1
<repo>/recap26/src/broken/AppletGone.java:3: error: package java.applet does not exist
import java.applet.Applet;
^
<repo>/recap26/src/broken/AppletGone.java:5: error: cannot find symbol
public class AppletGone extends Applet {
^
symbol: class Applet
<repo>/recap26/src/broken/AppletGone.java:6: error: init() in AppletGone does not override or implement a method from a supertype
@Override public void init() { System.out.println("applet init"); }
^
3 errors
=== recap26/src/broken/ThreadStopGone.java
javac (JDK 25, --release 25): exit 0
<repo>/recap26/src/broken/ThreadStopGone.java:5: warning: [removal] stop() in Thread has been deprecated and marked for removal
t.stop();
^
1 warning
javac (JDK 26, --release 26): exit 1
<repo>/recap26/src/broken/ThreadStopGone.java:5: error: cannot find symbol
t.stop();
^
symbol: method stop()
location: variable t of type Thread
1 error
+12
View File
@@ -0,0 +1,12 @@
CHECK ok : "STRASSE".equalsFoldCase("stra" + sharp s + "e") is true (full case folding)
CHECK ok : equalsIgnoreCase says false for the same pair (simple folding only)
CHECK ok : "apple".compareToFoldCase("BANANA") < 0
CHECK ok : sorted with String.UNICODE_CASEFOLD_ORDER: [A, b, B, c]
CHECK ok : UUID.ofEpochMillis(..).version() == 7
CHECK ok : the first 48 bits are the timestamp: 018bcfe5-6800-...
CHECK ok : try-with-resources on Process (implements Closeable in 26)
CHECK ok : MemoryMXBean.getTotalGcCpuTime() exists and is non-negative
CHECK ok : ByteOrder is an enum: [LITTLE_ENDIAN, BIG_ENDIAN]
CHECK ok : HttpClient.Version.HTTP_3 exists and is accepted by the builder
CHECK ok : Character.UnicodeBlock.SIDETIC exists (Unicode 17)
exit code: 0
+26
View File
@@ -0,0 +1,26 @@
# JEP 517: a client that prefers HTTP/3 against a server that only speaks HTTP/1.1 over TLS (loopback, JDK's own HttpsServer)
# There is no live HTTP/3 server in this transcript: the sandbox has no UDP egress. The API surface is javap output below.
client asked for : HTTP_3
server answered : HTTP_1_1 200 hello
HTTP_3_URI_ONLY : java.net.http.HttpConnectTimeoutException: quic handshake timeout
# javap --module java.net.http -public java.net.http.HttpOption 'java.net.http.HttpOption$Http3DiscoveryMode'
Compiled from "HttpOption.java"
public interface java.net.http.HttpOption<T> {
public static final java.net.http.HttpOption<java.net.http.HttpOption$Http3DiscoveryMode> H3_DISCOVERY;
public abstract java.lang.String name();
public abstract java.lang.Class<T> type();
}
Compiled from "HttpOption.java"
public final class java.net.http.HttpOption$Http3DiscoveryMode extends java.lang.Enum<java.net.http.HttpOption$Http3DiscoveryMode> {
public static final java.net.http.HttpOption$Http3DiscoveryMode ANY;
public static final java.net.http.HttpOption$Http3DiscoveryMode ALT_SVC;
public static final java.net.http.HttpOption$Http3DiscoveryMode HTTP_3_URI_ONLY;
public static java.net.http.HttpOption$Http3DiscoveryMode[] values();
public static java.net.http.HttpOption$Http3DiscoveryMode valueOf(java.lang.String);
}
# javap ... HttpClient$Version
public static final java.net.http.HttpClient$Version HTTP_1_1;
public static final java.net.http.HttpClient$Version HTTP_2;
public static final java.net.http.HttpClient$Version HTTP_3;
+69
View File
@@ -0,0 +1,69 @@
# One class file (javac 21 --release 21), four JVMs
$ java -cp hub HubExamples (JDK 21)
java.version = 21.0.12.1
CHECK ok : record accessor: c.email()
CHECK ok : record toString: Customer[id=1, [email protected], country=IN]
CHECK ok : compact constructor rejects an email without @: Invalid email
CHECK ok : area(Square(3)) == 9.0
CHECK ok : area(Triangle(4, 5)) == 10.0
CHECK ok : guard pattern: Circle(101) is a large circle
CHECK ok : guard pattern: Circle(1) is a small circle
CHECK ok : all 10,000 virtual-thread tasks completed before close() returned
CHECK ok : and it took seconds, not the 1,000 s a serial loop needs (exact time is machine dependent, not printed)
CHECK ok : Thread.ofVirtual().name(..).start(..) gives a virtual thread
CHECK ok : List.getFirst() / getLast()
CHECK ok : List.reversed(): [chris, brian, alex]
CHECK ok : reversed() is a view, not a copy: it sees the element added afterwards
CHECK ok : LinkedHashSet.getFirst() == 3, getLast() == 5
$ java -cp hub HubExamples (JDK 25)
java.version = 25.0.4.1
CHECK ok : record accessor: c.email()
CHECK ok : record toString: Customer[id=1, [email protected], country=IN]
CHECK ok : compact constructor rejects an email without @: Invalid email
CHECK ok : area(Square(3)) == 9.0
CHECK ok : area(Triangle(4, 5)) == 10.0
CHECK ok : guard pattern: Circle(101) is a large circle
CHECK ok : guard pattern: Circle(1) is a small circle
CHECK ok : all 10,000 virtual-thread tasks completed before close() returned
CHECK ok : and it took seconds, not the 1,000 s a serial loop needs (exact time is machine dependent, not printed)
CHECK ok : Thread.ofVirtual().name(..).start(..) gives a virtual thread
CHECK ok : List.getFirst() / getLast()
CHECK ok : List.reversed(): [chris, brian, alex]
CHECK ok : reversed() is a view, not a copy: it sees the element added afterwards
CHECK ok : LinkedHashSet.getFirst() == 3, getLast() == 5
$ java -cp hub HubExamples (JDK 26)
java.version = 26.0.2.1
CHECK ok : record accessor: c.email()
CHECK ok : record toString: Customer[id=1, [email protected], country=IN]
CHECK ok : compact constructor rejects an email without @: Invalid email
CHECK ok : area(Square(3)) == 9.0
CHECK ok : area(Triangle(4, 5)) == 10.0
CHECK ok : guard pattern: Circle(101) is a large circle
CHECK ok : guard pattern: Circle(1) is a small circle
CHECK ok : all 10,000 virtual-thread tasks completed before close() returned
CHECK ok : and it took seconds, not the 1,000 s a serial loop needs (exact time is machine dependent, not printed)
CHECK ok : Thread.ofVirtual().name(..).start(..) gives a virtual thread
CHECK ok : List.getFirst() / getLast()
CHECK ok : List.reversed(): [chris, brian, alex]
CHECK ok : reversed() is a view, not a copy: it sees the element added afterwards
CHECK ok : LinkedHashSet.getFirst() == 3, getLast() == 5
$ java -cp hub HubExamples (JDK 27)
java.version = 27
CHECK ok : record accessor: c.email()
CHECK ok : record toString: Customer[id=1, [email protected], country=IN]
CHECK ok : compact constructor rejects an email without @: Invalid email
CHECK ok : area(Square(3)) == 9.0
CHECK ok : area(Triangle(4, 5)) == 10.0
CHECK ok : guard pattern: Circle(101) is a large circle
CHECK ok : guard pattern: Circle(1) is a small circle
CHECK ok : all 10,000 virtual-thread tasks completed before close() returned
CHECK ok : and it took seconds, not the 1,000 s a serial loop needs (exact time is machine dependent, not printed)
CHECK ok : Thread.ofVirtual().name(..).start(..) gives a virtual thread
CHECK ok : List.getFirst() / getLast()
CHECK ok : List.reversed(): [chris, brian, alex]
CHECK ok : reversed() is a view, not a copy: it sees the element added afterwards
CHECK ok : LinkedHashSet.getFirst() == 3, getLast() == 5
+41
View File
@@ -0,0 +1,41 @@
# ScopedValue (JEP 506). Preview API in 21, final in 25.
$ javac ScopedValueDemo.java (JDK 21, no flag)
<repo>/lanes/src/ScopedValueDemo.java:9: error: ScopedValue is a preview API and is disabled by default.
static final ScopedValue<String> CURRENT_USER = ScopedValue.newInstance();
^
(use --enable-preview to enable preview APIs)
<repo>/lanes/src/ScopedValueDemo.java:9: error: ScopedValue is a preview API and is disabled by default.
static final ScopedValue<String> CURRENT_USER = ScopedValue.newInstance();
^
(use --enable-preview to enable preview APIs)
<repo>/lanes/src/ScopedValueDemo.java:13: error: ScopedValue is a preview API and is disabled by default.
ScopedValue.where(CURRENT_USER, "ankur").run(() -> {
^
(use --enable-preview to enable preview APIs)
3 errors
exit=1
$ javac ScopedValueDemo.java (JDK 25, no flag)
exit=0
$ java ScopedValueDemo (JDK 25)
java.version = 25.0.4.1
CHECK ok : inside the scope: CURRENT_USER.get() == ankur
CHECK ok : a method that was never passed the value still sees it
CHECK ok : outside the scope: CURRENT_USER.get() throws NoSuchElementException
$ javac ScopedValueDemo.java (JDK 26, no flag)
exit=0
$ java ScopedValueDemo (JDK 26)
java.version = 26.0.2.1
CHECK ok : inside the scope: CURRENT_USER.get() == ankur
CHECK ok : a method that was never passed the value still sees it
CHECK ok : outside the scope: CURRENT_USER.get() throws NoSuchElementException
$ javac ScopedValueDemo.java (JDK 27, no flag)
exit=0
$ java ScopedValueDemo (JDK 27)
java.version = 27
CHECK ok : inside the scope: CURRENT_USER.get() == ankur
CHECK ok : a method that was never passed the value still sees it
CHECK ok : outside the scope: CURRENT_USER.get() throws NoSuchElementException
+117
View File
@@ -0,0 +1,117 @@
# StructuredTaskScope (JEP 505 in 25). Fifth preview in 25, sixth in 26, seventh in 27.
$ javac StructuredHub.java (JDK 25, no flag)
<repo>/lanes/src/StructuredHub.java:1: error: StructuredTaskScope is a preview API and is disabled by default.
import java.util.concurrent.StructuredTaskScope;
^
(use --enable-preview to enable preview APIs)
<repo>/lanes/src/StructuredHub.java:15: error: StructuredTaskScope is a preview API and is disabled by default.
try (var scope = StructuredTaskScope.open()) {
^
(use --enable-preview to enable preview APIs)
<repo>/lanes/src/StructuredHub.java:24: error: StructuredTaskScope is a preview API and is disabled by default.
try (var scope = StructuredTaskScope.open(StructuredTaskScope.Joiner.<String>anySuccessfulResultOrThrow())) {
^
(use --enable-preview to enable preview APIs)
<repo>/lanes/src/StructuredHub.java:24: error: Joiner is a preview API and is disabled by default.
try (var scope = StructuredTaskScope.open(StructuredTaskScope.Joiner.<String>anySuccessfulResultOrThrow())) {
^
(use --enable-preview to enable preview APIs)
<repo>/lanes/src/StructuredHub.java:24: error: StructuredTaskScope is a preview API and is disabled by default.
try (var scope = StructuredTaskScope.open(StructuredTaskScope.Joiner.<String>anySuccessfulResultOrThrow())) {
^
(use --enable-preview to enable preview APIs)
5 errors
exit=1
$ javac --enable-preview --release 25 StructuredHub.java (JDK 25)
exit=0
$ java --enable-preview StructuredHub (JDK 25)
java.version = 25.0.4.1
CHECK ok : fan-out: both results joined: Dashboard[user=user-7, order=order-for-7]
CHECK ok : anySuccessfulResultOrThrow(): the first result wins and the slow subtask is cancelled
$ javac StructuredHub.java (JDK 26, no flag)
<repo>/lanes/src/StructuredHub.java:1: error: StructuredTaskScope is a preview API and is disabled by default.
import java.util.concurrent.StructuredTaskScope;
^
(use --enable-preview to enable preview APIs)
<repo>/lanes/src/StructuredHub.java:15: error: StructuredTaskScope is a preview API and is disabled by default.
try (var scope = StructuredTaskScope.open()) {
^
(use --enable-preview to enable preview APIs)
<repo>/lanes/src/StructuredHub.java:24: error: StructuredTaskScope is a preview API and is disabled by default.
try (var scope = StructuredTaskScope.open(StructuredTaskScope.Joiner.<String>anySuccessfulResultOrThrow())) {
^
(use --enable-preview to enable preview APIs)
<repo>/lanes/src/StructuredHub.java:24: error: Joiner is a preview API and is disabled by default.
try (var scope = StructuredTaskScope.open(StructuredTaskScope.Joiner.<String>anySuccessfulResultOrThrow())) {
^
(use --enable-preview to enable preview APIs)
<repo>/lanes/src/StructuredHub.java:24: error: cannot find symbol
try (var scope = StructuredTaskScope.open(StructuredTaskScope.Joiner.<String>anySuccessfulResultOrThrow())) {
^
symbol: method <String>anySuccessfulResultOrThrow()
location: interface Joiner
<repo>/lanes/src/StructuredHub.java:24: error: StructuredTaskScope is a preview API and is disabled by default.
try (var scope = StructuredTaskScope.open(StructuredTaskScope.Joiner.<String>anySuccessfulResultOrThrow())) {
^
(use --enable-preview to enable preview APIs)
6 errors
exit=1
$ javac --enable-preview --release 26 StructuredHub.java (JDK 26)
<repo>/lanes/src/StructuredHub.java:24: error: cannot find symbol
try (var scope = StructuredTaskScope.open(StructuredTaskScope.Joiner.<String>anySuccessfulResultOrThrow())) {
^
symbol: method <String>anySuccessfulResultOrThrow()
location: interface Joiner
1 error
exit=1
$ javac StructuredHub.java (JDK 27, no flag)
<repo>/lanes/src/StructuredHub.java:1: error: StructuredTaskScope is a preview API and is disabled by default.
import java.util.concurrent.StructuredTaskScope;
^
(use --enable-preview to enable preview APIs)
<repo>/lanes/src/StructuredHub.java:15: error: StructuredTaskScope is a preview API and is disabled by default.
try (var scope = StructuredTaskScope.open()) {
^
(use --enable-preview to enable preview APIs)
<repo>/lanes/src/StructuredHub.java:24: error: StructuredTaskScope is a preview API and is disabled by default.
try (var scope = StructuredTaskScope.open(StructuredTaskScope.Joiner.<String>anySuccessfulResultOrThrow())) {
^
(use --enable-preview to enable preview APIs)
<repo>/lanes/src/StructuredHub.java:24: error: Joiner is a preview API and is disabled by default.
try (var scope = StructuredTaskScope.open(StructuredTaskScope.Joiner.<String>anySuccessfulResultOrThrow())) {
^
(use --enable-preview to enable preview APIs)
<repo>/lanes/src/StructuredHub.java:24: error: cannot find symbol
try (var scope = StructuredTaskScope.open(StructuredTaskScope.Joiner.<String>anySuccessfulResultOrThrow())) {
^
symbol: method <String>anySuccessfulResultOrThrow()
location: interface Joiner
<repo>/lanes/src/StructuredHub.java:24: error: StructuredTaskScope is a preview API and is disabled by default.
try (var scope = StructuredTaskScope.open(StructuredTaskScope.Joiner.<String>anySuccessfulResultOrThrow())) {
^
(use --enable-preview to enable preview APIs)
6 errors
exit=1
$ javac --enable-preview --release 27 StructuredHub.java (JDK 27)
<repo>/lanes/src/StructuredHub.java:24: error: cannot find symbol
try (var scope = StructuredTaskScope.open(StructuredTaskScope.Joiner.<String>anySuccessfulResultOrThrow())) {
^
symbol: method <String>anySuccessfulResultOrThrow()
location: interface Joiner
1 error
exit=1
$ javac --enable-preview --release 26 StructuredHubNew.java (JDK 26)
exit=0
$ java --enable-preview StructuredHubNew (JDK 26)
java.version = 26.0.2.1
CHECK ok : anySuccessfulOrThrow(): the first result wins
$ javac --enable-preview --release 27 StructuredHubNew.java (JDK 27)
exit=0
$ java --enable-preview StructuredHubNew (JDK 27)
java.version = 27
CHECK ok : anySuccessfulOrThrow(): the first result wins
+29
View File
@@ -0,0 +1,29 @@
# Is finalization removed by default in 25? (JEP 421 deprecated it for removal in 18)
$ java FinalizerDefault (JDK 21)
java.version = 21.0.12.1
finalizer ran: true
$ java --finalization=disabled FinalizerDefault (JDK 21)
java.version = 21.0.12.1
finalizer ran: false
$ java FinalizerDefault (JDK 25)
java.version = 25.0.4.1
finalizer ran: true
$ java --finalization=disabled FinalizerDefault (JDK 25)
java.version = 25.0.4.1
finalizer ran: false
$ java FinalizerDefault (JDK 26)
java.version = 26.0.2.1
finalizer ran: true
$ java --finalization=disabled FinalizerDefault (JDK 26)
java.version = 26.0.2.1
finalizer ran: false
$ java FinalizerDefault (JDK 27)
java.version = 27
finalizer ran: true
$ java --finalization=disabled FinalizerDefault (JDK 27)
java.version = 27
finalizer ran: false
+9
View File
@@ -0,0 +1,9 @@
# System.setSecurityManager(new SecurityManager())
$ java SecurityManagerGone (JDK 21)
java.version = 21.0.12.1
setSecurityManager: UnsupportedOperationException: The Security Manager is deprecated and will be removed in a future release
$ java SecurityManagerGone (JDK 25)
java.version = 25.0.4.1
setSecurityManager: UnsupportedOperationException: Setting a Security Manager is not supported
+68
View File
@@ -0,0 +1,68 @@
# Thread.stop(), suspend(), resume(): when did they actually go?
$ java ThreadStopRuntime (JDK 21)
java.version = 21.0.12.1
Thread.stop(): UnsupportedOperationException
$ java ThreadStopRuntime (JDK 25)
java.version = 25.0.4.1
Thread.stop(): UnsupportedOperationException
$ javac ThreadSuspendGone.java (JDK 21)
exit=0
$ javac ThreadSuspendGone.java (JDK 25)
<repo>/lanes/src/ThreadSuspendGone.java:8: error: cannot find symbol
t.suspend();
^
symbol: method suspend()
location: variable t of type Thread
<repo>/lanes/src/ThreadSuspendGone.java:9: error: cannot find symbol
t.resume();
^
symbol: method resume()
location: variable t of type Thread
2 errors
exit=1
$ javac ThreadSuspendGone.java (JDK 26)
<repo>/lanes/src/ThreadSuspendGone.java:8: error: cannot find symbol
t.suspend();
^
symbol: method suspend()
location: variable t of type Thread
<repo>/lanes/src/ThreadSuspendGone.java:9: error: cannot find symbol
t.resume();
^
symbol: method resume()
location: variable t of type Thread
2 errors
exit=1
$ javac ThreadSuspendGone.java (JDK 23, Corretto image)
/src/ThreadSuspendGone.java:8: error: cannot find symbol
t.suspend();
^
symbol: method suspend()
location: variable t of type Thread
/src/ThreadSuspendGone.java:9: error: cannot find symbol
t.resume();
^
symbol: method resume()
location: variable t of type Thread
2 errors
exit=1
$ javac ThreadSuspendGone.java (JDK 24, Corretto image)
/src/ThreadSuspendGone.java:8: error: cannot find symbol
t.suspend();
^
symbol: method suspend()
location: variable t of type Thread
/src/ThreadSuspendGone.java:9: error: cannot find symbol
t.resume();
^
symbol: method resume()
location: variable t of type Thread
2 errors
exit=1
+49
View File
@@ -0,0 +1,49 @@
# sun.misc.Unsafe memory access (JEP 498) and JNI (JEP 472): what does the JVM say?
$ java UnsafeWarning (JDK 21)
java.version = 21.0.12.1
read back: 42
$ java UnsafeWarning (JDK 25)
java.version = 25.0.4.1
WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
WARNING: sun.misc.Unsafe::allocateMemory has been called by UnsafeWarning (file:<repo>/build/lanes/us25/)
WARNING: Please consider reporting this to the maintainers of class UnsafeWarning
WARNING: sun.misc.Unsafe::allocateMemory will be removed in a future release
read back: 42
$ java UnsafeWarning (JDK 24, Corretto image)
java.version = 24.0.2
WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
WARNING: sun.misc.Unsafe::allocateMemory has been called by UnsafeWarning (file:/b/us21/)
WARNING: Please consider reporting this to the maintainers of class UnsafeWarning
WARNING: sun.misc.Unsafe::allocateMemory will be removed in a future release
read back: 42
$ java JniWarning (JDK 21)
java.version = 21.0.12.1
System.loadLibrary("net") returned
$ java --enable-native-access=ALL-UNNAMED JniWarning (JDK 21)
java.version = 21.0.12.1
System.loadLibrary("net") returned
$ java JniWarning (JDK 25)
java.version = 25.0.4.1
WARNING: A restricted method in java.lang.System has been called
WARNING: java.lang.System::loadLibrary has been called by JniWarning in an unnamed module (file:<repo>/build/lanes/jni25/)
WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module
WARNING: Restricted methods will be blocked in a future release unless native access is enabled
System.loadLibrary("net") returned
$ java --enable-native-access=ALL-UNNAMED JniWarning (JDK 25)
java.version = 25.0.4.1
System.loadLibrary("net") returned
$ java JniWarning (JDK 24, Corretto image)
java.version = 24.0.2
System.loadLibrary("net") returned
WARNING: A restricted method in java.lang.System has been called
WARNING: java.lang.System::loadLibrary has been called by JniWarning in an unnamed module (file:/b/jni21/)
WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module
WARNING: Restricted methods will be blocked in a future release unless native access is enabled
+25
View File
@@ -0,0 +1,25 @@
# 4 virtual threads on ONE carrier, each sleeping 200 ms inside synchronized (JEP 491, Java 24)
$ java -Djdk.virtualThreadScheduler.parallelism=1 -Djdk.virtualThreadScheduler.maxPoolSize=1 PinningDemo (JDK 21)
java.version = 21.0.12.1
4 virtual threads, 1 carrier, sleep(200) inside synchronized: SERIALISED (pinned): about 4 x 200 ms
$ java -Djdk.virtualThreadScheduler.parallelism=1 -Djdk.virtualThreadScheduler.maxPoolSize=1 PinningDemo (JDK 25)
java.version = 25.0.4.1
4 virtual threads, 1 carrier, sleep(200) inside synchronized: OVERLAPPED (not pinned): about 200 ms
$ java -Djdk.virtualThreadScheduler.parallelism=1 -Djdk.virtualThreadScheduler.maxPoolSize=1 PinningDemo (JDK 26)
java.version = 26.0.2.1
4 virtual threads, 1 carrier, sleep(200) inside synchronized: OVERLAPPED (not pinned): about 200 ms
$ java -Djdk.virtualThreadScheduler.parallelism=1 -Djdk.virtualThreadScheduler.maxPoolSize=1 PinningDemo (JDK 27)
java.version = 27
4 virtual threads, 1 carrier, sleep(200) inside synchronized: OVERLAPPED (not pinned): about 200 ms
$ java -Djdk.virtualThreadScheduler.parallelism=1 -Djdk.virtualThreadScheduler.maxPoolSize=1 PinningDemo (JDK 23, Corretto image)
java.version = 23.0.2
4 virtual threads, 1 carrier, sleep(200) inside synchronized: SERIALISED (pinned): about 4 x 200 ms
$ java -Djdk.virtualThreadScheduler.parallelism=1 -Djdk.virtualThreadScheduler.maxPoolSize=1 PinningDemo (JDK 24, Corretto image)
java.version = 24.0.2
4 virtual threads, 1 carrier, sleep(200) inside synchronized: OVERLAPPED (not pinned): about 200 ms
+26
View File
@@ -0,0 +1,26 @@
# -XX:+UseZGC -XX:-ZGenerational -Xlog:gc+init -version : generational ZGC is the only ZGC from Java 24 (JEP 490)
$ java -XX:+UseZGC -XX:-ZGenerational -Xlog:gc+init -version (JDK 21)
[0.004s][info][gc,init] Version: 21.0.12.1+9-LTS (release)
[0.004s][info][gc,init] Using legacy single-generation mode
$ java -XX:+UseZGC -XX:-ZGenerational -Xlog:gc+init -version (JDK 25)
OpenJDK 64-Bit Server VM warning: Ignoring option ZGenerational; support was removed in 24.0
[0.004s][info][gc,init] Version: 25.0.4.1+1-LTS (release)
$ java -XX:+UseZGC -XX:-ZGenerational -Xlog:gc+init -version (JDK 26)
Unrecognized VM option 'ZGenerational'
Error: Could not create the Java Virtual Machine.
$ java -XX:+UseZGC -XX:-ZGenerational -Xlog:gc+init -version (JDK 27)
Unrecognized VM option 'ZGenerational'
Error: Could not create the Java Virtual Machine.
$ java -XX:+UseZGC -XX:-ZGenerational -Xlog:gc+init -version (JDK 23, Corretto image)
OpenJDK 64-Bit Server VM warning: Option ZGenerational was deprecated in version 23.0 and will likely be removed in a future release.
[0.004s][info][gc,init] Version: 23.0.2+7-FR (release)
[0.004s][info][gc,init] Using deprecated non-generational mode
$ java -XX:+UseZGC -XX:-ZGenerational -Xlog:gc+init -version (JDK 24, Corretto image)
OpenJDK 64-Bit Server VM warning: Ignoring option ZGenerational; support was removed in 24.0
[0.005s][info][gc,init] Version: 24.0.2+12-FR (release)
+24
View File
@@ -0,0 +1,24 @@
# javap --module java.base -public 'java.util.concurrent.StructuredTaskScope$Joiner', static factories only
== JDK 25
public static <T> StructuredTaskScope$Joiner<T, Stream<StructuredTaskScope$Subtask<T>>> allSuccessfulOrThrow();
public static <T> StructuredTaskScope$Joiner<T, T> anySuccessfulResultOrThrow();
public static <T> StructuredTaskScope$Joiner<T, Void> awaitAllSuccessfulOrThrow();
public static <T> StructuredTaskScope$Joiner<T, Void> awaitAll();
public static <T> StructuredTaskScope$Joiner<T, Stream<StructuredTaskScope$Subtask<T>>> allUntil(Predicate<StructuredTaskScope$Subtask<? extends T>>);
== JDK 26
public static <T> StructuredTaskScope$Joiner<T, List<T>> allSuccessfulOrThrow();
public static <T> StructuredTaskScope$Joiner<T, T> anySuccessfulOrThrow();
public static <T> StructuredTaskScope$Joiner<T, Void> awaitAllSuccessfulOrThrow();
public static <T> StructuredTaskScope$Joiner<T, Void> awaitAll();
public static <T> StructuredTaskScope$Joiner<T, List<StructuredTaskScope$Subtask<T>>> allUntil(Predicate<StructuredTaskScope$Subtask<T>>);
== JDK 27
public static <T, R_X extends Throwable> StructuredTaskScope$Joiner<T, List<T>, R_X> allSuccessfulOrThrow(Function<Throwable, R_X>);
public static <T> StructuredTaskScope$Joiner<T, List<T>, ExecutionException> allSuccessfulOrThrow();
public static <T, R_X extends Throwable> StructuredTaskScope$Joiner<T, T, R_X> anySuccessfulOrThrow(Function<Throwable, R_X>);
public static <T> StructuredTaskScope$Joiner<T, T, ExecutionException> anySuccessfulOrThrow();
public static <T, R_X extends Throwable> StructuredTaskScope$Joiner<T, Void, R_X> awaitAllSuccessfulOrThrow(Function<Throwable, R_X>);
public static <T> StructuredTaskScope$Joiner<T, Void, ExecutionException> awaitAllSuccessfulOrThrow();
public static <T> StructuredTaskScope$Joiner<T, List<StructuredTaskScope$Subtask<T>>, RuntimeException> allUntil(Predicate<? super StructuredTaskScope$Subtask<T>>);
+26
View File
@@ -0,0 +1,26 @@
# _ (unnamed variables and patterns) and compact source files with instance main()
$ javac UnnamedVariables.java (JDK 21, no flag)
<repo>/lanes/src/UnnamedVariables.java:12: error: unnamed variables are a preview feature and are disabled by default.
if (o instanceof Point(int x, _)) {
^
(use --enable-preview to enable unnamed variables)
1 error
exit=1
$ javac UnnamedVariables.java (JDK 25, no flag)
exit=0
$ java UnnamedVariables (JDK 25)
matched a Point, x = 3, y ignored with _
caught NumberFormatException without naming it
$ java CompactHello.java (JDK 21, no flag)
<repo>/lanes/src/CompactHello.java:1: error: unnamed classes are a preview feature and are disabled by default.
void main() {
^
(use --enable-preview to enable unnamed classes)
1 error
error: compilation failed
$ java CompactHello.java (JDK 25, no flag)
compact source file: no class, no static, no String[] args
@@ -0,0 +1,11 @@
# Reflection writing to a final field on JDK 27: same behaviour as 26 (compare 70-final-field-mutation.txt)
=== JDK 27, defaults
WARNING: Final field port in class FinalFieldMutation$Config has been mutated reflectively by class FinalFieldMutation in unnamed module @<hash> (file:<repo>/build/lanes/ffm27/)
WARNING: Use --enable-final-field-mutation=ALL-UNNAMED to avoid a warning
WARNING: Mutating final fields will be blocked in a future release unless final field mutation is enabled
field reads : 9090
port() returns : 8080
=== JDK 27, --illegal-final-field-mutation=deny
setInt refused : class FinalFieldMutation (in unnamed module @<hash>) cannot set final field FinalFieldMutation$Config.port (in unnamed module @<hash>), unnamed module @<hash> is not allowed to mutate final fields
+40
View File
@@ -0,0 +1,40 @@
# pom.xml sets maven.compiler.source/target/release to 25 (lanes/upgrade/pom.xml)
$ mvn package (build JDK 21)
[INFO] --- resources:3.3.1:resources (default-resources) @ upgrade-demo ---
[INFO] --- compiler:3.13.0:compile (default-compile) @ upgrade-demo ---
[INFO] Compiling 1 source file with javac [debug release 25] to target/classes
[INFO] BUILD FAILURE
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.13.0:compile (default-compile) on project upgrade-demo: Fatal error compiling: error: release version 25 not supported -> [Help 1]
$ mvn package (build JDK 25)
[INFO] --- resources:3.3.1:resources (default-resources) @ upgrade-demo ---
[INFO] --- compiler:3.13.0:compile (default-compile) @ upgrade-demo ---
[INFO] Compiling 1 source file with javac [debug release 25] to target/classes
[INFO] --- resources:3.3.1:testResources (default-testResources) @ upgrade-demo ---
[INFO] --- compiler:3.13.0:testCompile (default-testCompile) @ upgrade-demo ---
[INFO] --- surefire:3.2.5:test (default-test) @ upgrade-demo ---
[INFO] --- jar:3.4.1:jar (default-jar) @ upgrade-demo ---
[INFO] Building jar: <repo>/build/upgrade/mvn25/target/upgrade-demo-1.0.jar
[INFO] BUILD SUCCESS
$ mvn package (build JDK 27, still release 25)
[INFO] --- resources:3.3.1:resources (default-resources) @ upgrade-demo ---
[INFO] --- compiler:3.13.0:compile (default-compile) @ upgrade-demo ---
[INFO] Compiling 1 source file with javac [debug release 25] to target/classes
[INFO] --- resources:3.3.1:testResources (default-testResources) @ upgrade-demo ---
[INFO] --- compiler:3.13.0:testCompile (default-testCompile) @ upgrade-demo ---
[INFO] --- surefire:3.2.5:test (default-test) @ upgrade-demo ---
[INFO] --- jar:3.4.1:jar (default-jar) @ upgrade-demo ---
[INFO] Building jar: <repo>/build/upgrade/mvn27/target/upgrade-demo-1.0.jar
[INFO] BUILD SUCCESS
$ javap -v -cp target/classes demo.App | grep 'major version'
major version: 69
$ java -cp target/classes demo.App (JDK 25)
running on Java 25
$ java -cp target/classes demo.App (JDK 21: the class file is newer than the JVM)
Error: LinkageError occurred while loading main class demo.App
java.lang.UnsupportedClassVersionError: demo/App has been compiled by a more recent version of the Java Runtime (class file version 69.0), this version of the Java Runtime only recognizes class file versions up to 65.0
+12
View File
@@ -0,0 +1,12 @@
# build.gradle.kts asks for a Java 25 toolchain (lanes/upgrade/build.gradle.kts). Two questions: which JDK compiles, and which JDK runs Gradle itself?
$ gradle run (Gradle 8.14.3 running on JDK 21, toolchain finds JDK 25)
running on Java 25
$ gradle run (Gradle 8.14.3 running on JDK 25)
FAILURE: Build failed with an exception.
* What went wrong:
25.0.4.1
$ gradle run (Gradle 9.1.0 running on JDK 25)
running on Java 25
+24
View File
@@ -0,0 +1,24 @@
# ReleaseFlag.java calls String.equalsFoldCase, which is new in Java 26. The compiler is JDK 27's javac both times.
$ javac --release 25 ReleaseFlag.java
<repo>/lanes/src/ReleaseFlag.java:8: error: cannot find symbol
System.out.println("ABC".equalsFoldCase("abc"));
^
symbol: method equalsFoldCase(String)
location: class String
1 error
exit=1
$ javac -source 25 -target 25 ReleaseFlag.java
warning: [options] location of system modules is not set in conjunction with -source 25
not setting the location of system modules may lead to class files that cannot run on JDK 25
--release 25 is recommended instead of -source 25 -target 25 because it sets the location of system modules automatically
1 warning
exit=0
$ java -cp rf-b ReleaseFlag (JDK 25)
Exception in thread "main" java.lang.NoSuchMethodError: 'boolean java.lang.String.equalsFoldCase(java.lang.String)'
at ReleaseFlag.main(ReleaseFlag.java:8)
$ java -cp rf-b ReleaseFlag (JDK 27)
true
+19
View File
@@ -0,0 +1,19 @@
# javac LombokProbe.java with -processorpath lombok-<version>.jar, then java LombokProbe. Class: @Getter on one field.
Lombok 1.18.34 on JDK 25: javac failed: java.lang.ExceptionInInitializerError
Lombok 1.18.34 on JDK 26: javac failed: java.lang.ExceptionInInitializerError
Lombok 1.18.34 on JDK 27: javac failed: java.lang.ExceptionInInitializerError
Lombok 1.18.40 on JDK 25: compiled; getName() = ankur
Lombok 1.18.40 on JDK 26: compiled; getName() = ankur
Lombok 1.18.40 on JDK 27: javac failed: java.lang.ExceptionInInitializerError
Lombok 1.18.46 on JDK 25: compiled; getName() = ankur
Lombok 1.18.46 on JDK 26: compiled; getName() = ankur
Lombok 1.18.46 on JDK 27: javac failed: java.lang.ExceptionInInitializerError
Lombok 1.18.48 on JDK 25: compiled; getName() = ankur
Lombok 1.18.48 on JDK 26: compiled; getName() = ankur
Lombok 1.18.48 on JDK 27: compiled; getName() = ankur
# The same source with the jar on the class path only (no -processorpath), the way a hand-run javac used to find it:
JDK 21, Lombok 1.18.48 on the class path only: exit=0 Note: Annotation processing is enabled because one or more processors were found
JDK 25, Lombok 1.18.48 on the class path only: exit=1 <repo>/lanes/src/LombokProbe.java:11: error: cannot find symbol
JDK 23, Lombok 1.18.48 on the class path only: exit=1 <repo>/lanes/src/LombokProbe.java:11: error: cannot find symbol
JDK 24, Lombok 1.18.48 on the class path only: exit=1 <repo>/lanes/src/LombokProbe.java:11: error: cannot find symbol
+15
View File
@@ -0,0 +1,15 @@
# jdeps --jdk-internals on the class from lanes/src/UnsafeWarning.java (JDK 25's jdeps)
$ jdeps --jdk-internals --multi-release 25 UnsafeWarning.class
UnsafeWarning.class -> jdk.unsupported
UnsafeWarning -> sun.misc.Unsafe JDK internal API (jdk.unsupported)
Warning: JDK internal APIs are unsupported and private to JDK implementation that are
subject to be removed or changed incompatibly and could break your application.
Please modify your code to eliminate dependence on any JDK internal APIs.
For the most recent update on JDK internal API replacements, please check:
https://wiki.openjdk.org/display/JDK8/Java+Dependency+Analysis+Tool
JDK Internal API Suggested Replacement
---------------- ---------------------
sun.misc.Unsafe See https://openjdk.org/jeps/260
+17
View File
@@ -0,0 +1,17 @@
# lanes/src/MockitoProbe.java: mock an interface, stub one call. Four Mockito versions, each with the ByteBuddy it declares.
Mockito 5.12.0 (ByteBuddy 1.14.15) on JDK 21: works: mock says hi
Mockito 5.12.0 (ByteBuddy 1.14.15) on JDK 25: FAILS: Mockito cannot mock this class: interface MockitoProbe$Greeter.
Mockito 5.12.0 (ByteBuddy 1.14.15) on JDK 27: FAILS: Mockito cannot mock this class: interface MockitoProbe$Greeter.
Mockito 5.17.0 (ByteBuddy 1.15.11) on JDK 21: works: mock says hi
Mockito 5.17.0 (ByteBuddy 1.15.11) on JDK 25: FAILS: Mockito cannot mock this class: interface MockitoProbe$Greeter.
Mockito 5.17.0 (ByteBuddy 1.15.11) on JDK 27: FAILS: Mockito cannot mock this class: interface MockitoProbe$Greeter.
Mockito 5.18.0 (ByteBuddy 1.17.5 ) on JDK 21: works: mock says hi
Mockito 5.18.0 (ByteBuddy 1.17.5 ) on JDK 25: works: mock says hi
Mockito 5.18.0 (ByteBuddy 1.17.5 ) on JDK 27: works: mock says hi
Mockito 5.23.0 (ByteBuddy 1.17.7 ) on JDK 21: works: mock says hi
Mockito 5.23.0 (ByteBuddy 1.17.7 ) on JDK 25: works: mock says hi
Mockito 5.23.0 (ByteBuddy 1.17.7 ) on JDK 27: works: mock says hi
# Notices on stderr from the working Mockito 5.23.0 on JDK 25
Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK. Please add Mockito as an agent to your build as described in Mockito's documentation: https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#0.3
WARNING: A Java agent has been loaded dynamically (<repo>/build/upgrade/mockito/5.23.0/lib/byte-buddy-agent-1.17.7.jar)