Hello Everyone First, Thanks to Sergey for his detailed suggestion on test-case approach.
I've modified the test-case keeping Sergey's suggestion as a reference. Few subtle changes are- . Created explicit classes rather than using anonymous class definitions . Modified minimum test duration from 10 seconds to 5 seconds. The test-case now reproduces this issue without the proposed fix. (Tested on win7 and Ubuntu VM) Besides this, I 've updated Javadoc comments for FilteredImageSource as requested by Joe Darcy in CSR review. . Since every method is synchronized, I decided to update javadoc comments for the class. . The approach is similar to how java.util.HashTable captures the synchronized contract of its methods. The javadoc modification is as follows- @@ -35,7 +35,8 @@ /** * This class is an implementation of the ImageProducer interface which * takes an existing image and a filter object and uses them to produce - * image data for a new filtered version of the original image. + * image data for a new filtered version of the original image. Furthermore, + * {@code FilteredImageSource} is synchronized for thread-safety. * Here is an example which filters an image by swapping the red and Kindly review the above changes at your convenience and share your views Webrev link: http://cr.openjdk.java.net/~pnarayanan/8188083/webrev.02/ Thank you for your time Have a good day Prahalad -----Original Message----- From: Sergey Bylokhov Sent: Tuesday, November 28, 2017 11:14 PM To: Prahalad Kumar Narayanan; 2d-dev Cc: Philip Race Subject: Re: [OpenJDK 2D-Dev] [10] RFR: JDK-8188083- NPE in java.awt.image.FilteredImageSource.startProduction The test can use any part of our API. It is a small part of the code which can confirm/verify the fix. It should not be considered as a user's code and it could emulate behavior of classes inside jdk. If you do not like to call these methods directly you can do this like this: import java.awt.Graphics; import java.awt.Image; import java.awt.image.ColorModel; import java.awt.image.FilteredImageSource; import java.awt.image.ImageConsumer; import java.awt.image.ImageFilter; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; import java.util.Hashtable; public final class Test { private volatile static Throwable fail; public static void main(final String[] args) throws InterruptedException { final ImageConsumer ic = new ImageConsumer() { @Override public void setDimensions(int i, int i1) { } @Override public void setProperties(Hashtable<?, ?> hashtable) { } @Override public void setColorModel(ColorModel colorModel) { } @Override public void setHints(int i) { } @Override public void setPixels(int i, int i1, int i2, int i3, ColorModel colorModel, byte[] bytes, int i4, int i5) { } @Override public void setPixels(int i, int i1, int i2, int i3, ColorModel colorModel, int[] ints, int i4, int i5) { } @Override public void imageComplete(int i) { } }; final ImageProducer ip = new ImageProducer() { @Override public void addConsumer(ImageConsumer imageConsumer) { } @Override public boolean isConsumer(ImageConsumer imageConsumer) { return false; } @Override public void removeConsumer(ImageConsumer imageConsumer) { } @Override public void startProduction(ImageConsumer imageConsumer) { } @Override public void requestTopDownLeftRightResend( ImageConsumer imageConsumer) { } }; final Image image = new Image() { ImageFilter filter = new ImageFilter(); ImageProducer producer = new FilteredImageSource(ip, filter); @Override public int getWidth(ImageObserver observer) { return 100; } @Override public int getHeight(ImageObserver observer) { return 100; } @Override public ImageProducer getSource() { return producer; } @Override public Graphics getGraphics() { throw new UnsupportedOperationException(); } @Override public Object getProperty(String name, ImageObserver observer) { return null; } }; Thread t1 = new Thread(() -> { try { while (true) { image.getSource().addConsumer(ic); } } catch (Throwable t) { fail = t; } }); Thread t2 = new Thread(() -> { try { while (true) { image.getSource().removeConsumer(ic); } } catch (Throwable t) { fail = t; } }); Thread t3 = new Thread(() -> { try { while (true) { image.getSource().startProduction(ic); } } catch (Throwable t) { fail = t; } }); t1.setDaemon(true); t2.setDaemon(true); t3.setDaemon(true); t1.start(); t2.start(); t3.start(); t1.join(10000); if (fail != null) { throw new RuntimeException("Test fail", fail); } } } On 27/11/2017 23:31, Prahalad Kumar Narayanan wrote: > Hello Sergey > > Thank you for your review response. > > I had one version of the test that resembled your test code. > I uploaded the result (screenshot) of that test case with/ without fix on JBS. > > The only point of concern - API documentation mentions that the methods of > FilteredImageSource are not supposed to be invoked directly from user code. > If the methods are invoked directly from user code, the result is un-defined. > Since our JTreg test cases cannot violate the documented guide, I refrained > from attaching the test case in the first webrev. > > Kindly let me know your views to this. > > Thank you once again > Have a good day > > Prahalad > > -----Original Message----- > From: Sergey Bylokhov > Sent: Tuesday, November 28, 2017 12:46 PM > To: Prahalad Kumar Narayanan; 2d-dev > Cc: Philip Race > Subject: Re: [OpenJDK 2D-Dev] [10] RFR: JDK-8188083- NPE in > java.awt.image.FilteredImageSource.startProduction > > On 27/11/2017 22:12, Prahalad Kumar Narayanan wrote: >> Yes..! As you rightly pointed, the test passes before the fix as well. > > Then I suggest to additionally reuse a test which I sent previously, > it is fail almost always before the fix. The test which fails one time > in > 10000 runs will be never fixed, or such bugs will be closed as not > reproducible. > >> >> Reason is that, the occurrence of this bug is rare. >> . Submitter has observed only 15 occurrences of the exception with >> over 10,000 instances per month. >> . Though the occurrence is rare, submitter is expecting a fix for this >> issue. >> >> So what does this test-case resolve ? >> . Our change adds "synchronized" contract to the method to fix the >> Null pointer exception. >> . To test the changes, we should check for both- Null Pointer >> Exception and any deadlock that could arise from "synchronized" contract. >> . The test case helps to address both but in a passive way. Why do I >> say passive ? >> . First, the test provides a hope to detect & report NPE though >> its occurrence is rare. >> . Second, any deadlock arising from the concerned method, will >> cause the test to fail upon time-out. >> >> Thank you once again for your time >> Have a good day >> >> Prahalad >> >> -----Original Message----- >> From: Sergey Bylokhov >> Sent: Monday, November 27, 2017 9:11 PM >> To: Prahalad Kumar Narayanan; 2d-dev >> Cc: Philip Race >> Subject: Re: [OpenJDK 2D-Dev] [10] RFR: JDK-8188083- NPE in >> java.awt.image.FilteredImageSource.startProduction >> >> Hi,Prahalad. >> On 24/11/2017 21:40, Prahalad Kumar Narayanan wrote: >>> Based on discussions with Sergey, I 've now updated the fix with a test >>> case. >>> The changes are available for review under: >>> http://cr.openjdk.java.net/~pnarayanan/8188083/webrev.01/ >> >> This version of the test is always passed before the fix(I have checked w/ >> and w/o jtreg). >> >> -- >> Best regards, Sergey. >> > > -- Best regards, Sergey.