Skip to content

Conversation

@prsadhuk
Copy link
Contributor

@prsadhuk prsadhuk commented Jun 12, 2025

When trying to call 'icon.setImage(null);' where 'icon' is an instance of ImageIcon, a null pointer exception is thrown at runtime.
The code tried to get the id for that image and instantiates MediaTracker to associate the null image to that id and checks the status of loading this null image, removes the null image from the tracker and then tries to get the image width where it throws NPE as image is null.

It's better to not go through all MediaTracker usage and bail out initially itself for null image..


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change requires CSR request JDK-8359398 to be approved
  • Change must be properly reviewed (2 reviews required, with at least 2 Reviewers)

Issues

  • JDK-8159055: Clarify handling of null and invalid image data for ImageIcon constructors and setImage method (Bug - P4)
  • JDK-8359398: Clarify handling of null and invalid image data for ImageIcon constructors and setImage method (CSR)

Reviewers

Reviewing

Using git

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

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

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 25767

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

Using diff file

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

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Jun 12, 2025

👋 Welcome back psadhukhan! 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 Jun 12, 2025

@prsadhuk 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:

8159055: Clarify handling of null and invalid image data for ImageIcon constructors and setImage method

Reviewed-by: aivanov, prr, abhiscxk, kizune, serb

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 1099 new commits pushed to the master branch:

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 master branch, type /integrate in a new comment.

@openjdk openjdk bot added the rfr Pull request is ready for review label Jun 12, 2025
@openjdk
Copy link

openjdk bot commented Jun 12, 2025

@prsadhuk The following label will be automatically applied to this pull request:

  • client

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

@openjdk openjdk bot added the client client-libs-dev@openjdk.org label Jun 12, 2025
@mlbridge
Copy link

mlbridge bot commented Jun 12, 2025

@kumarabhi006
Copy link
Contributor

Does it require to update the doc as well to explicitly mention about NULL parameter ?
Otherwise fix looks ok to me.

@prsadhuk
Copy link
Contributor Author

I feel it's better to inform the user in the spec otherwise application may not know what will be done with NULL image

@kumarabhi006
Copy link
Contributor

I feel it's better to inform the user in the spec otherwise application may not know what will be done with NULL image

CSR needed ?

@prsadhuk
Copy link
Contributor Author

prsadhuk commented Jun 12, 2025

yes..i will raise it once we are done with this PR approval..

@kumarabhi006
Copy link
Contributor

yes..i will raise it once we are done with this PR approval..

Ok...
Can't we just mention in the javadoc that null image will throw an NPE and then the code changes are not required?

@prsadhuk
Copy link
Contributor Author

yes..i will raise it once we are done with this PR approval..

Ok... Can't we just mention in the javadoc that null image will throw an NPE and then the code changes are not required?

No, as I mentioned in the description the MediaTracker creation and id addition, tracking and removal is supposedly not required for null image.

Copy link
Contributor

@kumarabhi006 kumarabhi006 left a comment

Choose a reason for hiding this comment

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

LGTM

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Jun 12, 2025
Copy link
Member

@azuev-java azuev-java left a comment

Choose a reason for hiding this comment

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

Looks good.

@openjdk openjdk bot added csr Pull request needs approved CSR before integration and removed ready Pull request is ready to be integrated labels Jun 13, 2025
@prsadhuk
Copy link
Contributor Author

Copy link
Member

@aivanov-jdk aivanov-jdk left a comment

Choose a reason for hiding this comment

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

The ImageIcon constructor that accepts Image has the same problem, or a similar problem.

