JDK-8280911 : Cannot open resource URL with supplementary character
  • Type: Bug
  • Component: core-libs
  • Affected Version: 8,11,17,18,19
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2022-01-27
  • Updated: 2022-01-31
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Description
ADDITIONAL SYSTEM INFORMATION :
System:
Linux ceres 4.19.0-18-amd64 #1 SMP Debian 4.19.208-1 (2021-09-29) x86_64 GNU/Linux

Java:
openjdk version "17.0.1" 2021-10-19
OpenJDK Runtime Environment Temurin-17.0.1+12 (build 17.0.1+12)
OpenJDK 64-Bit Server VM Temurin-17.0.1+12 (build 17.0.1+12, mixed mode, sharing)


A DESCRIPTION OF THE PROBLEM :
Class.getResource and Class.getResourceAsStream will fail if the argument contains a supplementary codepoint (that is, a codepoint whose Unicode value is greater than 0xfff and which is represented in a String as a high and low surrogate pair).

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a file (or .jar entry) whose name includes a supplementary codepoint in the same package as a class, and pass that name to Class.getResource or Class.getResourceAsStream.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When the resource exists, the getResource and getResourceAsStream methods should succeed without throwing any exceptions and should returned a non-null value.

ACTUAL -
Exception in thread "main" java.lang.IllegalArgumentException: Error decoding percent encoded characters
	at java.base/sun.net.www.ParseUtil.decode(ParseUtil.java:218)
	at java.base/sun.net.www.protocol.file.Handler.openConnection(Handler.java:80)
	at java.base/sun.net.www.protocol.file.Handler.openConnection(Handler.java:72)
	at java.base/java.net.URL.openConnection(URL.java:1094)
	at ResourceUrlWithSupplementary.main(ResourceUrlWithSupplementary.java:7)


---------- BEGIN SOURCE ----------
import java.io.IOException;

public class ResourceUrlWithSupplementary {
    public static void main(String[] args)
    throws IOException {
        ResourceUrlWithSupplementary.class.getResource("\uD83D\uDC31").openConnection();
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Create a resource URL for the class itself, then use the resource name containing the supplementary character as a relative URL in the two-argument constructor of URL:

URL url = ResourceUrlWithSupplementary.class.getResource(
    ResourceUrlWithSupplementary.class.getSimpleName() + ".class");
url = new URL(url, "\uD83D\uDC31");
url.openConnection();


FREQUENCY : always



Comments
The observations on Ubuntu: echo test > '🐱' JDK 8: Failed, IllegalArgumentException observed. JDK 11: Failed. JDK 17: Failed. JDK 18ea+30: Failed. JDK 19ea+3: Failed.
29-01-2022

Additional information from the submitter: In Linux and MacOS, you can just enter this command in any terminal: echo test > '😄' As long as the new file is in the same directory as the Java .class file, Class.getResource will be able to read it (or would, if not for the bug I discovered). In Windows 10, I found I could do it this way: • start Notepad • type some characters • go to the menu bar and do File→Save • in the save dialog, move the keyboard focus to the ‘File name’ field • hold down the Windows logo key and type a period, to bring up the emoji input window • enter an emoji character as the file name • save the file Most emojis are supplementary codepoints.
29-01-2022

Requested the steps of creating a file (or .jar entry) whose name includes a supplementary codepoint from the submitter.
29-01-2022