RELEASE NOTES FOR: 11.0.31 ==================================================================================================== Notes generated: Mon Mar 16 21:32:42 CET 2026 Hint: Prefix bug IDs with https://bugs.openjdk.org/browse/ to reach the relevant JIRA entry. JAVA ENHANCEMENT PROPOSALS (JEP): None. RELEASE NOTES: security-libs/javax.net.ssl: JDK-8349583: Mechanism to Disable Signature Schemes Based on Their TLS Scope TLS protocol specific usage constraints are now supported by the `jdk.tls.disabledAlgorithms` property in the `java.security` configuration file, as follows: ``` UsageConstraint: usage UsageType { UsageType } UsageType: HandshakeSignature | CertificateSignature ``` `HandshakeSignature` restricts the use of an algorithm in TLS handshake signatures. `CertificateSignature` restricts the use of an algorithm in certificate signatures. An algorithm with this constraint cannot include other usage types defined in the `jdk.certpath.disabledAlgorithms` property. The usage type follows the keyword and more than one usage type can be specified with a whitespace delimiter. JDK-8340321: Disabled SHA-1 in TLS 1.2 and DTLS 1.2 Handshake Signatures The SHA-1 algorithm has been disabled by default in TLS 1.2 and DTLS 1.2 handshake signatures, by adding `"rsa_pkcs1_sha1 usage HandshakeSignature, ecdsa_sha1 usage HandshakeSignature, dsa_sha1 usage HandshakeSignature"` to the `jdk.tls.disabledAlgorithms` security property in the `java.security` config file. RFC 9155 deprecates the use of SHA-1 in TLS 1.2 and DTLS 1.2 digital signatures. Users can, at their own risk, re-enable the SHA-1 algorithm in TLS 1.2 and DTLS 1.2 handshake signatures by removing `"rsa_pkcs1_sha1 usage HandshakeSignature, ecdsa_sha1 usage HandshakeSignature, dsa_sha1 usage HandshakeSignature"` from the `jdk.tls.disabledAlgorithms` security property. JDK-8340321: Limitations on Disabling SHA-1 in TLS 1.2 Signatures in JDK 7u JDK 7u implements TLS 1.2 in accordance with RFC 5246, which defines a single `signature_algorithms` extension that applies to both TLS handshake signatures and certificate signatures. Unlike later specifications, it does not distinguish between these two usages. As a result, signature algorithms cannot be selectively disabled for handshake messages while remaining enabled for certificate validation. This tight coupling prevents fine-grained deprecation of algorithms such as SHA-1 limited only to handshake signatures. Users who wish to disable SHA-1 signature algorithms in TLS 1.2 may do so by adding `"SHA1withRSA, SHA1withECDSA, SHA1withDSA"` to the `jdk.tls.disabledAlgorithms` security property in the `java.security` config file. However, users should be aware that this setting applies globally to TLS signature usage in JDK 7u and will therefore reject all SHA-1 signed certificates, potentially impacting interoperability with legacy servers. JDK-8369282: Distrust TLS Server Certificates Anchored by Chunghwa Root Certificates and Issued After March 17, 2026 The JDK will stop trusting TLS server certificates issued after March 17, 2026 and anchored by Chunghwa root certificates, in line with similar plans announced by Google and Mozilla. TLS server certificates issued on or before March 17, 2026 will continue to be trusted until they expire. Certificates issued after that date, and anchored by the Certificate Authority listed in the table below, will be rejected. The restrictions are enforced in the JDK implementation (the `SunJSSE` Provider) of the Java Secure Socket Extension (JSSE) API. A TLS session will not be negotiated if the server's certificate chain is anchored by any of the Certificate Authorities in the table below and the certificate has been issued after March 17, 2026. An application will receive an exception with a message indicating the trust anchor is not trusted, for example: ``` "TLS Server certificate issued after 2026-03-17 and anchored by a distrusted legacy Chunghwa root CA: OU=ePKI Root Certification Authority, O="Chunghwa Telecom Co., Ltd." C=TW" ``` The JDK can be configured to trust these certificates again by removing "CHUNGHWA_TLS" from the `jdk.security.caDistrustPolicies` security property in the `java.security` configuration file. The restrictions are imposed on the following Chunghwa Root certificates included in the JDK:
| Distinguished Name | SHA-256 Fingerprint |
|---|---|
| OU=ePKI Root Certification Authority, O="Chunghwa Telecom Co., Ltd.", C=TW | C0:A6:F4:DC:63:A2:4B:FD:CF:54:EF:2A:6A:08:2A:0A:72:DE:35:80:3E:2F:F5:FF:52:7A:E5:D8:72:06:DF:D5 |
Hello, world
\n" + " \n" + "\n"; ``` _Using a "two-dimensional" block of text_ ``` String html = """Hello, world
"""; ``` ### SQL example _Using "one-dimensional" string literals_ ``` String query = "SELECT \"EMP_ID\", \"LAST_NAME\" FROM \"EMPLOYEE_TB\"\n" + "WHERE \"CITY\" = 'INDIANAPOLIS'\n" + "ORDER BY \"EMP_ID\", \"LAST_NAME\";\n"; ``` _Using a "two-dimensional" block of text_ ``` String query = """ SELECT "EMP_ID", "LAST_NAME" FROM "EMPLOYEE_TB" WHERE "CITY" = 'INDIANAPOLIS' ORDER BY "EMP_ID", "LAST_NAME"; """; ``` ### Polyglot language example _Using "one-dimensional" string literals_ ``` ScriptEngine engine = new ScriptEngineManager().getEngineByName("js"); Object obj = engine.eval("function hello() {\n" + " print('\"Hello, world\"');\n" + "}\n" + "\n" + "hello();\n"); ``` _Using a "two-dimensional" block of text_ ``` ScriptEngine engine = new ScriptEngineManager().getEngineByName("js"); Object obj = engine.eval(""" function hello() { print('"Hello, world"'); } hello(); """); ``` Description ----------- > _This section is identical to the same section in this JEP's predecessor, [JEP 355](https://openjdk.java.net/jeps/355), except for the addition of the subsection on [new escape sequences](#New-escape-sequences)._ A _text block_ is a new kind of literal in the Java language. It may be used to denote a string anywhere that a _[string literal](https://docs.oracle.com/javase/specs/jls/se12/html/jls-3.html#jls-3.10.5)_ could appear, but offers greater expressiveness and less accidental complexity. A text block consists of zero or more content characters, enclosed by opening and closing delimiters. The _opening delimiter_ is a sequence of three double quote characters (`"""`) followed by zero or more white spaces followed by a line terminator. The _content_ begins at the first character after the line terminator of the opening delimiter. The _closing delimiter_ is a sequence of three double quote characters. The content ends at the last character before the first double quote of the closing delimiter. The content may include double quote characters directly, unlike the characters in a string literal. The use of `\"` in a text block is permitted, but not necessary or recommended. Fat delimiters (`"""`) were chosen so that `"` characters could appear unescaped, and also to visually distinguish a text block from a string literal. The content may include line terminators directly, unlike the characters in a string literal. The use of `\n` in a text block is permitted, but not necessary or recommended. For example, the text block: ``` """ line 1 line 2 line 3 """ ``` is equivalent to the string literal: ``` "line 1\nline 2\nline 3\n" ``` or a concatenation of string literals: ``` "line 1\n" + "line 2\n" + "line 3\n" ``` If a line terminator is not required at the end of the string, then the closing delimiter can be placed on the last line of content. For example, the text block: ``` """ line 1 line 2 line 3""" ``` is equivalent to the string literal: ``` "line 1\nline 2\nline 3" ``` A text block can denote the empty string, although this is not recommended because it needs two lines of source code: ``` String empty = """ """; ``` Here are some examples of ill-formed text blocks: ``` String a = """"""; // no line terminator after opening delimiter String b = """ """; // no line terminator after opening delimiter String c = """ "; // no closing delimiter (text block continues to EOF) String d = """ abc \ def """; // unescaped backslash (see below for escape processing) ``` ### Compile-time processing A text block is a [constant expression](https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.28) of type `String`, just like a string literal. However, unlike a string literal, the content of a text block is processed by the Java compiler in three distinct steps: 1. Line terminators in the content are translated to LF (`\u000A`). The purpose of this translation is to follow the principle of least surprise when moving Java source code across platforms. 2. Incidental white space surrounding the content, introduced to match the indentation of Java source code, is removed. 3. Escape sequences in the content are interpreted. Performing interpretation as the final step means developers can write escape sequences such as `\n` without them being modified or deleted by earlier steps. The processed content is recorded in the `class` file as a `CONSTANT_String_info` entry in the constant pool, just like the characters of a string literal. The `class` file does not record whether a `CONSTANT_String_info` entry was derived from a text block or a string literal. At run time, a text block is evaluated to an instance of `String`, just like a string literal. Instances of `String` that are derived from text blocks are indistinguishable from instances derived from string literals. Two text blocks with the same processed content will refer to the same instance of `String` due to [interning](https://docs.oracle.com/javase/specs/jvms/se12/html/jvms-5.html#jvms-5.1-300), just like for [string literals](https://docs.oracle.com/javase/specs/jls/se12/html/jls-3.html#jls-3.10.5-410). The following sections discuss compile-time processing in more detail. #### 1. Line terminators Line terminators in the content are _normalized_ from CR (`\u000D`) and CRLF (`\u000D\u000A`) to LF (`\u000A`) by the Java compiler. This ensures that the string derived from the content is equivalent across platforms, even if the source code has been translated to a platform encoding (see `javac -encoding`). For example, if Java source code that was created on a Unix platform (where the line terminator is LF) is edited on a Windows platform (where the line terminator is CRLF), then without normalization, the content would become one character longer for each line. Any algorithm that relied on LF being the line terminator might fail, and any test that needed to verify string equality with `String::equals` would fail. The escape sequences `\n` (LF), `\f` (FF), and `\r` (CR) are _not_ interpreted during normalization; escape processing happens later. #### 2. Incidental white space The text blocks [shown above](#Motivation) were easier to read than their concatenated string literal counterparts, but the obvious interpretation for the content of a text block would include the spaces added to indent the embedded string so that it lines up neatly with the opening delimiter. Here is the HTML example using dots to visualize the spaces that the developer added for indentation: ``` String html = """ .............. .............. ..............Hello, world
.............. .............. .............."""; ``` Since the opening delimiter is generally positioned to appear on the same line as the statement or expression which consumes the text block, there is no real significance to the fact that 14 visualized spaces start each line. Including those spaces in the content would mean the text block denotes a string different from the one denoted by the concatenated string literals. This would hurt migration, and be a recurring source of surprise: it is overwhelmingly likely that the developer does _not_ want those spaces in the string. Also, the closing delimiter is generally positioned to align with the content, which further suggests that the 14 visualized spaces are insignificant. Spaces may also appear at the end of each line, especially when a text block is populated by copy-pasting snippets from other files (which may themselves have been formed by copy-pasting from yet more files). Here is the HTML example reimagined with some trailing white space, again using dots to visualize spaces: ``` String html = """ ................. .............. ..............Hello, world
.... .............. . ................. .............."""; ``` Trailing white space is most often unintentional, idiosyncratic, and insignificant. It is overwhelmingly likely that the developer does not care about it. Trailing white space characters are similar to line terminators, in that both are invisible artifacts of the source code editing environment. With no visual guide to the presence of trailing white space characters, including them in the content would be a recurring source of surprise, as it would affect the length, hash code, etc, of the string. Accordingly, an appropriate interpretation for the content of a text block is to differentiate _incidental white space_ at the start and end of each line, from _essential white space_. The Java compiler processes the content by removing incidental white space to yield what the developer intended. `String::indent` can then be used to further manipulate indentation if desired. Using `|` to visualize margins: ``` || | | |Hello, world
| | | || ``` The _re-indentation algorithm_ takes the content of a text block whose line terminators have been normalized to LF. It removes the same amount of white space from each line of content until at least one of the lines has a non-white space character in the leftmost position. The position of the opening `"""` characters has no effect on the algorithm, but the position of the closing `"""` characters does have an effect if placed on its own line. The algorithm is as follows: 1. Split the content of the text block at every LF, producing a list of _individual lines_. Note that any line in the content which was just an LF will become an empty line in the list of individual lines. 2. Add all _non-blank_ lines from the list of individual lines into a set of _determining lines_. (Blank lines -- lines that are empty or are composed wholly of white space -- have no visible influence on the indentation. Excluding blank lines from the set of determining lines avoids throwing off step 4 of the algorithm.) 3. If the last line in the list of individual lines (i.e., the line with the closing delimiter) is _blank_, then add it to the set of determining lines. (The indentation of the closing delimiter should influence the indentation of the content as a whole -- a [_significant trailing line_](#Significant-trailing-line-policy) policy.) 4. Compute the _common white space prefix_ of the set of determining lines, by counting the number of leading white space characters on each line and taking the minimum count. 5. Remove the common white space prefix from each _non-blank_ line in the list of individual lines. 6. Remove all trailing white space from all lines in the modified list of individual lines from step 5. This step collapses wholly-white-space lines in the modified list so that they are empty, but does not discard them. 7. Construct the result string by joining all the lines in the modified list of individual lines from step 6, using LF as the separator between lines. If the final line in the list from step 6 is empty, then the joining LF from the previous line will be the last character in the result string. The escape sequences `\b` (backspace), `\t` (tab) and `\s` (space) are _not_ interpreted by the algorithm; escape processing happens later. Similarly, the `\Hello, world
"""; ``` Including the trailing blank line with the closing delimiter, the common white space prefix is zero, so zero white space is removed from the start of each line. The algorithm thus produces: (using `|` to visualize the left margin) ``` | | |Hello, world
| | ``` Alternatively, suppose the closing delimiter is not moved all the way to the left, but rather under the `t` of `html` so it is eight spaces deeper than the variable declaration: ``` String html = """Hello, world
"""; ``` The spaces visualized with dots are considered to be incidental: ``` String html = """ ........ ........ ........Hello, world
........ ........ ........"""; ``` Including the trailing blank line with the closing delimiter, the common white space prefix is eight, so eight white spaces are removed from the start of each line. The algorithm thus preserves the essential indentation of the content relative to the closing delimiter: ``` | | |Hello, world
| | ``` Finally, suppose the closing delimiter is moved slightly to the _right_ of the content: ``` String html = """Hello, world
"""; ``` The spaces visualized with dots are considered to be incidental: ``` String html = """ .............. .............. ..............Hello, world
.............. .............. .............. """; ``` The common white space prefix is 14, so 14 white spaces are removed from the start of each line. The trailing blank line is stripped to leave an empty line, which being the last line is then discarded. In other words, moving the closing delimiter to the right of the content has no effect, and the algorithm again preserves the essential indentation of the content: ``` | | |Hello, world
| | ``` #### 3. Escape sequences After the content is re-indented, any _escape sequences_ in the content are interpreted. Text blocks support all of the escape sequences supported in string literals, including `\n`, `\t`, `\'`, `\"`, and `\\`. See [section 3.10.6](https://docs.oracle.com/javase/specs/jls/se12/html/jls-3.html#jls-3.10.6) of the _The Java Language Specification_ for the full list. Developers will have access to escape processing via `String::translateEscapes`, a new instance method. Interpreting escapes as the final step allows developers to use `\n`, `\f`, and `\r` for vertical formatting of a string without it affecting the translation of line terminators in step 1, and to use `\b` and `\t` for horizontal formatting of a string without it affecting the removal of incidental white space in step 2. For example, consider this text block that contains the `\r` escape sequence (CR): ``` String html = """ \r \rHello, world
\r \r \r """; ``` The CR escapes are not processed until after the line terminators have been normalized to LF. Using Unicode escapes to visualize LF (`\u000A`) and CR (`\u000D`), the result is: ``` |\u000D\u000A | \u000D\u000A |Hello, world
\u000D\u000A | \u000D\u000A |\u000D\u000A ``` Note that it is legal to use `"` and `""` freely inside a text block, except immediately before the closing delimiter. For example, the following text blocks are legal: ``` String story = """ "When I use a word," Humpty Dumpty said, in rather a scornful tone, "it means just what I choose it to mean - neither more nor less." "The question is," said Alice, "whether you can make words mean so many different things." "The question is," said Humpty Dumpty, "which is to be master - that's all." """; // Note the newline before the closing delimiter String code = """ String empty = ""; """; ``` However, a sequence of three `"` characters requires at least one `"` to be escaped, in order to avoid mimicking the closing delimiter. (A sequence of n `"` characters requires at least `Math.floorDiv(n,3)` of them to be escaped.) The use of `"` immediately before the closing delimiter also requires escaping. For example: ``` String code = """ String text = \""" A text block inside a text block \"""; """; String tutorial1 = """ A common character in Java programs is \""""; String tutorial2 = """ The empty string literal is formed from " characters as follows: \"\""""; System.out.println(""" 1 " 2 "" 3 ""\" 4 ""\"" 5 ""\""" 6 ""\"""\" 7 ""\"""\"" 8 ""\"""\""" 9 ""\"""\"""\" 10 ""\"""\"""\"" 11 ""\"""\"""\""" 12 ""\"""\"""\"""\" """); ``` ### New escape sequences To allow finer control of the processing of newlines and white space, we introduce two new escape sequences. First, the `\