<Swing Dev> Remove System.out.println from ImageIcon.loadImage
Volodin, Vladislav
vladislav.volodin at sap.com
Mon Jan 27 17:11:05 UTC 2020
Hello Sergey, and others,
here is the patch (made with "git diff") in the attachment. I have read that sometimes the attachments are lost. So here is my version with few comments regarding my code. I decided to use your approach with a small improvement. There is an excerpt of my patch.
The idea is pretty simple:
1. I create an empty gif 1x1;
2. Initialize DefaultToolkit (I plan to interrupt the main thread, and if I do not initialize the toolkit in advance, my test will fail at the beginning
3. Interrupt the main thread
4. Try to load the icon:
import javax.swing.*;
import java.awt.*;
public class imageIconInterrupted {
static byte[] EMPTY_GIF = new byte[]{
(byte) 0x47, (byte) 0x49, (byte) 0x46, (byte) 0x38, (byte) 0x39, (byte) 0x61, (byte) 0x01, (byte) 0x00,
(byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x21, (byte) 0xF9, (byte) 0x04,
(byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x2C, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x02
};
public static void main(String[] args) throws Exception {
Toolkit ignoreToolkit = Toolkit.getDefaultToolkit();
Thread.currentThread().interrupt();
ImageIcon iconInterrupt = new ImageIcon(EMPTY_GIF);
if (iconInterrupt.getImageLoadStatus() != MediaTracker.COMPLETE) {
throw new RuntimeException("Couldn't load GIF from bytes after interruption");
}
}
}
The code of loadImage I have changed as follows:
1. I clear loadStatus for "finally" part;
2. Check the interruption according to your comments;
3. Change the status to ABORTED, if the interruption happened again (this part I cannot test, because I cannot properly interrupt the thread whenever I want. Multithreading is quite fragile there :( )
4. update the status "interrupted" again;
5. and then - finally block.
protected void loadImage(Image image) {
...
try {
loadStatus = 0;
mTracker.addImage(image, id);
mTracker.waitForID(id, 0);
} catch (InterruptedException e1) {
try {
mTracker.waitForID(id, 0);
} catch (InterruptedException e2) {
loadStatus = MediaTracker.ABORTED;
Thread.currentThread().interrupt();
}
} finally {
if (loadStatus == 0) {
loadStatus = mTracker.statusID(id, false);
}
mTracker.removeImage(image, id);
}
P.S. if you think that my patch sounds fine, I will find a sponsor for the bug report and the patch preparation, so you can review it later.
After the second attempt, my EMPTY_GIF was loaded successfully. The ABORTED part it seems that I don't know if it has ever worked. My patch (in the attachment) checks also the state ERROR for the URL that doesn't exist. Something like:
ImageIcon iconNotExist = new ImageIcon(new URL("http://doesnt.exist.anywhere/1.gif")); // I am not sure if I spelled this URL grammatically correct
if (iconNotExist.getImageLoadStatus() != MediaTracker.ERRORED) {
throw new RuntimeException("Got unexpected status from non-existing GIF");
}
Thanks to everyone.
Kind regards,
Vlad
-----Original Message-----
From: Sergey Bylokhov <Sergey.Bylokhov at oracle.com>
Sent: Dienstag, 21. Januar 2020 22:26
To: Volodin, Vladislav <vladislav.volodin at sap.com>
Cc: Jason Mehrens <jason_mehrens at hotmail.com>; swing-dev at openjdk.java.net
Subject: Re: <Swing Dev> Remove System.out.println from ImageIcon.loadImage
On 1/21/20 1:14 pm, Volodin, Vladislav wrote:
> Hi all,
>
> If I am not mistaken, this method is called from the constructor and other methods. How long should we try loading the icon using the unmanaged (by any thread pool, but I am not sure about this statement) thread?
>
> We don’t even have the flag “interrupted”. So technically this icon has to be loaded.
I think it is necessary to save the "interrupted" state in the catch
block and try to call waitForID() again. It will be necessary to set
"interrupted" flag for the Thread after that(when the waitForID will
return without exception).
> Sent from myFone
>
>> On 21. Jan 2020, at 21:55, Sergey Bylokhov <Sergey.Bylokhov at oracle.com> wrote:
>>
>> On 1/21/20 12:26 pm, Jason Mehrens wrote:
>>> +1 for Sergey suggestion.
>>
>> Or probably we need to try to load the image again because of the spec of the method state this:
>> "Loads the image, returning only when the image is loaded."
>>
>>> ________________________________________
>>> From: Sergey Bylokhov <Sergey.Bylokhov at oracle.com>
>>> Sent: Sunday, January 19, 2020 9:31 PM
>>> To: Volodin, Vladislav; Jason Mehrens
>>> Cc: swing-dev at openjdk.java.net
>>> Subject: Re: <Swing Dev> Remove System.out.println from ImageIcon.loadImage
>>> I guess there are no objections, probably the best way to fix
>>> it is to drop the System.out.println and set interrupted flag.
>>> On 1/16/20 7:05 am, Volodin, Vladislav wrote:
>>>> If people in this distribution list agree, I can start working on a simple fix and either remove the logging (System.out.println), or replace it with PlatformLogger. I guess the second solution sounds better, but I don't know what is the better way to write a test-case for it.
>>> --
>>> Best regards, Sergey.
>>
>>
>> --
>> Best regards, Sergey.
--
Best regards, Sergey.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: imageIconBug-diff.patch
Type: application/octet-stream
Size: 3606 bytes
Desc: imageIconBug-diff.patch
URL: <https://mail.openjdk.java.net/pipermail/swing-dev/attachments/20200127/d08256da/imageIconBug-diff.patch>
More information about the swing-dev
mailing list