public ImageIcon (Image image) {
this.image = image;
Object o = image.getProperty("comment", imageObserver);

It throws NullPointerException if a null parameter is passed. Other constructors handle null values, so you should unify handling of null images.

@prsadhuk prsadhuk changed the title 8159055: ImageIcon.setImage can't handle null parameter 8159055: Clarify handling of null and invalid image data for ImageIcon constructors and setImage method Jul 29, 2025
@prrace
Copy link
Contributor

prrace commented Jul 29, 2025

Currently, JDK-8159055 is an enhancement which made sense while the goal of this PR was to change Image.setImage so that it accepts null as parameter.

After a month of discussions, that solution has been abandoned, instead it is stated that Image.setImage will throw NullPointerException if image parameter is null.

I think the type of JDK-8159055 should be changed to bug.

I agree. Not saying how null is handled is a bug. So fixing it is a bug fix, not an enhancement.

@openjdk openjdk bot added ready Pull request is ready to be integrated csr Pull request needs approved CSR before integration and removed ready Pull request is ready to be integrated labels Aug 5, 2025
Comment on lines 71 to 74
new ImageIcon((URL)null);
} else if (v == ArgVal.INVALID_DATA) {
expected = false;
new ImageIcon("file://" + imgName, "gif");
Copy link
Member

Choose a reason for hiding this comment

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

There's a discrepancy: null is tested with one-arg constructor whereas invalid data is tested with two-arg constructor which accepts the description in addition to the URL.

More over, new ImageIcon("file://" + imgName, "gif") does not call ImageIcon(URL, String) constructor, it calls ImageIcon(String, String).

Comment on lines 81 to 84
new ImageIcon(bytes);
} else if (v == ArgVal.INVALID_DATA) {
expected = false;
new ImageIcon(new byte[0], "gif");
Copy link
Member

Choose a reason for hiding this comment

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

Why not new ImageIcon(new byte[0])?

Why is it new byte[0] instead of invalidData that you seemingly created for the purpose of having invalid data?

break;
case IMAGE :
if (v == ArgVal.NULL) {
new ImageIcon((Image)null);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
new ImageIcon((Image)null);
new ImageIcon((Image) null);

I guess you advocated for having a space between the type cast operator and its argument.

Copy link
Contributor

Choose a reason for hiding this comment

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

Personally, I do not like having a space there.

Comment on lines 113 to 116
if (expected && !passed) {
System.err.println("Did not receive expected exception for : " + a);
throw new RuntimeException("Test failed");
}
Copy link
Member

@aivanov-jdk aivanov-jdk Aug 5, 2025

Choose a reason for hiding this comment

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

Suggested change
if (expected && !passed) {
System.err.println("Did not receive expected exception for : " + a);
throw new RuntimeException("Test failed");
}
if (expected && !passed) {
throw new RuntimeException("Did not receive expected exception for: " + a);
}

Why not throw a detailed error message, this would make analysing test failure easier. At the very least, you will be able to distinguish different types of failures without looking into the test log file.

Comment on lines 117 to 120
if (!expected && !passed) {
System.err.println("Received unexpected exception for : " + a);
throw new RuntimeException("Test failed");
}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (!expected && !passed) {
System.err.println("Received unexpected exception for : " + a);
throw new RuntimeException("Test failed");
}
if (!expected && !passed) {
throw new RuntimeException("Received unexpected exception for: " + a);
}

@prrace
Copy link
Contributor

prrace commented Aug 5, 2025

This PR seems to be back waiting on the CSR ?

@aivanov-jdk
Copy link
Member

This PR seems to be back waiting on the CSR ?

Yes, because the text was updated.

Additionally, the test needs updating because it doesn't test ImageIcon(URL) constructor, it tests ImageIcon(String) twice.

case URL :
if (v == ArgVal.NULL) {
new ImageIcon((URL)null);
} else if (v == ArgVal.INVALID_DATA) {
expected = false;
new ImageIcon("file://" + imgName, "gif");
passed = true; // no exception expected for this case
}

@prsadhuk
Copy link
Contributor Author

prsadhuk commented Aug 6, 2025

Test updated

Copy link
Member

@aivanov-jdk aivanov-jdk left a comment

Choose a reason for hiding this comment

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

Looks good… except for lots of unexpected blank lines in the test code.

Comment on lines +63 to +73
switch (a) {

case FILE :

expected = false;
String s = (v == ArgVal.NULL) ? null : imgName;
new ImageIcon(s);
passed = true; // no exception expected for this case
break;

case URL :
Copy link
Member

Choose a reason for hiding this comment

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

Was adding so many blank lines intentional?

@openjdk openjdk bot removed the csr Pull request needs approved CSR before integration label Aug 7, 2025
@aivanov-jdk
Copy link
Member

Don't you want to use JUnit for test/jdk/javax/swing/ImageIcon/ImageIconTest.java?

I think using separate small methods to test ImageIcon constructors is much clearer and readable than switching over a set of enums. Moreover, a JUnit test will run all the test methods, which means you'll get the full picture instead of failing the entire test when the a first assertion fails.

I posted ImageIconConstructorsTest.java that uses JUnit. To run this test with jtreg add the following tags:

/*
 * @test
 * @summary Verifies behavior of ImageIcon constructors with null parameters
 * @run junit ImageIconConstructorsTest
 */
public final class ImageIconConstructorsTest {
}

You'll have to add test methods for invalid files and invalid data, though.

The jtreg report looks like this:

----------System.out:(0/0)----------
----------System.err:(31/2237)----------
STARTED    ImageIconConstructorsTest::stringNull 'stringNull()'
SUCCESSFUL ImageIconConstructorsTest::stringNull 'stringNull()' [15ms]
STARTED    ImageIconConstructorsTest::noArgs 'noArgs()'
SUCCESSFUL ImageIconConstructorsTest::noArgs 'noArgs()' [0ms]
STARTED    ImageIconConstructorsTest::imageNull 'imageNull()'
SUCCESSFUL ImageIconConstructorsTest::imageNull 'imageNull()' [0ms]
...

break;
case IMAGE :
if (v == ArgVal.NULL) {
new ImageIcon((Image)null);
Copy link
Contributor

Choose a reason for hiding this comment

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

Personally, I do not like having a space there.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Aug 21, 2025
@prsadhuk
Copy link
Contributor Author

/touch

@openjdk
Copy link

openjdk bot commented Aug 26, 2025

@prsadhuk The pull request is being re-evaluated and the inactivity timeout has been reset.

@prsadhuk
Copy link
Contributor Author

/integrate

@openjdk
Copy link

openjdk bot commented Aug 26, 2025

Going to push as commit 98e64cf.
Since your change was applied there have been 1099 commits pushed to the master branch:

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label Aug 26, 2025
@openjdk openjdk bot closed this Aug 26, 2025
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Aug 26, 2025
@openjdk
Copy link

openjdk bot commented Aug 26, 2025

@prsadhuk Pushed as commit 98e64cf.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

@prsadhuk prsadhuk deleted the JDK-8159055 branch August 26, 2025 05:29
@aivanov-jdk
Copy link
Member

aivanov-jdk commented Aug 26, 2025

Personally, I do not like having a space there.

Neither do I.

There should be no space between a case label and the colon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

client client-libs-dev@openjdk.org integrated Pull request has been integrated

Development

Successfully merging this pull request may close these issues.

8 participants