-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8344908: URLClassPath should not propagate IllegalArgumentException when finding resources in classpath URLs #22351
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
Conversation
…hen finding resources in classpath URLs
👋 Welcome back jpai! A progress list of the required criteria for merging this PR into |
@jaikiran This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 94 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
Webrevs
|
*/ | ||
public static String decode(String s) { | ||
public static String decode(String s) throws IllegalArgumentException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if you meant to add this or not but "throws IAE" is not needed, usually don't put unchecked exceptions in the throws.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello Alan, that was intentional to be more prominently visible, but I'll remove it and will just retain @throws
javadoc tag that I added as part of this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done - I've updated the PR to remove the throws clause from the method signature.
if (s == null) { | ||
return false; | ||
} else { | ||
File f = new File (s); | ||
File f = new File(s); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lots of unrelated cleanup in this file, but okay.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I was considering not doing it, but the number of such lines didn't seem too many, so decided to include it. If you and others lean towards leaving the formatting clean up out of this, then I will update the PR accordingly.
final JarEntry jarEntry = new JarEntry(RESOURCE_NAME); | ||
jaros.putNextEntry(jarEntry); | ||
jaros.write("hello".getBytes(US_ASCII)); | ||
jaros.closeEntry(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a readability point of view, I think renaming "jaros" to "jos" would make it a bit easier to read. Also personally I would drop the uses of final from the try statement, only because there it adds noise when looking at the 3 resources in the statement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think renaming "jaros" to "jos" would make it a bit easier to read.
Done.
Also personally I would drop the uses of final from the try statement, only because there it adds noise when looking at the 3 resources in the statement.
Understood. I have updated the PR to remove them from the try
statement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some suggestion and remarks for the test
iae.printStackTrace(); // for debug purpose | ||
// if we can't create a directory with an emoji in its path name, | ||
// then skip the entire test | ||
assumeTrue(false, "Skipping test since emoji directory couldn't be created: " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps Assumptions.abort(message)
would be more clear here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello Eirik, it looks like this is a new API introduced in 5.9 of jupiter API. Looking at jtreg 7.4 that's used in JDK mainline, the jupiter API we use is 5.10.x. So yes, abort()
would be more appropriate here. I've updated accordingly.
// path that can serve the resource. | ||
return new String[]{ | ||
// non-existent dir | ||
ASCII_DIR.resolve("non-existent").toString(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just an observation: This will not be recognized as a directory, so this will not create a FileLoader
, but a JarLoader
(which will throw a FileNotFoundException
).
For good measure, you could consider adding an actual non-existing directory URL, but I think you'd need to use URLClassPath::addURL
for that instead of addFile
.
PS: It's rather weird that a non-exisiting FileLoader
is added to the class path, while a non-existing JarLoader is ignored. Thorny code indeed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of the "non-existent" path was intentional to trigger the exceptional code path. But I agree that the code comment which said non-existent dir
was inaccurate. So I've updated that comment to say "non-existent path"
} | ||
} | ||
|
||
private static String[] getClassPathElements() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could perhaps be addClassPathElemements(URLClassPath)
instead for cleaner call sites?
Or perhaps even URLClassPath makeClassPath()
since both tests seem to have identical class paths?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer keeping the classpath construction through URLClassPath.addFile()
closer to the test code itself. So I've left this part as-is.
Files.writeString(EMOJI_DIR.resolve(RESOURCE_NAME), "hello"); | ||
|
||
ASCII_DIR = Files.createTempDirectory(SCRATCH_DIR, "test-urlclasspath"); | ||
Files.writeString(ASCII_DIR.resolve(RESOURCE_NAME), "hello"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The contents of the resources seems not to matter for the test currently.
Consider using just Files::createFile
here, or make unique content for each resource such that you can verify the correct content was found in the tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done - I've updated the test to use Files.createFile
instead of writeString()
.
I'll need a Reviewer's review on this one please - the latest update is trivial changes in the test and the test continues to pass. |
Thank you Alan and Eirik for the reviews and inputs. |
/integrate |
Going to push as commit 81c44e5.
Your commit was automatically rebased without conflicts. |
Can I please get a review of this change that proposes to address the issue noted in https://bugs.openjdk.org/browse/JDK-8344908?
With this change, the URLClassPath will no longer propagate the
IllegalArgumentException
thrown when constructing a resource loader. The URL which caused the issue will continue to not be able to serve resources through that URLClassPath but the URLClassPath itself will now be functionally usable for locating resources through rest of the URLs.While at it, the internal class
FileURLMapper
which gets used in this code flow has been updated to be more confined by making it package private.For addressing the underlying issue with ParseUtil we have https://bugs.openjdk.org/browse/JDK-8258246 which I plan to look into separately. There are also a few other usages of
ParseUtil.decode()
in various other places outside of this code flow which I plan to look into separately.A new jtreg test has been introduced which reproduces the issue and verifies the fix. This test and other existing tests in tier1, tier2 and tier3 continue to pass with this change.
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/22351/head:pull/22351
$ git checkout pull/22351
Update a local copy of the PR:
$ git checkout pull/22351
$ git pull https://git.openjdk.org/jdk.git pull/22351/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 22351
View PR using the GUI difftool:
$ git pr show -t 22351
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/22351.diff
Using Webrev
Link to Webrev Comment