Unit test org.esa.snap.statistics.percentile.interpolated.MeanOpImageTest. testThatOperatorExceptionOccursWhenNoFloatingPointImagesAreProvided failed with the following stacktrace:
Expected: an instance of org.esa.snap.core.gpf.OperatorException
but: <java.lang.NullPointerException> is a java.lang.NullPointerException
Stacktrace was: java.lang.NullPointerException
at javax.media.jai.PlanarImage.copyData(PlanarImage.java:2344)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2525)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2546)
at org.esa.snap.statistics.percentile.interpolated.MeanOpImageTest.testThatOperatorExceptionOccursWhenNoFloatingPointImagesAreProvided(MeanOpImageTest.java:131)
...
It appears that OperatorException was thrown because in surefire report <system-err> shows:
org.geotools.util.logging.LoggingImagingListener: Problem occurs when computing a tile by the owner.
org.esa.snap.core.gpf.OperatorException: Unable to compute raster for non floating number data type
at org.esa.snap.statistics.percentile.interpolated.MeanOpImage.computeRect(MeanOpImage.java:37)
at javax.media.jai.PointOpImage.computeTile(PointOpImage.java:914)
at com.sun.media.jai.util.SunTileScheduler.scheduleTile(SunTileScheduler.java:904)
at javax.media.jai.OpImage.getTile(OpImage.java:1129)
at javax.media.jai.PlanarImage.copyData(PlanarImage.java:2343)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2525)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2546)
at org.esa.snap.statistics.percentile.interpolated.MeanOpImageTest.testThatOperatorExceptionOccursWhenNoFloatingPointImagesAreProvided(MeanOpImageTest.java:131)
...
For me on Windows the test works also on our build platform (Linux) it works. Maybe Mac is again a bit different here. I’ll test it in the coming days on Mac
Actually throwing OperatorException is not correct in the MeanOpImage. Because it is not a GPF operator. It would be better to throw UnsupportedOperationException similar. I’ll check if I can change this easily.
I just tried out your new code which is throwing UnsupportedOperationException. The exception is indeed thrown as can be seen in the surefire-report:
INFO: org.geotools.util.logging.LoggingImagingListener: Problem occurs when computing a tile by the owner.
java.lang.UnsupportedOperationException: Unable to compute raster for non floating number data type
at org.esa.snap.statistics.percentile.interpolated.MeanOpImage.computeRect(MeanOpImage.java:35)
at javax.media.jai.PointOpImage.computeTile(PointOpImage.java:914)
at com.sun.media.jai.util.SunTileScheduler.scheduleTile(SunTileScheduler.java:904)
at javax.media.jai.OpImage.getTile(OpImage.java:1129)
at javax.media.jai.PlanarImage.copyData(PlanarImage.java:2343)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2525)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2546)
at org.esa.snap.statistics.percentile.interpolated.MeanOpImageTest.testThatOperatorExceptionOccursWhenNoFloatingPointImagesAreProvided(MeanOpImageTest.java:131)
...
However, what is caught in the test case is still NullPointerException as seen here:
Expected: an instance of java.lang.UnsupportedOperationException
but: <java.lang.NullPointerException> is a java.lang.NullPointerException
Stacktrace was: java.lang.NullPointerException
at javax.media.jai.PlanarImage.copyData(PlanarImage.java:2344)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2525)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2546)
at org.esa.snap.statistics.percentile.interpolated.MeanOpImageTest.testThatOperatorExceptionOccursWhenNoFloatingPointImagesAreProvided(MeanOpImageTest.java:131)
...
INFO: org.geotools.util.logging.LoggingImagingListener: Problem occurs when computing a tile by the owner.
java.lang.UnsupportedOperationException: Unable to compute raster for non floating number data type
at org.esa.snap.statistics.percentile.interpolated.MeanOpImage.computeRect(MeanOpImage.java:35)
at javax.media.jai.PointOpImage.computeTile(PointOpImage.java:914)
at com.sun.media.jai.util.SunTileScheduler.scheduleTile(SunTileScheduler.java:904)
at javax.media.jai.OpImage.getTile(OpImage.java:1129) at javax.media.jai.PlanarImage.copyData(PlanarImage.java:2343)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2525)
Expected: an instance of java.lang.UnsupportedOperationException
but: <java.lang.NullPointerException> is a java.lang.NullPointerException
Stacktrace was: java.lang.NullPointerException at javax.media.jai.PlanarImage.copyData(PlanarImage.java:2344)
at javax.media.jai.PlanarImage.getAsBufferedImage(PlanarImage.java:2525)
From the above 2 stack traces, it appears that UnsupportedOperationException was indeed thrown within getTile(tx, ty) method.
But for some reason, the code still continued with tile still null.
Just found out that the above behaviour is due to the different ImagingListener used when in eclipse and maven.
When running the test case in eclipse, the ImagingListener class is
com.sun.media.jai.util.ImagingListenerImpl
but in maven command line, the ImagingListener class is
org.geotools.util.logging.LoggingImagingListener
I managed to trace the test case code flow as below:
Raster tile = getTile(tx, ty) at line 2343 above will call tile = scheduler.scheduleTile(this, tileX, tileY) at line 1129 below:
… which will reach line 904 below…
… which will reach line 914 below …
… then reaching line 35 of MeanOpImage which throws UnsupportedOperationException.
The UnsupportedOperationException thrown is handled between 916 and 931 below:
Since UnsupportedOperationException is an instance of RuntimeException, line 921 above handles it through the method sendExceptionToListener below:
As mentioned earlier, the ImagingListener gotten from ImageUtil in line 1644 is different when I ran the test from eclipse and maven.
Tracing the code further to org.geotools.util.logging.Logging, I can see that geotools will replace ImagingListener with LoggingImagingListener in line 119 if the class name contains ImagingListenerImpl. I think this happened when I ran the test case in maven command line which made the test case logged UnsupportedOperationException instead of throwing the exception for the test case to catch.
Any way to set the ImageListener to com.sun.media.jai.util.ImagingListenerImpl when running the case from maven command line so that the test case can pass?
Based on my above finding, I modified testThatOperatorExceptionOccursWhenNoFloatingPointImagesAreProvided method as below in order to pass the test from maven command line:
@Test
public void testThatOperatorExceptionOccursWhenNoFloatingPointImagesAreProvided() {
// get the ImagingListener currently in use
ImagingListener originalImagingListener = JAI.getDefaultInstance().getImagingListener();
// set the ImagingListener to com.sun.media.jai.util.ImagingListenerImpl
JAI.getDefaultInstance().setImagingListener(ImagingListenerImpl.getInstance());
final Vector<RenderedImage> sources = new Vector<>();
sources.add(ConstantDescriptor.create(2f, 2f, new Integer[]{3}, null));
sources.add(ConstantDescriptor.create(2f, 2f, new Integer[]{2}, null));
//execution
final MeanOpImage meanOpImage = new MeanOpImage(sources);
exception.expect(UnsupportedOperationException.class);
meanOpImage.getAsBufferedImage();
// revert the ImagingListener to the one in use
JAI.getDefaultInstance().setImagingListener(originalImagingListener);
fail("Should not reach this line");
}
Also found out that org.geotools.util.logging.LoggingImagingListener logger is set only when org.esa.snap.statistics.percentile.interpolated.UtilsTest_GroupProductsDaily test is run.
This could be the reason why the test passed in eclipse because I only ran the MeanOpImageTest whereas from maven command line I ran all tests.
The problem is that GeoTools changes the behavior. As soon as it is used or at least its logging the ImagingListener is changed, as you already noticed.