Skip to content

8356439: Rename JavaLangAccess::*NoRepl methods #26413

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

vy
Copy link
Contributor

@vy vy commented Jul 21, 2025

NoRepl-suffixed String methods denote methods that do not replace invalid characters, but throw CharacterCodingException on encounter. This behavior cannot easily be derived from the method footprints, has been a source of confusion for maintainers, and is not uniformly adopted, e.g., newStringUTF8NoRepl() and getBytesUTF8NoRepl() does not throw CCE. This PR removes NoRepl suffix from method names and consistently uses throws CCE in method footprints. (b484510 passes tier1,2.)


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8356439: Rename JavaLangAccess::*NoRepl methods (Enhancement - P4)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/26413/head:pull/26413
$ git checkout pull/26413

Update a local copy of the PR:
$ git checkout pull/26413
$ git pull https://git.openjdk.org/jdk.git pull/26413/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 26413

View PR using the GUI difftool:
$ git pr show -t 26413

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/26413.diff

@bridgekeeper
Copy link

bridgekeeper bot commented Jul 21, 2025

👋 Welcome back vyazici! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Jul 21, 2025

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@openjdk
Copy link

openjdk bot commented Jul 21, 2025

@vy The following labels will be automatically applied to this pull request:

  • core-libs
  • nio
  • security

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing lists. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added security security-dev@openjdk.org nio nio-dev@openjdk.org core-libs core-libs-dev@openjdk.org labels Jul 21, 2025
String msg = "malformed input off : " + off + ", length : " + nb;
throw new IllegalArgumentException(msg, new MalformedInputException(nb));
mie.initCause(new IllegalArgumentException(msg));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Earlier throw(Malformed|Unmappable) methods were throwing IAE containing extra diagnostics information and wrapping a CCE as a cause. After switching methods to throw CCE, which doesn't have a ctor accepting a String message, to retain this extra diagnostics information, I've added swapped their causal chain placement, and wrapped IAE with a CCE this time.

This played well with CCE-throwing methods, yet there are other public methods which did not have throws CCE in their footprint. For backward compatibility, in those spots, I've used cce2iae to obtain, again, a IAE wrapping the CCE, which matched the old behavior.

Copy link
Member

@liach liach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I strongly suggest against using CCE as the standard exception. The only place that relies on CCE is Files; IAE is more suitable for everywhere else. I recommend adding the special CCE handling in Files alone so we can remove the redundant try-catch everywhere else.

@@ -325,7 +325,7 @@ public interface JavaLangAccess {
* @return the newly created string
* @throws CharacterCodingException for malformed or unmappable bytes
*/
String uncheckedNewStringNoRepl(byte[] bytes, Charset cs) throws CharacterCodingException;
String uncheckedNewString(byte[] bytes, Charset cs) throws CharacterCodingException;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs should mention these two details:

  1. This method does not replace upon malformed data but fails
  2. This method does not copy the byte array for validation (can add to the warning)

@vy
Copy link
Contributor Author

vy commented Jul 21, 2025

@liach, thanks so much for the prompt feedback!

I strongly suggest against using CCE as the standard exception.

Would you mind elaborating on the rationale behind this preference, please?

@liach
Copy link
Member

liach commented Jul 21, 2025

Would you mind elaborating on the rationale behind this preference, please?

If you look at the history of newStringNoRepl, you will find it's originally added for JDK-8201276 in ca48716. Since then, newStringNoRepl has been used by various other sites mostly as a utility. None of those further usages ever used the CharacterCodingException. In fact, in String, the actual implementation throws an IAE that is later wrapped in a CCE. I don't think we should punish all other users of this API just because Files.readString requires this CCE; the CCE wrapping can be moved to Files.readString.

@AlanBateman
Copy link
Contributor

newStringNoRepl has confused several maintainers as it's not immediately obvious that it means "no replace", or more specifically CodingErrorAction.REPORT behavior. So it's good to see this getting attention.

Anyone working on String expects CodingErrorAction.REPLACE behavior so having String methods use methods that don't throw would feel right.

There are "far away" APIs, Files.readXXX was mentioned, that require CodingErrorAction.REPORT behavior methods so having JLA methods throw CharacterCodingException is helpful.

There are other far away APIs such as UUID and ZipCoder that specify a Charset and know that no exception will be throw. They want CodingErrorAction.REPORT behavior except that it's a bug if CharacterCodingException is thrown. These cases catch CCE and throw AssertionError, which is okay, and hopefully we have enough tests in all these area to ensure that it doesn't happen.

Anyway, from a first read of the changes then I think we need to make sure that the method descriptions are accurate. There are several places where "IAE" is mentioned but the methods are changed to throw CCE. IAE is awkward in this area because throwing it, instead of CCE, makes it difficult to know if the handling is correct. There is constant code churn in this area and too easy to introduce a regression and "unexpected exception" if IAE is used to in place of a CharacterCodingException.

Another high level comment from a first read is that it feels like there are two forms needed. One form is REPLACE action and doesn't throw. The other is REPORT action and throws CharacterCodingException. That is what we have already, it's just the naming is awkward. So it may be that it's more about finding good names so that it's clear from all the use sites.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core-libs core-libs-dev@openjdk.org nio nio-dev@openjdk.org security security-dev@openjdk.org
Development

Successfully merging this pull request may close these issues.

3 participants